TrueType 的 ‘glyf’ 表中,每个字型都有一个 “指令列表”,其中放置与该字体相关的 渲染指令 (instructions)。“指令列表” 是一个字节序列,其中每个字节存放的是指令的字节码。

每个 TrueType 的渲染器中都有 指令译码器 (interpreter)。译码器会根据字节码翻译并执行指令,执行诸如沿着某方向移动曲线上的点、对齐点、对点进行插值等操作,以此达到字形微调的目的。

指令译码器 还包括一个数据栈 (Stack)、一个寄存器 (Storage)、一个控制值表 (Control Value Table)。

  • 数据栈用来存储操作数和返回值。
  • 寄存器用来存储希望整个指令执行过程一直都能用的数据。整个指令列表执行结束后,寄存器中的值就无效了。
  • 控制值表用来存储一些指令约定可能会读取的内容。

以下是拉丁字母 ‘i’ 在 Helvetica.ttc (version = 17.0d1e1, 随 macOS 12.5 分发的字体) 中的字型(Glyph Index = 105)的渲染指令及其反汇编内容,以及该指令的解释。

字节码 字节码反汇编的指令或内容 执行到这句话时将发生的操作
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。