Actionscript 3 有没有办法在ActionScript中获得字形的实际边界框?

Actionscript 3 有没有办法在ActionScript中获得字形的实际边界框?,actionscript-3,Actionscript 3,我正在学习ActionScript/Flash。我喜欢玩文本,并且已经用优秀的Java2D API做了很多类似的事情 我想知道的一件事是“你到底在哪里画那个字形?”TextField类提供了方法getBounds和getCharBounders,但这些方法返回的矩形分别远远超出了整个文本对象或单个字符的实际边界 var b:Sprite = new Sprite(); b.graphics.lineStyle(1,0xFF0000); var r:Rectangle = text.getChar

我正在学习ActionScript/Flash。我喜欢玩文本,并且已经用优秀的Java2D API做了很多类似的事情

我想知道的一件事是“你到底在哪里画那个字形?”TextField类提供了方法
getBounds
getCharBounders
,但这些方法返回的矩形分别远远超出了整个文本对象或单个字符的实际边界

var b:Sprite = new Sprite();
b.graphics.lineStyle(1,0xFF0000);
var r:Rectangle = text.getCharBoundaries(4);
r.offset(text.x, text.y);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);

b = new Sprite();
b.graphics.lineStyle(1,0x00FF00);
r = text.getBounds(this);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);


是否有任何方法可以获得有关ActionScript中文本图示符的实际视觉边界的更精确信息?

恐怕TextField上可用的所有方法都应该执行您已经发现的操作。除非性能是应用程序中的关键(即,除非您打算经常这样做),否则一个选项可能是将文本字段绘制到位图数据,并在GetCharBounders()检索的边界框中查找最顶部、最左侧的et c彩色像素

vari:int;
var-rect:矩形;
左上角变量:点;
var btm_右:点;
var bmp:BitmapData=新的BitmapData(tf.width,tf.height,false,0xffffff);
bmp.draw(tf);
rect=tf.getCharBounders(4);
左上=新点(无穷大,无穷大);
btm_right=新点(-无穷大,-无穷大);

对于(i=rect.x;i在Flash 9中不太可能——Richard的答案是一个巧妙的解决方案,尽管可能完全不适合生产代码(如他所提到的):)


如果您可以访问Flash 10,请查看新的文本行。

Richard的做法是正确的,但是BitmapData.getColorBounds()更快、更准确。。。我已经使用过好几次了,并且针对您的特定需求进行了优化—它并不像人们想象的那么慢


科里建议使用flash.text.engine可能是“正确”的方法,但我警告你,与TextField相比,flash.text.engine非常(非常!)难以使用。

请为你务实而详细的答案投票,并对陷阱进行讨论。我很感激。如果有人复制了上面的代码,请注意第二个for循环,应该是增量j而不是I。相反,这正是我想要的+谢谢你的宝贵意见。这就是问题所在。现在的问题是“为什么FlexBuilder只为Flash9提供调试播放器,而不是Flash10?”我在做生意。非常感谢。遗憾的是,文本引擎提供的内省并不比Flash 9更好。最好是文本行的宽矩形边界框,可以使用atom边界进行水平分区。但是没有办法获得单个标志符号的实际边界。太糟糕了!在Flash9之前,文本度量非常不准确,因此我决定生成Adobe字体度量(AFM)文件——基本上是字体中所有字符数据的纯文本描述——并且我能够将这些文件加载到Flash中并解析数据(包括字距对)。我编写了一个文本换行算法,并且实际上能够编写一个函数,该函数接受一个文本字段,并生成单个单词的完美叠加,每个单词都有可点击的区域,具有非常精确的字符边界。因此,它不仅在Flash9中是可行的,而且在Flash8(AS2)中也是可行且快速的。这可能会有所帮助
var i : int;
var rect : Rectangle;
var top_left : Point;
var btm_right : Point;

var bmp : BitmapData = new BitmapData(tf.width, tf.height, false, 0xffffff);
bmp.draw(tf);

rect = tf.getCharBoundaries(4);
top_left = new Point(Infinity, Infinity);
btm_right = new Point(-Infinity, -Infinity);

for (i=rect.x; i<rect.right; i++) {
  var j : int;

  for (j=rect.y; j<rect.bottom; j++) {
    var px : uint = bmp.getPixel(i, j);

    // Check if pixel is black, i.e. belongs to glyph, and if so, whether it
    // extends the previous bounds
    if (px == 0) {
      top_left.x = Math.min(top_left.x, i);
      top_left.y = Math.min(top_left.y, j);
      btm_right.x = Math.max(btm_right.x, i);
      btm_right.y = Math.max(btm_right.y, j);
    }
  }
}

var actualRect : Rectangle = new Rectangle(top_left.x, top_left.y);
actualRect.width = btm_right.x - top_left.x;
actualRect.height = btm_right.y - top_left.y;