OpenType 字体文件组织结构
OpenType 字体文件结构
OpenType 字体的组织
https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
OpenType 字体格式的关键特征是 TrueType 的 “封装”,它以常规和可扩展的方式,为表的集合提供组织方式。
表字典
开始的 12 个字节为表字典定义,这是字体中字典的顶级字典。如果字体文件仅仅包含一种字体,表字典将在文件中的位置 0 处开始。如果字体文件是一个 OpenType 字体集文件,那么该字体表字典的开始位置需要在 TTCHeader 中得到。
Offset | Type | Name | Description |
---|---|---|---|
0 | uint32 | sfntVersion | 0x00010000 or 0x4F54544F ('OTTO') — see below. |
4 | uint16 | numTables | Number of tables. |
6 | uint16 | searchRange | Maximum power of 2 less than or equal to numTables, times 16 ((2floor(log2(numTables))) * 16, where “” is an exponentiation operator). |
8 | uint16 | entrySelector | Log2 of the maximum power of 2 less than or equal to numTables (log2(searchRange/16), which is equal to floor(log2(numTables))). |
10 | uint16 | rangeShift | numTables times 16, minus searchRange ((numTables * 16) - searchRange). |
12 | tableRecord | tableRecords[numTables] | Table records 数组—one for each top-level table in the font |
从位置 12 开始为表记录,每条记录长度为 16 字节。所以表记录的总长度为记录数量 * 16。
表记录
每条表记录长度为 16 个字节,表记录的结构如下所示:
Offset | Type | Name | Description |
---|---|---|---|
0 | Tag | tableTag | 4 个字节长度的表标识名称 |
4 | uint32 | checksum | 校验和 |
8 | Offset32 | offset | 从字体文件开始的偏移量 |
12 | uint32 | length | 该表长度 |
注意:这里的偏移量是文件中从文件开始位置计算的的绝对位置。
次级表
命名表
命名表支持对于 OpenType 字体关联多语言的字符串。这些字符串可以表示版权提示,字体名称,字体族名称,样式名称以及其它内容。为了保持该表简短,字体厂商可能希望提供一个小的语言集,以后,字体可以被 "本地化"。然后添加翻译之后的字符串。
另外,OpenType 字体需要这些字符串作为语言无关的 命名 ID。在附加的语言变体中,该表也支持平台特定的字符编码变体,需要特定字符串的应用程序可以使用平台 ID、编码 ID、语言 ID 和名称 ID 进行搜索。注意,不同的平台可能包含不同的编码字符串的要求。
如果字体没有包含对于该平台的字符串,许多新的平台可以使用其它平台的字符串。因此,如果对于当前平台的字符串没有包含的话,一些应用程序可能显示错误的字符串。
https://docs.microsoft.com/en-us/typography/opentype/spec/name
命名表头
版本 0 的命名表如下组织,开始 6 个字节,然后是名称记录表。最后是实际的字符串数据存储。
每条名称记录长度为 12 字节。
以版本 0 为例,如果共有 21 条记录,那么记录表的长度为 21 * 12 = 252 字节,加上表头的 6 个字节,那么总共为 258 个字节。则 storageOffset 将为 258。
版本 0 的命名表头
Offset | Type | Name | Description |
---|---|---|---|
0 | uint16 | version | Table version number (=0). |
2 | uint16 | count | Number of name records. |
4 | Offset16 | storageOffset | 从该表位置为基准的字符串存储偏移量 |
8 | NameRecord | nameRecord[count] | The name records where count is the number of records. |
(Variable) | Storage for the actual string data. |
见:https://docs.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-0
版本 1 命名表头
Offset | Type | Name | Description |
---|---|---|---|
0 | uint16 | version | Table version number (=1). |
2 | uint16 | count | Number of name records. |
4 | Offset16 | storageOffset | Offset to start of string storage (from start of table). |
8 | NameRecord | nameRecord[count] | The name records where count is the number of records. |
uint16 | langTagCount | Number of language-tag records. | |
LangTagRecord | langTagRecord[langTagCount] | The language-tag records where langTagCount is the number of records. | |
(Variable) | Storage for the actual string data. |
见:https://docs.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-1
命名表记录
每条名称记录长度为 12 字节。
这里的偏移量使用以字节为单位的从存储区开始计算。所以,第一个记录的偏移量将为 0 。
Type | Name | Description |
---|---|---|
uint16 | platformID | Platform ID. |
uint16 | encodingID | Platform-specific encoding ID. |
uint16 | languageID | Language ID. |
uint16 | nameID | Name ID. |
uint16 | length | String length (in bytes). |
Offset16 | stringOffset | String offset from start of storage area (in bytes). |
见:https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-records
其中:
- Platform ID,https://docs.microsoft.com/en-us/typography/opentype/spec/name#platform-ids
- 0: Unicode
- 1: Macintosh
- 2: Windows
- Platform-specific encoding ID,https://docs.microsoft.com/en-us/typography/opentype/spec/name#platform-specific-encoding-and-language-ids-unicode-platform-platform-id--0
- Name ID,https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids
字体集文件 TTC 文件结构
字体集文件包含一个 TTC 头结构,该 TTC 头结构必须位于 TTC 文件的开始部分。
版本 1 的 TTC 头
长度为 12 字节,开始的 4 个字节为 ttcf 串。最后是每种字体的偏移量表。偏移量是 4 个字节的整数表示。
Type | Name | Description |
---|---|---|
TAG | ttcTag | Font Collection ID string: 'ttcf' (used for fonts with CFF or CFF2 outlines as well as TrueType outlines) |
uint16 | majorVersion | Major version of the TTC Header, = 1. |
uint16 | minorVersion | Minor version of the TTC Header, = 0. |
uint32 | numFonts | Number of fonts in TTC |
Offset32 | tableDirectoryOffsets[numFonts] | Array of offsets to the TableDirectory for each font from the beginning of the file |
然后每种字体的结构见前面的 OpenType 字体组织。
版本 2 的 TTC 头
Type | Name | Description |
---|---|---|
TAG | ttcTag | Font Collection ID string: 'ttcf' |
uint16 | majorVersion | Major version of the TTC Header, = 2. |
uint16 | minorVersion | Minor version of the TTC Header, = 0. |
uint32 | numFonts | Number of fonts in TTC |
Offset32 | tableDirectoryOffsets[numFonts] | Array of offsets to the TableDirectory for each font from the beginning of the file |
uint32 | dsigTag | Tag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature) |
uint32 | dsigLength | The length (in bytes) of the DSIG table (null if no signature) |
uint32 | dsigOffset | The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature) |