TrueType 的 ‘glyf’ 表中,每个字型都有一个 “指令列表”,其中放置与该字体相关的 渲染指令 (instructions)。“指令列表” 是一个字节序列,其中每个字节存放的是指令的字节码。
每个 TrueType 的渲染器中都有 指令译码器 (interpreter)。译码器会根据字节码翻译并执行指令,执行诸如沿着某方向移动曲线上的点、对齐点、对点进行插值等操作,以此达到字形微调的目的。
指令译码器 还包括一个数据栈 (Stack)、一个寄存器 (Storage)、一个控制值表 (Control Value Table)。
- 数据栈用来存储操作数和返回值。
- 寄存器用来存储希望整个指令执行过程一直都能用的数据。整个指令列表执行结束后,寄存器中的值就无效了。
- 控制值表用来存储一些指令约定可能会读取的内容。
以下是拉丁字母 ‘i’ 在 Helvetica.ttc (version = 17.0d1e1, 随 macOS 12.5 分发的字体) 中的字型(Glyph Index = 105)的渲染指令及其反汇编内容,以及该指令的解释。
- (c) 1990-2006 Apple Computer Inc. (c) 1981 Linotype AG (c) 1990-91 Type Solutions Inc.
- 本文参考了与 TrueType 指令集相关的介绍文档:TrueType Instruction Set (OpenType 1.9) - Typography
字节码 | 字节码反汇编的指令或内容 | 执行到这句话时将发生的操作 |
---|---|---|
0x40 | NPUSHB | 将 n 个字节按顺序入栈。将会读取接下来的 1 个字节作为 n。 |
0x1C | 28 | 上一个指令 (NPUSHB) 的操作数 n。将会读取接下来的 28 个字节。 |
0x07 | 7 | 十进制数字 7 |
0xE5 | 229 | 十进制数字 229 |
0x04 | 4 | 十进制数字 4 |
0x00 | 0 | 十进制数字 0 |
0x01 | 1 | 十进制数字 1 |
0x00 | 0 | 十进制数字 0 |
0x06 | 6 | 十进制数字 6 |
0x03 | 3 | 十进制数字 3 |
0x0A | 10 | 十进制数字 10 |
0x09 | 9 | 十进制数字 9 |
0x17 | 23 | 十进制数字 23 |
0x17 | 23 | 十进制数字 23 |
0x1A | 26 | 十进制数字 26 |
0x06 | 6 | 十进制数字 6 |
0x01 | 1 | 十进制数字 1 |
0x02 | 2 | 十进制数字 2 |
0x29 | 41 | 十进制数字 41 |
0x07 | 7 | 十进制数字 7 |
0x03 | 3 | 十进制数字 3 |
0x00 | 0 | 十进制数字 0 |
0x19 | 25 | 十进制数字 25 |
0x08 | 8 | 十进制数字 8 |
0x09 | 9 | 十进制数字 9 |
0xAA | 170 | 十进制数字 170 |
0x21 | 33 | 十进制数字 33 |
0x62 | 98 | 十进制数字 98 |
0x42 | 66 | 十进制数字 66 |
0x18 | 24 | 十进制数字 24 |
0x2B | CALL | 弹出当前栈顶数字,执行已定义的 ID 为该栈顶数字函数。 - 注:函数需使用 FDEF[] 指令来定义。 |
0x2B | CALL | 弹出当前栈顶数字,执行已定义的 ID 为该栈顶数字函数。 - 注:函数需使用 FDEF[] 指令来定义。 |
0x4E | FLIPOFF | 设置 Graphics State 中的 auto_flip 属性为 FALSE。 |
0xF4 | MIRP[rp0,rnd,grey] | Move Indirect Relative Point:MIRP 指令可以根据多种条件保留两点之间的距离。 |
0x3C | ALIGNRP | Align Relative Point:将 rp0 和点 p 之间的距离减小为零,以对齐两点。 |
0x4D | FLIPON | 设置 Graphics State 中的 auto_flip 属性为 TRUE。 |
0xC4 | MDRP[rnd,grey] | Move Direct Relative Point:MDRP 通常用于使用来自原始轮廓的值来控制字形特征的宽度或高度。 |
0xFD | MIRP[rp0,min,rnd,black] | Move Indirect Relative Point:MIRP 指令可以根据多种条件保留两点之间的距离 |
0x3C | ALIGNRP | Align Relative Point:将 rp0 和点 p 之间的距离减小为零,以对齐两点。 |
0xC4 | MDRP[rnd,grey] | Move Direct Relative Point:MDRP 通常用于使用来自原始轮廓的值来控制字形特征的宽度或高度。 |
0x4E | FLIPOFF | 设置 Graphics State 中的 auto_flip 属性为 FALSE。 |
0x45 | RCVT | Read Control Value Table - 从栈中弹出 1 个值 location,然后读取 CVT[location] 的值放入栈。 - CVT = Control Value Table |
0x65 | NEG | 从栈中弹出 1 个值 n,然后将 -n 放入栈。 |
0x44 | WCVTP | Write Control Value Table in Pixel units - 从栈中弹出 1 个值 value - 从栈中弹出 1 个值 location - 然后将 CVT[location] 的值设为 value 的 26.6 定点数格式。 |
0xE6 | MIRP[rnd,white] | |
0x00 | SVTCA[y-axis] | Set freedom and projection Vectors To Coordinate Axis |
0x3F | MIAP[rnd] | Move Indirect Absolute Point: - 从栈中弹出 1 个值 location - 从栈中弹出 1 个值 p - 将点 p 沿着 projection_vector 移动到 CVT[location] 定义的位置上。 |
0x3F | MIAP[rnd] | Move Indirect Absolute Point: - 从栈中弹出 1 个值 location - 从栈中弹出 1 个值 p - 将点 p 沿着 projection_vector 移动到 CVT[location] 定义的位置上。 |
0x3C | ALIGNRP | Align Relative Point:将 rp0 和点 p 之间的距离减小为零,以对齐两点。 |
0x3F | MIAP[rnd] | Move Indirect Absolute Point: - 从栈中弹出 1 个值 location - 从栈中弹出 1 个值 p - 将点 p 沿着 projection_vector 移动到 CVT[location] 定义的位置上。 |
0x4D | FLIPON | 设置 Graphics State 中的 auto_flip 属性为 TRUE。 |
0xED | MIRP[min,rnd,black] | Move Indirect Relative Point:MIRP 指令可以根据多种条件保留两点之间的距离 |
0x31 | IUP[x] | Interpolate Untouched Points through the outline - 在每个轮廓上,对任何两个已被移动过的点 (a, b) 之间的每个未移动的点 n,按照以下规则进行移动。 - 如果点 n 的 x 坐标位于 (a, b) 移动之前的 x 坐标之间,则把 n 放在 (a, b) 的新 x 坐标之间线性插值的地方。 - 否则按照与 n 最近的那个已被移动的点在 x 上已移动的距离,在 x 方向移动点 n。 |
0x30 | IUP[y] | Interpolate Untouched Points through the outline - 在每个轮廓上,对任何两个已被移动过的点 (a, b) 之间的每个未移动的点 n,按照以下规则进行移动。 - 如果点 n 的 y 坐标位于 (a, b) 移动之前的 y 坐标之间,则把 n 放在 (a, b) 的新 y 坐标之间线性插值的地方。 - 否则按照与 n 最近的那个已被移动的点在 y 上已移动的距离,在 y 方向移动点 n。 |