如何获取AS3 TextField中文本的实际高度? TextField.textHeight似乎报告了一些不依赖于TextField内容的固定值。
以下示例代码产生以下内容:
text=o p g y d j
textWidth=120.8
textHeight=**96**
text=o
textWidth=15
textHeight=**96**
text=oW
textWidth=43.3
textHeight=**96**
显然,“o”和“p”等的高度应该不同
AS3代码:
import flash.text.TextField;
var format : TextFormat = new TextFormat();
format.font = "Times New Roman";
format.size = 30;
format.align = TextFormatAlign.CENTER;
var textField1 : TextField = new TextField();
textField1.defaultTextFormat = format;
textField1.selectable = false;
textField1.sharpness = 0;
textField1.embedFonts = true;
textField1.multiline = false;
textField1.height = 50;
textField1.width = 200;
textField1.x = 10;
textField1.y = 10;
addChild(textField1);
textField1.text = "o p g y d j";
trace("text=" + textField1.text);
trace("textWidth=" + textField1.textWidth);
trace("textHeight=" + textField1.textHeight);
textField1.text = "o";
trace("\ntext=" + textField1.text);
trace("textWidth=" + textField1.textWidth);
trace("textHeight=" + textField1.textHeight);
textField1.text = "oW";
trace("\ntext=" + textField1.text);
trace("textWidth=" + textField1.textWidth);
trace("textHeight=" + textField1.textHeight);
stop();
我猜TextField.textHeight不是正确的变量,但我应该使用什么呢?
答案 0 :(得分:13)
Mark Fox是正确的,textHeight
并不代表文本的实际高度 - 而且Flash中的经典TextField
对获取渲染文本的实际像素高度没有任何支持。 textHeight
代表的是行高 - 即上升( font 的高度超过基线),下降( font 高度低于基线)和领先(线之间的空间)相结合。如上所述,高度是恒定的,基于字体的上升和下降,而不是实际的文本的。 (请注意这一点,请参阅Adobe's overview of the terms here - 并注意TextLineMetrics
对您无济于事。)
“新”Flash文本引擎(flash.text.engine)确实包含用于获取使用该技术呈现的文本的实际高度的属性(例如TextLine.totalHeight
) - 但随后我们将进入低级文本渲染。如果你需要使用“经典”TextField
,这无论如何都无法帮助你测量文本,因为Flash文本引擎有自己的渲染器,它不一定渲染与高度和宽度相同的文本。 “经典”文字。
您可以做的是将TextField
渲染为BitmapData
然后测量文本的边界:
// Create a completely transparent BitmapData:
var bmd:BitmapData = new BitmapData(
textfield.width,
textfield.height,
true,
0x00ffffff);
// Note that some cases may require you to render a Sprite/MovieClip
// CONTAINING the TextField for anything to get drawn.
// For example, AntiAliasType.ADVANCED (antialias for readability) is known to
// not be renderable in some cases - other settings may cause nothing to be
// rendered too. In that case, simply wrap add the TextField as a child of an
// otherwise empty Sprite/MovieClip, and pass that to draw() instead:
bmd.draw(textfield);
// This gets the bounds of pixels that are not completely transparent.
// Param 1: mask = specifies which color components to check (0xAARRGGBB)
// Param 2: color = is the color to check for.
// Param 3: findColor = whether to bound pixels OF the specified color (true),
// or NOT OF the specified color (false)
//
// In this case, we're interested in:
// 1: the alpha channel (0xff000000)
// 2: being 00 (0x00......)
// 3: and want the bounding box of pixels that DON'T meet that criterium (false)
var rect:Rectangle = bmd.getColorBoundsRect(0xff000000, 0x00000000, false);
// Do remember to dispose BitmapData when done with it:
bmd.dispose();
trace("text height = " + rect.height);
trace("text width = " + rect.width);
关于准确性的说明
这可能完全不相关,取决于您将要使用的内容,但值得记住:
此方法显然总是以整个像素返回结果 - 然而,字形的实际渲染使用子像素。
换句话说,如果添加测量“V”和“o”宽度的结果,然后将其与“Vo”的结果进行比较,它们可能不相同。你可能得到“40 + 35 = 74”。忽略那些字距调整等可能会将字母拉得更近,每个字母的渲染(放置,消除锯齿等)也可能会有所不同,具体取决于其背景。
答案 1 :(得分:3)
您的问题突出了Flash排版API中弱语义的遗留问题。
textHeight
属性表示字体的相对大小(以像素为单位),它不考虑TextField
中特定字形(单个字母形状)的像素表示。
据我所知,没有直接的程序方法来测量Flash的字形。但是,您可以对文本字段进行位图处理并使用getPixel进行猜测:
var tf:TextField = …your textfield…
var wide:int = tf.width;
var tall:int = tf.height;
var bmpd:BitmapData = new BitmapData(wide, tall, true,0xFFFFFFFF);
bmpd.draw( tf );
var totalPixels:int = wide * tall;
var index:int = totalPixels + 1;
var useIndex:int;
var xPixel:int;
var yPixel:int;
while (--index > 0) {
useIndex = index - 1;
xPixel = useIndex % wide;
yPixel = int(useIndex / wide);
var pixelColor:uint = bmpd.getPixel(xPixel, yPixel);
// write some logic to find the y extremes where the pixelColor values are not white (or whatever background color specified when you created the BitmapData)
}
答案 2 :(得分:0)
你可以通过" textHeight";
来做到这一点// Create TextField
var tf:TextField = new TextField();
tf.wordWrap = true;
tf.multiline = true;
tf.selectable = false;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.autoSize = TextFieldAutoSize.LEFT; // It's should not be "=TextFieldAutoSize.NONE;"
tf.embedFonts = true;
tf.text = "Your text here";
this.addChild(tf);
trace(tf.textHeight);
希望它会有所帮助