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

其中:

字体集文件 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)

引用

OpenType 字体文件组织结构的更多相关文章

  1. GetFontResourceInfo 函数: 获取字体文件对应的字体名

    在 win 7, gdi32.dll,找不到 GetFontResourceInfo(), 但能找到 GetFontResourceInfoW(), 用法类似. //----------------- ...

  2. 把vux中的@font-face为base64格式的字体信息解码成可用的字体文件

    在最近移动端项目中用到了vux,感觉用着还习惯,当把vux使用到PC端的时候出现了IE浏览器出现,这样的错误信息: CSS3114: @font-face 未能完成 OpenType 嵌入权限检查.权 ...

  3. [转]TrueType(TTF)字体文件裁剪(支持简体中文,繁体中文TTF字体裁剪)

    原文入口: TTF字体文件裁剪(支持简体中文,繁体中文TTF字体裁剪) 对于TrueType(TTF)字体格式的介绍可以看: https://www.cnblogs.com/slysky/p/1131 ...

  4. @font-face字体文件用法

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. css字体文件

    ├── glyphicons-halflings-regular.eot├── glyphicons-halflings-regular.svg├── glyphicons-halflings-reg ...

  6. cocos2d-x 中 TTF 字体文件的位置

    cocos2d-x 中,字体文件需要保存在 fonts 文件夹中,如果字体路径中没有 fonts/ 会自动添加上这个文件夹. 如果字体名称没有 .ttf 后缀,也会自动加上这个后缀. unsigned ...

  7. Android实例-使用自定义字体文件(XE8+小米2)

    结果: 1.需要修改DELPHI自身的FMX.FontGlyphs.Android.pas,复制到程序的根目录下(红色部分为修改过的). 2.字体文件从 C:\Windows\Fonts 直接拷贝到A ...

  8. iOS使用自定义字体的方法(内置和任意下载ttf\otf\ttc字体文件)

    最近做了个有关阅读的应用,使用了自定义字体,学习了一下这方面的知识. 1.首先是最简单也普遍的做法,打包内置字符库文件: 把字体库文件添加到工程,如font1.ttf添加到工程,然后在工程plist添 ...

  9. js分析 猫_眼_电_影 字体文件 @font-face

    0. 参考 https://developer.mozilla.org/zh-CN/docs/Web/CSS/@font-face 这是一个叫做@font-face 的CSS @规则 ,它允许网页开发 ...

  10. js分析 天_眼_查 字体文件

    0. 参考 js分析 猫_眼_电_影 字体文件 @font-face 1. 分析 1.1 定位目标元素 1.2 查看网页源代码 1.3 requests 请求提取得到大量错误信息 对比猫_眼_电_影抓 ...

随机推荐

  1. 【USB3.0协议学习】Topic3·三种Reset Events分析

    USB3.0中的三种Reset Events 1. PowerOn Reset PowerOn Reset被用来代指上电复位,当一个device接入到root hub或者外置hub的时候,该devic ...

  2. linux overlay文件系统

    一个 overlay 文件系统包含两个文件系统,一个 upper 文件系统和一个 lower 文件系统,是一种新型的联合文件系统.overlay是"覆盖-上面"的意思,overla ...

  3. 05-react的类组件和函数组件 -- 状态 state

    // 函数组件是无状态的 既没有数据的 类似 vue 组件中的 data 数据 // 类组件是有状态的组件 是有数据的 是双向绑定的数据 是数据驱动视图的 负责UI的视图更新 (单个组件的私有数据组件 ...

  4. 05 Transformer 中的前馈神经网络(FFN)的实现

    2:20:理论链接 博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链 ...

  5. [GXYCTF2019]BabyUpload 1

    打开靶机,上传文件抓包 后缀不能带ph,大小写也无法绕过,意味着phtml后缀也无法上传 对后缀只过滤ph,我们转变思路上传图片马,用.htaccess使图片马以php格式打开 上传图片马 上传失败, ...

  6. 在 Kubernetes 中实现微服务应用监控

    张坚,科大讯飞开发工程师,云原生爱好者. 本篇文章我们基于 Prometheus 和 Grafana 实现微服务应用监控. KubeSphere 平台本身提供了监控功能,包括节点状态.集群资源使用率. ...

  7. mysql 备份还原命令备忘

    1.备份 mysqldump -u username -p databasename tableName > backupfile.sql 2.还原 mysql -u username -p p ...

  8. 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(4)

    1.问题描述: 目前华为推送API使用的是v2或者v1版本,请问目前最新的鸿蒙next使用v3版本是否兼容v2或者v1,反过来将v2或者v1的api可以推送鸿蒙next的设备吗? 解决方案: v3接口 ...

  9. NLP语言学基础

    不同的自然语言有不同的语法结构,因此需要对语言数据进行语法解析,才能让机器更准确地学到相应的模式.而语言不同于图像,数据标注工作需要有一定的语言学知识,因此数据的整理也相对更困难.下面以英语为例(别的 ...

  10. apisix问题记录

    负载均衡 可以给 rest api(9080)做负载均衡 不可以给dashboard做负载均衡,否则会出现闪退,dashboard之间的token并不是通用的 路由导出 openapi 路由导出ope ...