我在解决有关TTF规范的问题时遇到问题。
uint8 flags[variable] Array of flags
在“ glyf”中我想知道是否有人可以澄清这些内容。
为此(1)it says:
checkSumAdjustment进行计算:将其设置为0,计算“ head”表的校验和并将其放在表目录中,将整个字体求和为uint32_t,然后存储0xB1B0AFBA-sum。 (因此,“ head”表的校验和将是错误的。可以,请不要重置它。),
我发现了他们引用的两个校验和实现:
// https://docs.microsoft.com/en-us/typography/opentype/spec/otff
uint32
CalcTableChecksum(uint32 *Table, uint32 Length)
{
uint32 Sum = 0L;
uint32 *Endptr = Table+((Length+3) & ~3) / sizeof(uint32);
while (Table < EndPtr)
Sum += *Table++;
return Sum;
}
uint32 CalcTableChecksum(uint32 *table, uint32 numberOfBytesInTable)
{
uint32 sum = 0;
uint32 nLongs = (numberOfBytesInTable + 3) / 4;
while (nLongs-- > 0)
sum += *table++;
return sum;
}
那是简单的实现。我的问题是,校验和 value 中包含什么。看起来就像这样:
对于(2),我不确定如何计算。看来我只是将所有字形像spritemap一样捆绑在一起,然后计算最终大小。但是它说我不考虑字形的边界框,所以不能完全确定其含义。
对于(3),没有找到有关这些变量含义的任何文档。
对于(4),我不知道这是什么意思“ uint8 flags [variable]标志数组”。它们具有下表,但我不确定它是每个轮廓还是每个字形还是每个点。
如果您有任何了解,我还有一个有关理解复合字形here的相关问题。
答案 0 :(得分:1)
通常,您会发现current OpenType specification有用,因为它包含许多Apple版本中未出现的更新,说明和更正。
关于您的具体问题:
1 head.checksumAdj
个计算
说明很合理,尽管隐含了“步骤0”,将所有字体数据(表,目录等)组装成最终形式和顺序。一旦拥有了:
将checkSumAdj
表中head
的值设置为零
仅计算head
表的校验和,并将其存储在字体的表目录中的相应字段中(在其中为字体中包含的所有表存储标签/校验和/偏移量/长度)< / p>
计算整个字体的总和(所有uint32的总和,就像表校验和一样),包括步骤1和2中的修改。
存储 0xB1B0AFBA减去head.checkSumAdj
中第3步的值。就这样!关于头校验和的措词显示不正确,这意味着如果要在存储最终值之后在head
表 上运行校验和计算,则会出现错误。但这没关系,因为它是这样定义的:本质上,对于head
表的校验和,必须首先忽略checkSumAdj
值(将其设置为0)。
2 head
xMin,xMax,yMin,yMax
这只是所有字形的xMin,xMax,yMin和yMax。每个字形 xMin,xMax等都非常简单,是所有点的“最小(最大)X(Y)坐标”(对于复合字形,您可以在之后得到结果构成字形,即在复合字形定义中应用任何移位,缩放或其他变换之后)。在head
表和字形数据中,边界框都是16位带符号整数的数组。因此,通常的过程是遍历每个字形,获取计算出的边界框,并在执行此操作时,(独立地)跟踪X / Y的最小值/最大值。完成循环后,您将获得head
表的值,该表实际上是一个矩形,其中包括字体中每个字形的每个坐标。
3个maxp
值
在maxp
table definition中,这些定义相当合理:
maxPoints
是任何单个非复合(“简单”)字形
maxContours
类似地是任何单个非复合字形
maxComponentPoints
是复合字形中的最大点数(即所有组成字形的点数之和)
maxComponentContours
类似地是复合字形
maxTwilightPoints
是指TrueType指令的区域0中使用的“暮光”点的最大数量。如果您的字体不使用TrueType指令,则可以将此(以及其他与指令相关的字段)设置为零。如果您不熟悉TrueType指令(通常称为“提示”)及其如何存储在OpenType规范中,则可能需要查看OpenType规范的“ Instructing TrueType Glyphs”和“ TrueType Instruction Set”部分。字形数据。
4个glyf
表简单字形标志
uint8 flags[variable]
表示 flags数组的长度是可变的。 specification(“简单字形标志”)中对此进行了讨论:
从逻辑上讲,有一个标志字节元素,一个x坐标, 每个点一个y坐标。 但是请注意,该标志 字节元素和坐标数组使用打包表示形式。 如果标记元素的逻辑序列或x-的序列,则为 或y坐标重复,然后是实际的标志字节元素或 坐标值可以在单个条目中给出,并带有特殊标志 用于指示此值对于后续逻辑重复 条目。
换句话说,flags
数组的元素,在展开时是按坐标的,但是实际的 storage 作为uint8数组却不是必要的(与坐标数据本身的存储一样)。在很大程度上取决于每个字形中坐标的排列。