在 OOXML 里有一个段落属性标签 Spacing,该标签上有 lineRule、line 这两个常用的属性,它俩会直接影响文字的行高。
lineRule 可以是 exact(精确值)、atLeast(最小值)、auto(自动),前两个比较好理解,auto 的规则不是很明确。
当 lineRule 为 auto 时,line 中的数值除以 240 表示多倍行距的倍率,比如值为 240 对应的就是单倍行距,值为 360 对应的就是 1.5 倍行距。
核心问题在于,这个多倍的基数是什么?或者说单倍行距到底是多高呢?
在 OOXML 规范中,关于这一点并不是很明确,行高的计算有很多复杂的逻辑,WPS 实现的效果也难以做到和 Office Word 完全一致。
简单来讲,它应该是根据当前 run 文字的字体、字重、字号等属性测量出来的文字行高,对于 CJK 文字,可能会额外乘以一个 extendScale,通常为 1.3。除此之外,还有大量优化细节的逻辑,等后续我对此有更深理解之后再单独展开讲讲。
这里讲一种特殊场景,此场景下的行高规则稍微简单一些,那就是对齐文档网格。
文档网格整体概念比较简单,包含了行网格和字符网格,段落可以设置对齐行网格属性,run 也可以设置对齐文字网格属性。
当一个文档节中设置了行网格,并且段落也开启了对齐网格(默认开启)时,实际文字的行高应该是「文字轮廓行高向上对齐整数个网格线」与「多倍行距(多倍网格线)」中的较大值。
多倍行距这个属性,在对齐网格的场景下,基准将变成单个网格线行高。这一点并不是 OOXML 规范内的要求,而是我通过测试一些 Office Word 实际渲染效果后猜测出来的规则。
实际测试了金山文档、石墨文档、腾讯文档,自由组合对齐网格、段落间距、段前段后、字号等属性,均符合这条规则。
不过也发现,各家的 Word 编辑器行内文字在垂直方向上的基线对齐方式存在一些差异,后面有时间再进一步了解吧。