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

问题描述

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

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

解决方法

根据 https://docs.microsoft.com/en-us/typography/opentype/otspec140/cmap#format-4-segment-mapping-to-delta-values,这是没有意义的,因为非零的 idRangeOffset 意味着解析器需要查询 glyphIdArray,它不涉及 {{1 }} 值,而 idDelta 表示段的字形 ID 基于将 idRangeOffset:0 添加到字符代码偏移量,并且使用 {{ 1}}。

所以要回答您的问题:“如果从 glyphIndexArray 中提取的字形索引可以是字体制造商想要的任何东西,为什么还需要添加 idDelta?”,原因是“因为根本不会发生这种情况”。

引用规范:

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

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

值 c 是有问题的字符代码,i 是 c 出现的段索引。如果索引操作得到的值不为0(表示missingGlyph),则将idDelta[i]加入其中,得到字形索引。 idDelta 算法是模 65536。

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

虽然规范假设你知道 C 是如何工作的,但现在人们并不知道:前面的 idDelta 意味着我们正在计算一个字节偏移量,相对于文件的开头。 glyphIdArray 表示“这个东西的内存位置”(尽管在这种情况下,这意味着我们字体文件中的字节偏移量),因此我们将一个数字(*)添加到ith 范围偏移量 (&),它为我们提供了一个新的偏移量。如果我们从与该数字对应的字节偏移量开始读取字体字节,我们将在正确的位置读取我们的字形 ID。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...