OpenType字体规范解析(一)综述

OpenType字体规范解析(一)综述

我们在设计中经常需要使用字体文件,有时候会想一窥究竟字体文件到底是以怎样的格式存储的,OpenType就是定义字体文件存储格式的规范。

OpenType 是 Microsoft 和 Adobe 于 1996 年共同开发的字体标准,旨在统一 TrueType 和 PostScript 技术,其文件扩展名可以是 .ttf 或 .otf,取决于内部使用的字形数据格式。

OpenType字体文件规范综述见https://learn.microsoft.com/en-us/typography/opentype/spec/otff

文件结构

OpenType文件由一系列表(table)构成。

表目录

文件开头需要包含表目录。

表目录用于定义字体中所包含的所有顶级表格的信息。这些表格存储了字体渲染、布局和元数据等功能所需的数据。

表目录格式如下:

类型名称描述
uint32sfntVersion0x00010000 或 0x4F54544F(即 ‘OTTO’)
uint16numTables表格数量
uint16searchRange小于或等于 numTables 的最大 2 的幂,乘以 16。公式:(2floor(log2(numTables))) * 16,其中“”为指数运算符。
uint16entrySelector小于或等于 numTables 的最大 2 的幂的对数。公式:log2(searchRange / 16),等价于 floor(log2(numTables))。
uint16rangeShift表格数量乘以 16,减去 searchRange。公式:(numTables * 16) - searchRange。
TableRecordtableRecords[numTables]表格记录数组——每个顶级表格(即字体文件中的主要表格)对应一个记录。

TableRecord

表目录中需要包含每个表对应的TableRecord,其中记录了每个表的概要信息。

TableRecord格式如下:

类型名称描述
TagtableTag表格标识符。
uint32checksum此表格的校验和。
Offser32offset从字体文件开始的偏移量。
uint32length此表格的长度。

核心表

在表目录之后,文件需要包含每个表的具体数据。每个表由不同字段组成,字段的数据格式见下一节。

核心表及其简介:

必须表

这些表是 OpenType 字体文件中必不可少的,它们包含最基本的信息,支持字体的基础功能。

  1. cmap (Character to Glyph Index Mapping Table)
    描述字符编码与字形索引之间的映射,确保输入的文本字符能被正确转换为字形。

  2. head (Font Header Table)
    提供字体的全局信息,如版本号、字体边界框、时间戳等。

  3. hhea (Horizontal Header Table)
    定义水平布局的信息,包括行距、最大字形宽度等。

  4. hmtx (Horizontal Metrics Table)
    存储每个字形的水平指标(如宽度和左边距)。

  5. maxp (Maximum Profile Table)
    指定字体中的各种限制和最大值,例如最大字形数、最大堆栈深度等。

  6. name (Naming Table)
    包含字体的元信息,例如字体名称、版权信息、版本等。

  7. OS/2 (OS/2 and Windows Metrics Table)
    提供与字体相关的详细元数据,例如字重、字体类别、字符范围等。

  8. post (PostScript Table)
    定义字体中字形名称及 PostScript 相关信息。

描述字形的表

这些表包含字形的轮廓或图形描述数据。

  1. glyf (Glyph Data Table)
    定义字形的 TrueType 描述数据(仅适用于 TrueType 字体)。

  2. CFF (Compact Font Format Table)
    提供字形的 CFF 描述数据(适用于 CFF 字体)。

  3. SVG (Scalable Vector Graphics Table)
    用于存储 SVG 格式的矢量图形,用作替代字形。

  4. COLR 和 CPAL (Color Tables)
    用于多色字体(如 Emoji 字体),描述彩色字形和配色。

排版相关的表

这些表提供高级排版功能,支持复杂文本布局。

  1. GSUB (Glyph Substitution Table)
    描述字形替换规则,例如连字或字符形式的替换。

  2. GPOS (Glyph Positioning Table)
    描述字形定位规则,例如调整间距或添加标点符号。

  3. GDEF (Glyph Definition Table)
    定义字形分类及其属性。

  4. BASE (Baseline Table)
    提供基线的对齐信息,用于多种脚本和书写方向。

  5. JSTF (Justification Table)
    定义字体在文本调整中的行为,例如字符间距调整。

图像和位图表

这些表存储位图或其他替代描述的字形数据。

  1. EBDT, EBLC, EBSC
    描述嵌入式位图字形的数据。

  2. sbix (Standard Bitmap Graphics Table)
    提供与字形关联的彩色位图。

  3. CBDT, CBLC
    描述彩色位图字体的数据。

全局辅助表

这些表提供字体文件的全局支持信息。

  1. kern (Kerning Table)
    定义字对的字距调整信息(通常被 GPOS 表取代)。

  2. vhea 和 vmtx
    提供垂直排版的相关信息(适用于垂直书写的字体)。

数据格式

在OpenType字体文件中使用以下数据类型,也就是每个表中所包含的字段,使用以下数据类型存储。另外,所有OpenType字体均使用大端(网络)字节顺序。

数据类型描述
uint88位无符号整数。
int88位有符号整数。
uint1616位无符号整数。
int1616位有符号整数。
uint2424位无符号整数。
uint3232位无符号整数。
int3232位有符号整数。
Fixed32位有符号定点数(16.16格式)。
FWORD描述字体设计单位中数量的int16值。
UFWORD描述字体设计单位中数量的uint16值。
F2DOT1416位有符号定点数,低14位为小数部分(2.14格式)。
LONGDATETIME日期和时间,从UTC时间1904年1月1日午夜12点起计算的秒数,表示为64位有符号整数。
Tag由四个uint8组成的数组(长度=32位),用于标识表、设计变量轴、脚本、语言系统、特性或基线。
Offset8指向表的8位偏移量,与uint8相同,NULL偏移=0x00。
Offset16指向表的短偏移量,与uint16相同,NULL偏移=0x0000。
Offset24指向表的24位偏移量,与uint24相同,NULL偏移=0x000000。
Offset32指向表的长偏移量,与uint32相同,NULL偏移=0x00000000。
Version16Dot16打包的32位值,包含主版本号和次版本号。(参见表版本号的格式说明)。

校验和(checksum)计算

校验和用于确定字体文件的数据完整性,在head表通过checksumAdjustment字段定义。

校验和通过以下方式计算:

uint32
CalcTableChecksum(uint32 *Table, uint32 Length)
{
uint32 Sum = 0L;
uint32 *Endptr = Table+((Length+3) & ~3) / sizeof(uint32);
while (Table < EndPtr)
    Sum += *Table++;
return Sum;
}

值得注意的是,checksumAdjustment并不直接存储校验和,而是存储一个固定数值减去校验和的值。

其设置流程如下:

  1. 将 checksumAdjustment 字段设置为 0。
  2. 计算所有表格(包括 ‘head’ 表格)的校验和,并将每个表格的校验和值填写到表目录中的相应记录。
  3. 计算整个字体的校验和。
  4. 从 0xB1B0AFBA 中减去该值。
  5. 将结果存储在 ‘head’ 表格的 checksumAdjustment 字段中。

这样,可以保证最后,计算整个文件校验和时,其值等于0xB1B0AFBA就说明校验正确。

注:文章包含AI辅助生成内容,如无意中使用了您的数据,请联系笔者进行处理。

小广告

笔者开源了一款字体设计工具,可以设计字体轮廓并生成otf字体文件,欢迎来玩。源码地址:
github: https://github.com/HiToysMaker/fontplayer
gitee: https://gitee.com/toysmaker/fontplayer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值