AS3 自定义 TextField 文本正在其 textWidth 之外绘制

Posted

技术标签:

【中文标题】AS3 自定义 TextField 文本正在其 textWidth 之外绘制【英文标题】:AS3 custom TextField text is being drawn outside its textWidth 【发布时间】:2018-10-13 10:13:44 【问题描述】:

所以这个有点难以解释。我有一个自定义 Text 类,当您更改它的值时,它会自动调整大小并设置文本的宽度。然后,我将该文本绘制在位图上以放大它以使文本看起来像素化。

我有一个名为maxWidth 的属性,如果你想让它保持一定的宽度,它允许你限制文本的宽度。默认情况下,maxWidth 是文本父级的宽度,因此它不会被切断或意外扩展父级的边界。

不幸的是,当我绘制文本时,它有时会在右侧被截断。现在我检查了所有的值,widthtextWidth 显示在它们的 maxWidth 值中,但是当我通过屏幕截图查看自己时,我发现文本实际上比它应该宽了大约 3 个像素是。

这里有一张图片可以更好地解释我的意思:

我打开了边框,这样你就可以很容易地明白我的意思。第一行上的单词“and”被画在它的边界之外。这是在您更改其边界时处理调整文本大小的代码行。

override protected function checkResize(value:String):void 
    var bufferWidth:uint = Math.floor(Number(defaultTextFormat.size) / bufferDivisor) + bufferMin;
    var maxWidth:Number = this.maxWidth;
    x = y = 0;

    if (parent is Stage) 
        var stageParent:Stage = Stage(parent);
        super.width = stageParent.stageWidth;
        super.height = stageParent.stageHeight;

        if (maxWidth == 0) maxWidth = stageParent.stageWidth;
    
    else 
        super.width = parent.width;
        super.height = parent.height;

        if (maxWidth == 0) maxWidth = parent.width;
    

    maxWidth = maxWidth / scale;
    text = value;

    if (textWidth + bufferWidth <= maxWidth) super.width = textWidth + bufferWidth;
    else super.width = maxWidth;

    super.height = textHeight + 4;

    if (textSnapshot) updateSnapshot();
    if (alignRelation) Align.alignTo(textSprite, alignRelation, alignDirection, alignXOffset, alignYOffest);

对于此文本,特别是 width 值指出它是 512,这是正确的,因为那是 maxWidth。但是,如果您注意到文本中的第一行,它超出了 512 宽度边框,它实际上一直到 515,即使它说它的 width 是 512。更奇怪的是 textWidth 甚至声明它是 510.4尽管第一行远远超出了这个数量。我只是想知道我是否做错了什么,或者是否有办法获得真正的textWidth 值。

【问题讨论】:

过去我们遇到过一个非常相似的问题,它可能与 Flash Player 重新计算文本边界的方式有关。您可以尝试在两个不同的帧中调用 checkResize 函数两次,在第二次调用之后应该正确计算边界。不过,不确定是否是同一种情况。关键点 - 两个不同的帧,正确的边界将在宽度分配给文本字段后的下一帧中计算。 "在 width 被分配给文本字段之后的下一帧中" - 对不起,在 value 被分配之后,而不是宽度。 我想这与亚像素表现得古怪有关。从技术上讲,宽度是正确的,因为它保持在其父级的范围内。不知何故,字符串被绘制在宽度边界之外而没有实际更新宽度。不幸的是,多次调用 checkResize 似乎没有任何作用。现在解决这个问题的唯一方法是弄乱缓冲区,但即便如此,它仍然设法切断另一个文本。 我也遇到过同样的问题,一直没找到原因。我的 hack-ey 解决方案是将宽度填充为整体的百分比。我也认为宽度与每个字体字符的宽度如何被错误地测量有关。 我找到了自己的 hack-ey 解决方案,每当我更改文本时,它会逐渐减小宽度,直到 textwidth 也减小(因为 textwidth 会根据宽度自动调整),通常这意味着最长的行环绕到下一行并正确绘制所有内容。这不是一个完美的解决方案,但它现在可以工作 【参考方案1】:

这似乎与嵌入字体有关,至少在我遇到同样问题的时候。一种解决方法是设置文本字段的右边距,像这样

var tf:TextFormat = new TextFormat();
tf.rightMargin = 10; // or whatever fixes your problem, e.g. relate it to font size
textField.setTextFormat(tf);

【讨论】:

我无法验证此解决方案的有效性,因此我无法确认它是答案,但听起来是正确的,因为我最初嵌入了我的字体。我最终放弃了所有内容并制作了一个自定义字符解析器,该解析器使用位图图像来形成单词,它提供了完美的像素宽度,同时还允许我将文本放大以获得像素化。这样我就可以绕过 Flash 渲染器并更好地控制代码。

以上是关于AS3 自定义 TextField 文本正在其 textWidth 之外绘制的主要内容,如果未能解决你的问题,请参考以下文章

Air As3 XML 编辑/保存

AS3里【TextField】于【TextArea】有啥区别?

ActionScript 3 AS3:使用新的Object()向TextField()添加文本样式

AS3 Textfield根据高度设置宽度

AS3/Flex 自定义 TextInput 组件填充

textfield不会清楚,as3