Is there a way to get the actual bounding box of a glyph in ActionScript?

戏子无情 提交于 2019-12-19 10:21:59

问题


I'm learning ActionScript/Flash. I love to play with text, and have done a lot of that kind of thing with the superb Java2D API.

One of the things I like to know is "where, exactly, are you drawing that glyph?" The TextField class provides the methods getBounds and getCharBoundaries, but these methods return rectangles that extend far beyond the actual bounds of the whole text object or the individual character, respectively.

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

Is there any way to get more precise information about the actual visual bounds of text glyphs in ActionScript?


回答1:


Not reasonably possible in Flash 9 -- Richard's answer is a clever work-around, though probably completely unsuitable for production code (as he mentions) :)

If you have access to Flash 10, check out the new text engine classes, particularly TextLine.




回答2:


Richard is on the right track, but BitmapData.getColorBounds() is much faster and accurate... I've used it a couple of times, and optimized for your specific needs its not as slow as one might think.

Cory's suggestion of using flash.text.engine is probably the "correct" way to go, but I warn you that flash.text.engine is VERY (very!) hard to use compared to TextField.




回答3:


I'm afraid all the methods that are available on TextField are supposed to do what you have already found them to do. Unless performance is key in your application (i.e. unless you intend to do this very often) maybe one option would be to draw the text field to a BitmapData, and find the topmost, leftmost, et c colored pixels within the bounding box retrieved by 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;

This code should loop through all the pixels that were deemed part of the glyph rectangle by getCharBoundaries(). If a pixel is not black, it gets discarded. If black, the code checks whether the pixels extends further up, down, right or left than any pixel that has previuosly been checked in the loop.

Obviously, this is not optimal code, with nested loops and unnecessary point objects. Hopefully though, the code is readable enough, and you are able to make out the parts that can most easily be optimized.

You might also want to introduce some threshold value instead of ignoring any pixel that is not pitch black.



来源:https://stackoverflow.com/questions/1942911/is-there-a-way-to-get-the-actual-bounding-box-of-a-glyph-in-actionscript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!