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

时间:2009-12-21 21:59:23

标签: actionscript-3

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

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

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);

some bounds

有没有办法在ActionScript中获取有关文本字形的实际视觉边界的更精确信息?

3 个答案:

答案 0 :(得分:3)

理查德走在正确的轨道上,但BitmapData.getColorBounds()更快更准确......我已经使用了几次,并针对您的特定需求进行了优化,并不像人们想象的那么慢。 / p>

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

答案 1 :(得分:2)

我担心TextField上可用的所有方法都应该按照您已经发现的方式执行。除非性能在您的应用程序中起关键作用(即除非您打算经常这样做),否则可能有一个选项是将文本字段绘制到BitmapData,并找到getCharBoundaries检索到的边界框内最顶部,最左边的等颜色像素()?

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;

此代码应遍历所有被getCharBoundaries()视为字形矩形一部分的像素。如果像素不是黑色,则会被丢弃。如果是黑色,则代码检查像素是否比在循环中预先检查过的任何像素进一步向上,向下,向右或向左延伸。

显然,这不是最佳代码,具有嵌套循环和不必要的点对象。但是,希望代码足够可读,并且您能够找出最容易优化的部分。

您可能还想引入一些阈值而不是忽略任何非投球黑色的像素。

答案 2 :(得分:2)

在Flash 9中没有合理的可能 - 理查德的答案是一个聪明的解决方案,虽然可能完全不适合生产代码(正如他所提到的):)

如果您有权访问Flash 10,请查看新的text engine classes,特别是TextLine。