坐标、字体度量与范围
字体单位与排版缩放
字体以字体单位保存轮廓。若每 em 有 \(U\) 单位、指定字级为 \(s\),缩放率就是 \(\lambda = s / U\)。字体坐标 \(p = (x, y)\) 加上字形处理器给的原点与偏移后,会成为
字体的基准线、宽度与高度度量 所标示的上伸线、基线、下伸线与字幅,皆先以字体单位读取,再依 \(\lambda\) 映射到排版空间;字形的宽度与深度也在同一坐标系统中量测。排版结果的 y 轴向上,第一条基线在 \(y = 0\)。
字幅不等于实际墨迹宽度
排字光标在第 \(i\) 个字形之后的位置为 \(x_{i+1} = x_i + a_i\),其中 \(a_i\) 是该字形的字幅(advance)。轮廓可能伸到原点左侧,也可能超过字幅,因此 GlyphKit 同时返回逻辑范围 \(L\) 与墨迹范围 \(I\)。
定义 · 边界联集
对非空轴对齐矩形 \(B_j\),联集的四条边分别取所有 \(x_{\min},y_{\min}\) 的最小值与 \(x_{\max},y_{\max}\) 的最大值。
如何选择范围
对齐、换行与预留空间应使用逻辑范围;裁切、碰撞与紧密输出使用墨迹范围。基线是独立数据,不该由任一矩形反推。
输出时才需要换算 DPI
GlyphKit 不决定像素。输出端以 \(d\) DPI 导出时,会把 \(q\) 排版点换算成 \(q d / 72\) 像素。这个换算放在排版引擎之外,因此同一份 TextLayout 可供 SVG、PDF、位图与动画共用。
1.0.0b4 的已知问题
LineLayout 与 TextLayout 的 ink_bounds,是用相对于各字形原点的字形范围组出来的,所以涵盖不到由多个字形组成的一行,换行后的行也是错的。修正之前,请使用逻辑范围;没有换行的文本,则自己对 glyph.x + glyph.ink_bounds.x_max 等值取联集。