【发布时间】:2019-12-19 01:25:51
【问题描述】:
以下是TrueType字体格式documentation提供的关于“格式4:段映射到增量值”子表格式字段的信息,可用于cmap字体表(第用于将字符代码映射到字形索引):
Type Name Description 1. uint16 format Format number is set to 4. 2. uint16 length This is the length in bytes of the subtable. 3. uint16 language For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document. 4. uint16 segCountX2 2 × segCount. 5. uint16 searchRange 2 × (2**floor(log2(segCount))) 6. uint16 entrySelector log2(searchRange/2) 7. uint16 rangeShift 2 × segCount - searchRange 8. uint16 endCode[segCount] End characterCode for each segment, last=0xFFFF. 9. uint16 reservedPad Set to 0. 10. uint16 startCode[segCount] Start character code for each segment. 11. int16 idDelta[segCount] Delta for all character codes in segment. 12. uint16 idRangeOffset[segCount] Offsets into glyphIdArray or 0 13. uint16 glyphIdArray[ ] Glyph index array (arbitrary length)(注意:我对字段进行了编号以允许引用它们)
大部分字段,如1. format、2. length,3。语言,9。 reservedPad`是微不足道的基本信息并且可以理解。
其他字段4. segCountX2、5. searchRange、6 .entrySelector、7. rangeShift 我认为具有预先计算值的一些奇怪方式,但基本上只是存储段数segCount 的一种冗余方式(隐含)。还有那些我没有大头疼的了解的领域。
最后还有代表数组的字段。每个段都有一个字段8. endCode、10. stadCode、11. idDelta 和12. idRangeOffset,可能/可能不会甚至是一个字段13. glyphIdArray。这些是我仍然难以正确解释的领域,也是这个问题的主题。
为了得到最有帮助的答案,请允许我快速勾勒出我对这些领域的看法:
- 基本上是逐段工作,每个段将字符代码从
startCode映射到endCode到字体字形的索引(反映它们在glyf表中出现的顺序)。 - 将字符代码作为输入
- 将字形索引作为输出
- 段是通过迭代它们来确定的,检查输入值是否在
startCode到endCode的范围内。 - 有了这样找到的段,字段各自的字段
idRangeOffset和idDelta也被确定了。 -
idRangeOffset传达了特殊的含义 - case A)
idRangeOffset被设置为特殊值0意味着输出可以是 根据输入值(字符代码)和idDelta计算得出。 (我认为是glyphId = inputCharCode + idDelta或glyphId = inputCharCode - idDelta) - 案例 B)
idRangeOffset不是0会发生不同的事情,这是我在这里寻求答案的一部分。
关于案例 B),文档指出:
如果段的 idRangeOffset 值不为 0,则映射 字符代码依赖于 glyphIdArray。字符代码偏移量 startCode 被添加到 idRangeOffset 值。这笔款项用作 从 idRangeOffset 本身的当前位置到索引的偏移量 出正确的 glyphIdArray 值。这种晦涩的索引技巧有效 因为 glyphIdArray 紧跟在字体中的 idRangeOffset 文件。产生字形索引的 C 表达式是:
glyphId = *(idRangeOffset[i]/2 + (c - startCode[i]) + &idRangeOffset[i])
我认为这提供了一种将连续输入范围(因此是“段”)映射到存储在字段 glyphIdArray 中的值列表的方法,可能作为一种提供无法通过 idDelta 计算的输出值的方法,例如无序/不连续。这至少是我对文档中描述为“晦涩难懂”的内容的阅读。
【问题讨论】:
标签: truetype