Flash Player的TextField自动缩放机制

Flash Player在处理文本时,出于效率考虑,不会随时根据代码来调整文字排版——据我所知文字排版消耗非常大——而是在添加到显示列表或每一帧结束时再做处理。

ActionScript 3

今天发现一个问题,先详细描述一下我的需求:

  1. 显示一段文字,文字字数不定,但文本框长度有限,短于限制则完全显示,超过限制则截断只剩一行,并续以“…”
  2. 必须应对多语言环境,比如中文、英文、俄文等

我是这么计划的

  1. 因为多语种,每个语言的文字宽度可能都不一致,所以不太可能确定文本框的长度
  2. 于是创建一个里面有“…”的文本框缀在最后的做法可能就无效了
  3. 那么建立一个自动换行的文本框,利用Flash Player自己的渲染机制进行换行
  4. 取第一行的文字,连上”…”后再替换原来的文本
  5. 查阅手册,发现TextField有个方法叫getLineLength(index:int),取某行字数,遂决定采取此方案

写成代码后发现不行,代码大意如此(1):

var txt:TextField = new TextField();
txt.wordWrap = true;
txt.text = '一段很长的文字,大约有100字吧';
txt.width = 240; // 期望长度
var length:int = txt.getLineLength(0);
txt.text = txt.text.substr(0, length) + '...';
addChild(txt);

结果文本框比我预想的短很多,只有几个字,绝对不到240px。于是我开始各种调试,均无果,于是专门写了个这样子的测试用例(2)来测试:

var txt:TextField = new TextField();
txt.wordWrap = true;
txt.text = '还是那段文字,总之很长';
addChild(txt);
addEventListener(MouseEvent.CLICK, onClick);

function onClick(evt:MouseEvent):void {
  txt.width = 100 + Math.random() * 100;
  trace(txt.getLineLength(0));
}

我惊讶发现这样做居然没问题了,这很灵异啊~

继续仔细观察,我发现(1)里的文字长度也有规律可循,长度似乎接近TextField默认的100px(TextField被创建为实例时,宽高均为100),于是我猜想:

Flash Player在处理文本时,出于效率考虑,不会随时根据代码来调整文字排版——据我所知文字排版消耗非常大——而是在添加到显示列表每一帧结束时再做处理。

在(2)的onClick里复制一遍,就会发现,这个推论应该是真实的。