将文本字段对齐在一起会产生不准确的间距外观

时间:2012-05-27 20:12:04

标签: actionscript-3

我已将Arial作为嵌入字体添加到我的字体格式中,我已添加到许多文本字段中,这些字段必须彼此精确对齐以创建空格的外观。它们彼此相邻排列约1-2个像素。问题是,当在正常舞台大小下观看时,它们看起来间隔不准确,但是当我放大文本时看起来很好。

我已经尝试过乱搞并添加高级抗锯齿,但没有任何效果。也许Arial不适合小尺寸?我知道没有设置它产生我想要的结果的字体,但它不是我想要使用的字体;它必须使用Times?

有什么想法吗?

var myFont = new Font1();

            format1 = new TextFormat(); 
            format1.color = 0x000000; 
            format1.size = 16;
        format1.font = myFont.fontName;

编辑: 基本上我将每个角色分成它自己的文本字段,所以我可以操纵每个角色并为其制作动画。但要做到这一点,我需要将字符空间分开,就像它是一个文本字段一样。

private var bmd:BitmapData; // bitmapdata to draw textField in;
        private function getExactMetrics(textField:TextField):Object
        {
            // copy textField to bitmap
            bmd = new BitmapData(textField.width,textField.height,true,0x000000);
            bmd.draw(textField);

            // loop through pixels of bitmap data and store the x location of pixels found.
            var foundx:Array = [];

             for (var nx:int = 0; nx < bmd.width;nx++)
               {
                for (var ny:int = 0; ny < bmd.height; ny++)
                {

                    var px:uint = bmd.getPixel32(nx, ny);
                    if (px != 0)
                    {
                        foundx.push(nx);
                        break;
                    }

                }
            }

            // get the values for the metrics
            var startX:int = foundx[0]; // first pixel found representing the x start of the text in pixels
            var endX:int = foundx[foundx.length-1]; t
            var realWidth:Number = endX - startX; 

            // clear the array with found x positions
            foundx = [];

            // wrap values in object
            var metrics:Object = { };
            metrics.width = realWidth;
            metrics.x = startX;

            // clear bitmapdata
            bmd = null;

            return metrics; // retrurn metric object;
        }

    }

2 个答案:

答案 0 :(得分:1)

请记住,字体有kerning,这意味着字母不只是彼此相邻,而是间距取决于字体的设置。例如,单词'To''o'略低于字母'T'的'顶部梁'。

如果你只是把信放在一边,那看起来很糟糕,你必须考虑字距。

TextField类有一个getCharBoundaries方法,可用于获取准确的字符位置。但不确定它是否适用于htmlText。

为了简化您可以使用第三方库。 Greensock有一个很棒的SplitTextField(但它不是免费的)或Textanim(开源)。

答案 1 :(得分:0)

Verdana等字体在较小尺寸下可能具有更高的可读性;但是,听起来您遇到了文本指标问题。

在此示例中,TextLineMetrics用于准确测量每个文本字段。

结果:

text line metrics

代码:

package
{
    import flash.display.Sprite;
    import flash.text.AntiAliasType;
    import flash.text.Font;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.text.TextLineMetrics;

    [SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0xefefef, frameRate = 30)]
    public class X extends Sprite
    {

        public function X()
        {
            super();

            // collection of words
            var words:Array = [ "These", "are", "the", "words", "to", "be", "placed" ];

            // define a text format
            var textFormat:TextFormat = new TextFormat();
            textFormat.font = "Arial";
            textFormat.bold = false;
            textFormat.size = 8;
            textFormat.color = 0x0;
            textFormat.align = TextFormatAlign.LEFT;

            // destination x coordinate for next word text field
            var dx:Number = 0;

            // for every word
            for each (var word:String in words)
            {
                // create a text field
                var textField:TextField = new TextField();
                textField.setTextFormat(textFormat);
                textField.defaultTextFormat = textFormat;
                textField.autoSize = TextFieldAutoSize.LEFT;
                textField.antiAliasType = AntiAliasType.ADVANCED;

                // set text and place the text field
                textField.text = word;
                textField.x = dx;
                textField.y = 20;
                addChild(textField);

                // measure the text field for accurate width
                var textLineMetrics:TextLineMetrics = textField.getLineMetrics(0);
                dx += textLineMetrics.width + 2;
            }
        }

    }
}