Actionscript 3 查找实际文本高度为3

Actionscript 3 查找实际文本高度为3,actionscript-3,Actionscript 3,如何获取AS3文本字段中文本的实际高度?似乎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 fl

如何获取AS3文本字段中文本的实际高度?似乎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不是正确的变量,但我应该使用什么来替代呢?

您的问题突出了Flash排版API中存在的一个弱语义遗留问题

textHeight
属性表示字体的相对大小(以像素为单位),它不考虑
TextField
中特定字形(单个字母形状)的像素表示

据我所知,没有直接的编程方法来测量一个符号与闪存。但是,您可以对文本字段进行位图,并使用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)
}

Mark Fox说得对,
textHeight
不代表文本的实际高度,Flash中的经典
TextField
不支持获取渲染文本的实际像素高度。
textHeight
所代表的是线条高度,即其上升(字体高于基线的高度)、下降(字体低于基线的高度)和领先(线条之间的间距)的组合。正如所暗示的,高度是恒定的,基于字体的上升和下降,而不是实际文本的上升和下降。(记住这一点,请参阅-并注意
TextLineMetrics
对您也没有帮助)

“新”的Flash文本引擎(Flash.Text.Engine)确实包含了一些属性,用于获取使用该技术渲染的文本的实际高度(例如,
TextLine.totalHeight
)——但接下来我们将进入低级文本渲染。如果您需要使用“classic”
TextField
s,这无论如何都不会帮助您测量文本,因为Flash文本引擎有自己的渲染器,它不一定以与“classic”文本相同的高度和宽度渲染文本

您可以改为将
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);
关于准确性的注意事项

这可能是完全不相关的,这取决于您将使用它做什么,但值得记住:

显然,这种方法总是以整像素为单位返回结果——但是,glyph的实际渲染使用子像素

换句话说,如果将测量“V”和“o”宽度的结果相加,然后将其与“Vo”的结果进行比较,则它们可能不相同。你可能会得到“40+35=74”。忽略字距调整等可能会使字母靠得更近,每个字母的呈现方式(位置、抗锯齿等)也可能不同,具体取决于其上下文。

您可以通过“textHeight”来实现这一点


希望它能在创建
bmd
时有所帮助,您可以将
fillColor
设置为
0xffffffff
,使其充满纯白。既然您希望它完全透明,那么您的意思可能是
0x00ffffff
(尽管只
0
就可以了)。是的,0x00ffffff就是我们需要的。谢谢Jimmi,我检查了你的解决方案,它给出了正确的尺寸。(注意:bmd fillColor应设置为0x00ffffff)。非常感谢你!你知道Adobe在新的Flash CC版本中不推荐TLF,对吗@帕格索伊:感谢您的更正-我已经更正了代码,并且使
getColorBoundsRect()
调用更为通用+添加了参数解释。顺便说一句,目前Flash Pro CC有一个与文本相关的主要错误,其中包括返回完全错误的TextField.textHeight。字体大小和呈现文本大小之间的不一致是每个API的弱点。Flash依赖于Java,Java依赖于OS API。正如其他答案所示,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);