规范中 TTF 字体构建的缺失部分
Missing pieces for TTF font building from Spec
我无法解决这些与 TTF 规范相关的问题。
- "Computing the checksum" 在 "head".
- "xMin"、"yMin"、等 "head"
- maxPoints、maxContours、maxComponentPoints、maxComponentContours、maxTwilightPoints "maxp"
uint8 flags[variable] Array of flags
在 "glyf"
我想知道是否有人可以澄清这些片段。
1
对于 (1) it says 这个:
checkSumAdjustment To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory, sum the entire font as a uint32_t, then store 0xB1B0AFBA - sum. (The checksum for the 'head' table will be wrong as a result. That is OK; do not reset it.),
我找到了他们引用的两个校验和实现:
// 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。所以看起来是这样的:
- 计算头部校验和 table。
- "sum the entire font as a" 不知道什么意思.
- 也不知道这意味着什么("then store 0xB1B0AFBA - sum. (The checksum for the 'head' table will be wrong as a result. That is OK; do not reset it.),")
2
对于 (2),我不确定如何计算。似乎我只是将所有字形捆绑成一个 spritemap,然后计算最终大小。但是我认为它说不要考虑字形的边界框,所以 不完全 确定它的意思。
3
对于 (3),未找到有关这些变量含义的任何文档。
4
对于(4),我不知道这是什么意思"uint8 flags[variable] Array of flags"。他们在下面有 table,但我不确定它是 per contour 还是 per glyph 或 per点.
我还有一个关于理解复合字形的相关问题here 如果你知道的话。
一般来说,您可能会发现 current OpenType specification 很有用,因为它包含许多 Apple 版本中没有的更新、说明和更正。
关于您的具体问题:
1head.checksumAdj
计算
说明相当清楚,虽然有隐含的 "step zero" of assemble 所有字体数据(tables、目录等)进入最终版本表格和顺序。一旦你拥有了:
将 head
table 中的 checkSumAdj
的值设置为零
计算 head
table 的校验和并将其存储在字体的 table 目录(其中 tag/checksum/offset/length 是为字体中包含的所有 table 存储)
计算整个字体的总和(所有uint32的总和,就像table校验和),包括步骤1和2的修改。
将 0xB1B0AFBA 减去步骤 3 中的值存储在 head.checkSumAdj
中。就这样!关于头部校验和出现不正确的措辞意味着如果你要 运行 在 head
table 之后 存储最终值的校验和计算,这看起来是错误的。但这没关系,因为它是这样定义的:本质上是 head
table 的校验和,您必须首先忽略(设置为 0)checkSumAdj
值。
2 head
xMin, xMax, yMin, yMax
这就是所有字形的 xMin、xMax、yMin 和 yMax。每个 字形 xMin、xMax 等都非常简单 "the minimum (maximum) X (Y) coordinate" 所有点(对于复合字形,你会在 after组成字形,即在复合字形定义中应用任何移位、缩放或其他转换之后)。在 head
table 和字形数据中,边界框都是一个 16 位有符号整数数组。所以通常的过程是遍历每个字形,得到计算出的边界框,当你这样做的时候,跟踪 X/Y min/max (独立)。完成循环后,您将获得 head
table 的值,它本质上是一个矩形,包含字体中每个字形的每个坐标。
3 maxp
值
这些在 maxp
table definition 中有相当明确的定义:
maxPoints
是任意单个非复合("simple")字形的最大点数
maxContours
同样是任何单个非复合 字形
的最大轮廓数
maxComponentPoints
是复合字形中的最大点数(即所有组成字形的点数之和)
maxComponentContours
同样是 composite glyph
中的最大轮廓数
maxTwilightPoints
是指TrueType指令0区使用的最大"twilight"点数。如果您的字体不使用 TrueType 指令,则可以将此(以及其他与指令相关的字段)设置为零。如果您不熟悉 TrueType 指令(通常称为 "hints")以及它们如何存储在字形数据中,您可能需要查看 OpenType 规范的“Instructing TrueType Glyphs" and "TrueType Instruction Set”部分。
4 glyf
table 简单字形标志
uint8 flags[variable]
表示flags数组长度可变。其原因在 specification ("Simple Glyph Flags"):
中讨论
In logical terms, there is one flag byte element, one x-coordinate,
and one y-coordinate for each point. Note, however, that the flag
byte elements and coordinate arrays used packed representations. In
particular if a logical sequence of flag elements or sequence of x-
or y- coordinates is repeated, then the actual flag byte element or
coordinate value can be given in a single entry, with special flags
used to indicate that this value is repeated for subsequent logical
entries.
换句话说,flags
数组的元素,展开后是每个坐标,但实际存储 作为 uint8 数组不一定(与坐标数据本身的存储一样)。很大程度上取决于每个字形中的坐标排列。
我无法解决这些与 TTF 规范相关的问题。
- "Computing the checksum" 在 "head".
- "xMin"、"yMin"、等 "head"
- maxPoints、maxContours、maxComponentPoints、maxComponentContours、maxTwilightPoints "maxp"
uint8 flags[variable] Array of flags
在 "glyf"
我想知道是否有人可以澄清这些片段。
1
对于 (1) it says 这个:
checkSumAdjustment To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory, sum the entire font as a uint32_t, then store 0xB1B0AFBA - sum. (The checksum for the 'head' table will be wrong as a result. That is OK; do not reset it.),
我找到了他们引用的两个校验和实现:
// 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。所以看起来是这样的:
- 计算头部校验和 table。
- "sum the entire font as a" 不知道什么意思.
- 也不知道这意味着什么("then store 0xB1B0AFBA - sum. (The checksum for the 'head' table will be wrong as a result. That is OK; do not reset it.),")
2
对于 (2),我不确定如何计算。似乎我只是将所有字形捆绑成一个 spritemap,然后计算最终大小。但是我认为它说不要考虑字形的边界框,所以 不完全 确定它的意思。
3
对于 (3),未找到有关这些变量含义的任何文档。
4
对于(4),我不知道这是什么意思"uint8 flags[variable] Array of flags"。他们在下面有 table,但我不确定它是 per contour 还是 per glyph 或 per点.
我还有一个关于理解复合字形的相关问题here 如果你知道的话。
一般来说,您可能会发现 current OpenType specification 很有用,因为它包含许多 Apple 版本中没有的更新、说明和更正。
关于您的具体问题:
1head.checksumAdj
计算
说明相当清楚,虽然有隐含的 "step zero" of assemble 所有字体数据(tables、目录等)进入最终版本表格和顺序。一旦你拥有了:
将
head
table 中的checkSumAdj
的值设置为零计算
head
table 的校验和并将其存储在字体的 table 目录(其中 tag/checksum/offset/length 是为字体中包含的所有 table 存储)计算整个字体的总和(所有uint32的总和,就像table校验和),包括步骤1和2的修改。
将 0xB1B0AFBA 减去步骤 3 中的值存储在
head.checkSumAdj
中。就这样!关于头部校验和出现不正确的措辞意味着如果你要 运行 在head
table 之后 存储最终值的校验和计算,这看起来是错误的。但这没关系,因为它是这样定义的:本质上是head
table 的校验和,您必须首先忽略(设置为 0)checkSumAdj
值。
2 head
xMin, xMax, yMin, yMax
这就是所有字形的 xMin、xMax、yMin 和 yMax。每个 字形 xMin、xMax 等都非常简单 "the minimum (maximum) X (Y) coordinate" 所有点(对于复合字形,你会在 after组成字形,即在复合字形定义中应用任何移位、缩放或其他转换之后)。在 head
table 和字形数据中,边界框都是一个 16 位有符号整数数组。所以通常的过程是遍历每个字形,得到计算出的边界框,当你这样做的时候,跟踪 X/Y min/max (独立)。完成循环后,您将获得 head
table 的值,它本质上是一个矩形,包含字体中每个字形的每个坐标。
3 maxp
值
这些在 maxp
table definition 中有相当明确的定义:
maxPoints
是任意单个非复合("simple")字形的最大点数maxContours
同样是任何单个非复合 字形 的最大轮廓数
maxComponentPoints
是复合字形中的最大点数(即所有组成字形的点数之和)maxComponentContours
同样是 composite glyph 中的最大轮廓数
maxTwilightPoints
是指TrueType指令0区使用的最大"twilight"点数。如果您的字体不使用 TrueType 指令,则可以将此(以及其他与指令相关的字段)设置为零。如果您不熟悉 TrueType 指令(通常称为 "hints")以及它们如何存储在字形数据中,您可能需要查看 OpenType 规范的“Instructing TrueType Glyphs" and "TrueType Instruction Set”部分。
4 glyf
table 简单字形标志
uint8 flags[variable]
表示flags数组长度可变。其原因在 specification ("Simple Glyph Flags"):
In logical terms, there is one flag byte element, one x-coordinate, and one y-coordinate for each point. Note, however, that the flag byte elements and coordinate arrays used packed representations. In particular if a logical sequence of flag elements or sequence of x- or y- coordinates is repeated, then the actual flag byte element or coordinate value can be given in a single entry, with special flags used to indicate that this value is repeated for subsequent logical entries.
换句话说,flags
数组的元素,展开后是每个坐标,但实际存储 作为 uint8 数组不一定(与坐标数据本身的存储一样)。很大程度上取决于每个字形中的坐标排列。