字形与 em 方框

字形与 em 方框

最后更新 2026-11-02

  • 字形
  • 轮廓
  • em 方框
  • unitsPerEm
  • 贝塞尔
  • 复合字形
  • hinting
EN中文
本页目录

字体里最实在的东西是轮廓:一段段直线与曲线围出的形状,填充后就是笔画。其余所有表(名字、度量、覆盖)都是在描述这些轮廓。

轮廓是什么

一个字形由若干闭合路径组成:

  • 直线段(L);
  • 曲线段——TrueType 用二次贝塞尔(一个控制点),CFF 用三次贝塞尔(两个控制点);
  • 每条路径有方向(顺时针或逆时针)。

方向不是装饰:它决定哪边是里面。字体基本都按非零环绕规则(nonzero winding)填充——同方向套在一起是实心,反方向套在一起就是挖空,所以 o 的内圈是反着画的。

坐标系统:em 方框

字形坐标的单位是字体单位(font unit),刻度由 head 表的 unitsPerEm 决定:

  • 常见 1000(CFF 字体)或 2048(TrueType 字体);
  • 一 em = unitsPerEm 个单位;
  • 基线是 y = 0,向上为正(注意:与 SVG 相反)。

所以 x 高度 = 1062 这种说法只在 unitsPerEm = 2048 的字体里成立;同一个设计师在 1000 单位的字体里会写大约 518。跨字体比较要换算成百分比。

em 方框不是字面框

em 方框是设计的参考方格,边长 = unitsPerEm。它是排版的基本单位(字号 16px 就是 16px 见方的方框)。

字面框(ink box)是字形真正占的地方,通常比方框小一圈,也可能超出:

  • 拉丁小写字母比方框矮;
  • 手写体、花体的延伸笔画经常冲出方框;
  • 汉字基本填满方框(这也是中文字体看起来更满的原因)。

复合字形

带重音的字符(é、ñ)通常不是单独画的,而是由基字母与符号两个零件的轮廓引用拼成(composite glyph)。

这在 TrueType 里是一组指令(glyf 里的组件记录),在 CFF 里是 seac 或由排版引擎合成。

后果:一个字体可能有 800 个字形,但覆盖 1200 个码位——重音字母是拼出来的。

hinting:小字号下的补偿

早期屏幕分辨率低,曲线落在像素网格上会糊。cvt / fpgm / prep 三张表加上每个字形的指令,可以在渲染时微调笔画位置,让 12px 的字仍然清晰。

今天高分辨率屏幕普及,hinting 的重要性下降,很多新字体干脆不带指令。

hinting 只是「轮廓变像素」那一整套里的一环:抗锯齿、次像素渲染(ClearType)也在同一个环节上 ——见 文字光栅化。

为什么同字号看着不一样大

字号只规定了 em 方框的大小,没规定字面占多少:

  • x 高度大的字体显得更大;
  • 字重更大的字体显得更大(墨多);
  • 汉字填满方框,混排时通常比同字号的西文显眼。

所以把这个字体调成和那个一样大,在技术上做不到精确——只能靠视觉判断或 font-size-adjust 这类补偿(见 合成与杂项)。

在本站哪里看

  • 样例图就是用轮廓画出来的 SVG;
  • 度量图里的 ink 框就是这个字形实际占的范围;
  • 排版预览是真的在用轮廓渲染,不是示意图。

延伸阅读