Spec

时间:2019-01-11 18:07:09

标签: fonts specifications true-type-fonts

我在解决有关TTF规范的问题时遇到问题。

  1. “头部”中的“计算校验和”。
  2. “ head”中的“ xMin”,“ yMin”等
  3. “ maxp”中的maxPoints,maxContours,maxComponentPoints,maxComponentContours,maxTwilightPoints
  4. uint8 flags[variable] Array of flags在“ glyf”中

我想知道是否有人可以澄清这些内容。

1

为此(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 中包含什么。看起来就像这样:

  1. 计算主表的校验和。
  2. ”将整个字体加为“ 不知道这是什么意思
  3. 不知道这是什么意思(“然后存储0xB1B0AFBA-总和。(因此,'head'表的校验和将是错误的。可以,请不要重置它。),”)

2

对于(2),我不确定如何计算。看来我只是将所有字形像spritemap一样捆绑在一起,然后计算最终大小。但是它说我不考虑字形的边界框,所以不能完全确定其含义。

3

对于(3),没有找到有关这些变量含义的任何文档。

4

对于(4),我不知道这是什么意思“ uint8 flags [variable]标志数组”。它们具有下表,但我不确定它是每个轮廓还是每个字形还是每个点

如果您有任何了解,我还有一个有关理解复合字形here的相关问题。

1 个答案:

答案 0 :(得分:1)

通常,您会发现current OpenType specification有用,因为它包含许多Apple版本中未出现的更新,说明和更正。

关于您的具体问题:

1 head.checksumAdj个计算

说明很合理,尽管隐含了“步骤0”,将所有字体数据(表,目录等)组装成最终形式和顺序。一旦拥有了:

  1. checkSumAdj表中head的值设置为零

  2. 仅计算head表的校验和,并将其存储在字体的表目录中的相应字段中(在其中为字体中包含的所有表存储标签/校验和/偏移量/长度)< / p>

  3. 计算整个字体的总和(所有uint32的总和,就像表校验和一样),包括步骤1和2中的修改。

  4. 存储 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数组却不是必要的(与坐标数据本身的存储一样)。在很大程度上取决于每个字形中坐标的排列。