如何正确理解TrueType cmap的子表格式4?

问题描述 投票:0回答:1

[以下是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. format2. length, 3。语言, 9。 reservePad`是琐碎的基本信息并已被理解。

[其他字段4. segCountX25. searchRange6 .entrySelector7. rangeShift我认为拥有预计算值是一种奇怪的方式,但基本上只是一种存储段数segCount的冗余方式(隐式) 。我对那些领域也没有太大的头痛。

最后保留了表示数组的字段。每个段都有一个字段8. endCode10. stadCode11. idDelta12. idRangeOffset,甚至[[might / might not]]甚至是一个字段13. glyphIdArray。这些是我仍然难以正确解释的领域,而这个问题正是关于这些领域的。为了提供最有用的答案,请允许我快速概述一下这些领域:

    基本上按段工作,每个段将从startCodeendCode的字符代码映射到字体字形的索引(反映了它们在glyf表中出现的顺序)。
  • 将字符代码作为输入
  • 将字形索引作为输出
  • 段是通过反复检查输入值是否在startCodeendCode的范围内而确定的。
  • 具有这样找到的段,还确定了各个字段idRangeOffsetidDelta的字段。
  • [idRangeOffset传达特殊含义
  • 情况A)idRangeOffset设置为特殊值0表示输出可以是根据输入值(字符代码)和idDelta计算得出。 (我认为它是glyphId = inputCharCode + idDeltaglyphId = 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字体格式文档提供的有关“格式4:段映射到增量值”子表格式的信息,可用于...

true-type-fonts
1个回答
1
投票
因为glyphIdArray[]跟随TrueType文件中的idRangeOffset[],所涉及的代码段
© www.soinside.com 2019 - 2024. All rights reserved.