TrueType 字体中 idDelta 和 idRangeOffset 可以都非零吗?

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

是否有可能在 TrueType 字体的 cmap 格式 4 中,段的 idDelta 和 idRangeOffset 都非零?如果是这样,为什么?

如果从 glyphIndexArray 获取的字形索引可以是字体制造商想要的任何内容,为什么还需要添加 idDelta?

fonts truetype opentype
2个回答
1
投票

根据https://learn.microsoft.com/en-us/typography/opentype/otspec140/cmap#format-4-segment-mapping-to-delta-values,这没有意义,因为

非零的 idRangeOffset
意味着解析器需要查阅
glyphIdArray
,这不以任何方式涉及
idDelta
值,而
idRangeOffset:0
意味着段的字形 id 基于添加
idDelta
到字符代码偏移量,并且 not 使用
glyphIdArray
。那么,可以它们都非零吗?当然。数学仍然有效。

但这也很奇怪,主要是因为你的问题的答案“如果从 glyphIndexArray 获取的字形索引可以是字体制造商想要的任何内容,为什么你需要添加 idDelta?”:因为这表明你误解了 idDelta和 idRangeOffset 工作。

引用规格:

如果该段的idRangeOffset值不为0,则字符编码的映射依赖于glyphIdArray。距 startCode 的字符代码偏移量将添加到 idRangeOffset 值中。该总和用作 idRangeOffset 本身内当前位置的偏移量,以索引出正确的 glyphIdArray 值。这种晦涩的索引技巧之所以有效,是因为 glyphIdArray 紧跟在字体文件中的 idRangeOffset 之后。产生字形索引的 C 表达式是:

*(idRangeOffset[i]/2 + (c - startCount[i]) + &idRangeOffset[i])

值c是所涉及的字符代码,i是c出现的段索引。如果索引操作获得的值不为0(表示缺少Glyph),则将idDelta[i]添加到它以获得字形索引。 idDelta 算术以 65536 为模。

如果 idRangeOffset 为 0,则将 idDelta 值直接与字符代码偏移量(即 idDelta[i] + c)相加,得到对应的字形索引。同样,idDelta 算术以 65536 为模。

虽然规范假设您知道 C 是如何工作的,但现在人们并不知道:前面的

*
意味着我们正在计算相对于文件开头的字节偏移量。
&
表示“这个东西的内存位置”(尽管在本例中这意味着我们字体文件中的字节偏移量)。

因此:我们将一个数字 (

idRangeOffset[i]/2 + (c - startCount[i])
) 添加到第 ith 范围偏移量 (
&idRangeOffset[i]
) 的字节位置,这为我们提供了一个新的偏移量。如果我们从与该数字对应的字节偏移量开始读取字体字节,我们将在正确的位置读取字形 id。在这种情况下,我们不需要 idDelta,因为我们不使用段。


0
投票

但是有一个问题。 2020 年 6 月,我发现运行 iOS 12.4.6 的 iPhone 6 和 7 会假设 idRangeOffset 非零时 idDelta 为零。子表与 Windows 和 HarfBuzz 渲染器一起正常工作。我不知道iOS 12.5.5中的解释是否固定,也不知道MacOS的情况。这样的错误可以持续这么长时间,这表明这种优化很少被应用——它只在不寻常的情况下可用。

© www.soinside.com 2019 - 2024. All rights reserved.