文章目录
- OpenType字体规范解析(七)OS/2表、post表
- OS/2表
- OS/2表格式
- xAvgCharWidth
- usWeightClass
- usWidthClass
- fsType
- 下标、上标字符
- sFamilyClass
- panose
- ulUnicodeRange
- achVendID
- fsSelection
- usFirstCharIndex、usLastCharIndex
- sTypoAscender、sTypoDescender、sTypoLineGap
- usWinAscent、usWinDescent
- ulCodePageRange1、ulCodePageRange2
- sxHeight、sCapHeight
- usDefaultChar
- usBreakChar
- usMaxContext
- usLowerOpticalPointSize、usUpperOpticalPointSize
- post表
- 小广告
OpenType字体规范解析(七)OS/2表、post表
我们在设计中经常需要使用字体文件,有时候会想一窥究竟字体文件到底是以怎样的格式存储的,OpenType就是定义字体文件存储格式的规范。
这篇文章主要介绍了OS/2表和post表。
OS/2表
OS/2 表包含OpenType字体中所需的度量和其他数据。
OS/2表格式
类型 | 名称 | 描述 |
---|---|---|
uint16 | version | 表的版本号 |
FWORD | xAvgCharWidth | 字体中所有字符的平均宽度(单位:em) |
uint16 | usWeightClass | 字体的字重(Weight),范围为 1–1000,常见值如 400(Regular)、700(Bold)。 |
uint16 | usWidthClass | 字体的宽度类别,范围为 1(Ultra-condensed)到 9(Ultra-expanded)。 |
uint16 | fsType | 字体的嵌入许可权限,如禁止嵌入、仅打印预览等。 |
FWORD ySubscriptXSize | 下标字符的推荐宽度。 | |
FWORD ySubscriptYSize | 下标字符的推荐高度。 | |
FWORD ySubscriptXOffset | 下标字符相对基线的 X 轴偏移量。 | |
FWORD ySubscriptYOffset | 下标字符相对基线的 Y 轴偏移量。 | |
FWORD ySuperscriptXSize | 上标字符的推荐宽度。 | |
FWORD ySuperscriptYSize | 上标字符的推荐高度 | |
FWORD ySuperscriptXOffset | 上标字符相对基线的 X 轴偏移量。 | |
FWORD ySuperscriptYOffset | 上标字符相对基线的 Y 轴偏移量。 | |
FWORD yStrikeoutSize | 删除线的厚度。 | |
FWORD yStrikeoutPosition | 删除线相对基线的位置。 | |
int16 sFamilyClass | 字体家族类别,用于定义字体的设计风格(如 Serif、Sans-serif)。 | |
uint8 panose[10] | 用于描述字体外观的 PANOSE 分类编号系统。 | |
uint32 ulUnicodeRange1 Bits 0 – 31 | 字体支持的 Unicode 字符范围的第一部分(最低 32 位)。 | |
uint32 ulUnicodeRange2 Bits 32 – 63 | 字体支持的 Unicode 字符范围的第二部分(32–63 位)。 | |
uint32 ulUnicodeRange3 Bits 64 – 95 | 字体支持的 Unicode 字符范围的第三部分(64–95 位)。 | |
uint32 ulUnicodeRange4 Bits 96 – 127 | 字体支持的 Unicode 字符范围的第四部分(96–127 位)。 | |
Tag achVendID | 字体供应商的 4 字符标识符。 | |
uint16 fsSelection | 字体样式选择标志,例如 Italic、Bold、Regular。 | |
uint16 usFirstCharIndex | 字体支持的第一个字符的 Unicode 编码值。 | |
uint16 usLastCharIndex | 字体支持的最后一个字符的 Unicode 编码值。 | |
FWORD sTypoAscender | 字体设计的上升高度(相对基线的高度)。 | |
FWORD sTypoDescender | 字体设计的下降高度(相对基线的深度)。 | |
FWORD sTypoLineGap | 设计行间距,定义行间的额外空间。 | |
UFWORD usWinAscent | 字体在 Windows 平台上的上升高度,用于行高计算。 | |
UFWORD usWinDescent | 字体在 Windows 平台上的下降深度,用于行高计算。 | |
uint32 ulCodePageRange1 Bits 0 – 31 | 字体支持的代码页范围的第一部分(最低 32 位)。 | |
uint32 ulCodePageRange2 Bits 32 – 63 | 字体支持的代码页范围的第二部分(32–63 位)。 | |
FWORD sxHeight | 字母“x”的高度,用于小写字符的比例计算。 | |
FWORD sCapHeight | 大写字符的高度(如“X”的高度)。 | |
uint16 usDefaultChar | 默认字符的 Unicode 编码(用于替代未定义字符)。 | |
uint16 usBreakChar | 用于断行的字符(通常为空格)。 | |
uint16 usMaxContext | 字体上下文长度的最大值(如字形替换所需的上下文长度)。 | |
uint16 usLowerOpticalPointSize | 字体的最低推荐光学字号。 | |
uint16 usUpperOpticalPointSize | 字体的最高推荐光学字号。 |
xAvgCharWidth
xAvgCharWidth
是字体中所有字形的平均宽度(以 unitsPerEm
为单位)。其主要作用如下:
-
性能优化
- 某些排版或渲染引擎会使用
xAvgCharWidth
来快速估算文本段的宽度,从而优化布局性能。 - 在处理大段文本时,可以通过平均宽度估算总长度,避免逐字计算。
- 某些排版或渲染引擎会使用
-
文字对齐与间距调整
xAvgCharWidth
可用于设计字体时的对齐参考值。- 排版引擎可能基于此值调整字符间距(例如实现类似
justify
的文本对齐功能)。
-
文本测量的默认值
- 如果没有特定的宽度值,某些系统可能会将
xAvgCharWidth
作为字形宽度的默认值。例如,当需要估算某些未知字形的宽度时。
- 如果没有特定的宽度值,某些系统可能会将
-
跨平台兼容性
- 不同平台(如 Windows 和 macOS)可能使用此字段协助一致的文本布局效果。
xAvgCharWidth
的值一般通过字体中的所有字形的实际宽度(即 advanceWidth
)加权平均计算得到。具体计算公式可能类似于:
[
\text{xAvgCharWidth} = \frac{\sum (\text{advanceWidth} \times \text{glyphFrequency})}{\text{totalGlyphCount}}
]
- advanceWidth:每个字形的宽度。
- glyphFrequency:字形的使用频率(如基于常见文本样本的统计)。
- totalGlyphCount:字体中所有字形的总数。
虽然 xAvgCharWidth
并不是排版引擎必须依赖的字段,但它是一个有用的参考值,尤其在支持多语言和高效文本布局时,能够简化字体渲染的流程。
usWeightClass
usWeightClass 用于定义字体的字重(weight),即字体的粗细程度。在排版或设计应用中,通过 usWeightClass 区分字体的粗细等级(如 Regular、Bold、Light 等),便于用户选择合适的字重。在网页设计中,usWeightClass 的值可以映射到 CSS 的 font-weight 属性,以控制字体粗细。
usWeightClass 的取值范围为 1 至 1000,但通常只使用以下推荐值:
值 | 描述 | 示例字体 |
---|---|---|
100 | Thin | 非常细 |
200 | Extra Light (Ultra Light) | 特细 |
300 | Light | 细 |
400 | Normal (Regular) | 常规字体(正文字体) |
500 | Medium | 中等粗细 |
600 | Semi Bold (Demi Bold) | 中粗字体 |
700 | Bold | 粗体 |
800 | Extra Bold (Ultra Bold) | 特粗 |
900 | Black (Heavy) | 极粗字体 |
1000 | Extra Black (Ultra Black) | 超粗 |
usWidthClass
usWidthClass
用于定义字体的宽度(width),即字符的横向压缩或拉伸程度。这个字段的主要作用包括:
- 区分字体宽度
- 在一个字体家族(Font Family)中,用于标识不同宽度的变体(如 Condensed、Expanded 等)。
- 辅助字体选择
- 排版引擎或设计软件可通过此字段自动匹配适合的宽度变体。
- 跨平台一致性
- 确保字体在不同操作系统或应用程序中,显示的字符宽度一致。
- 映射到 CSS 属性
- 在网页设计中,
usWidthClass
可以影响字体在 CSS 中的宽度定义,例如通过font-stretch
属性进行调整。
- 在网页设计中,
usWidthClass
的取值范围为 1 到 9,具体定义如下:
值 | 描述 | 含义 |
---|---|---|
1 | Ultra-condensed | 极度紧缩 |
2 | Extra-condensed | 特别紧缩 |
3 | Condensed | 紧缩 |
4 | Semi-condensed | 半紧缩 |
5 | Medium (Normal) | 正常宽度(默认值) |
6 | Semi-expanded | 半扩展 |
7 | Expanded | 扩展 |
8 | Extra-expanded | 特别扩展 |
9 | Ultra-expanded | 极度扩展 |
fsType
fsType
主要用于定义字体的授权和使用许可,指示字体的使用限制。这个字段的值可以决定字体的可嵌入性、可编辑性等特性,通常由字体设计者或授权方设置。
fsType
是一个 16 位的字段,表示为 2 个字节。它的具体取值可以是以下几种情况(根据位的组合):
位值 | 描述 |
---|---|
Bit 0 | 禁止嵌入字体(如果设置为 1) |
Bit 1 | 禁止文档修改(如果设置为 1) |
Bit 2 | 禁止在服务器上使用(如果设置为 1) |
Bit 3 | 禁止将字体嵌入可编辑文档(如果设置为 1) |
常见的 fsType
值:
值 | 描述 |
---|---|
0 | 字体没有限制,完全自由使用 |
1 | 禁止嵌入字体 |
2 | 禁止修改文档 |
3 | 禁止在服务器上使用(通常为 Web) |
4 | 禁止嵌入可编辑文档 |
5 | 字体只可以嵌入“打印”文档,但不能嵌入可编辑文档 |
6 | 字体只能嵌入“打印”文档 |
7 | 只允许个人使用,不允许商用或传播 |
下标、上标字符
在字体排版中,有时需要使用下标或上标字符,ySubscriptXSize等字段定义了下标、上标字符的尺寸、位置等属性。下标、上标字符通常用于数学公式、化学式或者文本中的注释等场景,它们的显示要求与普通字符有所不同。
sFamilyClass
sFamilyClass表示字体的家族类别(family class),它的作用是通过数字编码来标识字体的样式和类型。这个字段有助于确定字体的设计风格和类型,从而在选择字体时可以更容易地进行分类和过滤。
sFamilyClass
的值分为两部分:
- 高 8 位(字节 0):指定字体的设计类型(如衬线字体、无衬线字体等)。
- 低 8 位(字节 1):指定字体的样式,例如常规、斜体、粗体等。
panose
panose用于描述字体的视觉特征或样式,帮助操作系统和应用程序在字体匹配和选择时使用。具体来说,panose 是一种通过数字编码来标识字体外观特征的方法,类似于一个视觉指纹。panose 字段是 PANOSE 1.0 规范的实现,通过一组十个字节的值来描述字体的风格、重量、宽度等特征。
panose 字段由10个字节组成,每个字节对应字体的一个具体特征。通过这些特征,字体可以被描述为不同的视觉风格。以下是每个字节的意义:
-
Family Type (字节 1):
表示字体的家族类型,比如无衬线字体、衬线字体、等宽字体等。
取值范围:0-11(每个值对应一个家族类型,如无衬线、衬线、手写等)。 -
Serif Style (字节 2):
仅适用于衬线字体,用于描述衬线的样式。比如直线衬线、弯曲衬线等。
取值范围:0-5(不同的衬线样式)。 -
Weight (字节 3):
字体的粗细程度。例如轻、正常、粗体等。
取值范围:0-9(从极细到极粗的不同等级)。 -
Proportion (字节 4):
字体的宽度,比如标准宽度、压缩宽度或扩展宽度等。
取值范围:0-9(标准宽度、扩展、压缩等)。 -
Contrast (字节 5):
字体笔画的对比度,即笔画的粗细变化。高对比度和低对比度的字体外观不同。
取值范围:0-5(从低对比到高对比)。 -
Stroke Variation (字节 6):
字体的笔画变化,描述字体笔画的粗细变化。是否有均匀的笔画,还是有变化的笔画。
取值范围:0-3(均匀笔画、变化笔画等)。 -
Arm Style (字节 7):
字母中横臂的样式。不同的字体会在横向的笔画上有所不同,可能是水平的、倾斜的等。
取值范围:0-5(如水平、弯曲、角度等)。 -
Letterform (字节 8):
字母的形态,指字形的样式。例如圆形字形、方形字形等。
取值范围:0-5(不同字形风格)。 -
Midline (字节 9):
字母的中线,指的是字母的中部。例如是高、中、低等。
取值范围:0-2(如上中线、下中线、无中线)。 -
X-height (字节 10):
字母的 X 高度,指的是小写字母(如 “x”)的高度。X 高度是字体中小写字母的标高,影响字体的视觉效果。
取值范围:0-5(小到大不同的 X 高度值)。
ulUnicodeRange
ulUnicodeRange用于指定字体所覆盖的 Unicode 字符范围。这有助于应用程序和操作系统快速确定字体是否支持特定的 Unicode 字符,从而进行适当的字体选择和渲染。
achVendID
用于标识创建或分发字体的公司、组织或个人。这是一个 4 字节(4 个 ASCII 字符)长的字段,通过为每个供应商分配唯一的代码,帮助区分字体的来源。
fsSelection
Bit | 描述 |
---|---|
0 | Italic:如果设置为 1,则表明字体是斜体。 |
1 | Underscore:如果设置为 1,则表明字体支持下划线功能(很少使用)。 |
2 | Negative:如果设置为 1,则表明字体是倒影(白色轮廓字体,背景填充黑色,通常用于特殊效果)。 |
3 | Outlined:如果设置为 1,则表明字体是轮廓字体。 |
4 | Strikeout:如果设置为 1,则表明字体支持删除线功能。 |
5 | Bold:如果设置为 1,则表明字体是粗体。 |
6 | Regular:如果设置为 1,则表明字体是常规样式(非斜体、非粗体等)。 |
7 | UseTypoMetrics:如果设置为 1,应用程序应该使用 OS/2 表中的 sTypoAscender 和 sTypoDescender。 |
8 | WWS:如果设置为 1,则表明字体支持“宽度、权重和样式”(Weight, Width, Slope)的命名方案。 |
9 | Oblique:如果设置为 1,则表明字体是倾斜体(与 Italic 区别在于更机械化的倾斜)。 |
10–15 | 保留位:未使用,应该设置为0。 |
usFirstCharIndex、usLastCharIndex
这两个字段描述了字体的 编码范围,即字体所支持字符的最小和最大 Unicode 值。
应用程序可以通过读取这两个字段快速确定字体是否支持某个字符,提高文本渲染引擎的性能,避免检查整个cmap表。
sTypoAscender、sTypoDescender、sTypoLineGap
这三个字段用于定义字体排版中基线到各种垂直参考点距离的关键参数,它们共同决定了行间距和排版布局的基准。
-
sTypoAscender
表示从 基线(baseline) 到字体设计中字符可达的最高位置的垂直距离。
通常基于字体的设计意图,取决于字体设计者设定的字母上升部分的最高点(如拉丁字母中的 “b” 或 “d” 的顶部)。 -
sTypoDescender
表示从 基线(baseline) 到字体设计中字符可达的最低位置的垂直距离(为负值)。
通常指字母下降部分的最低点(如拉丁字母中的 “p” 或 “q” 的底部)。 -
sTypoLineGap
定义了在 sTypoAscender 和 sTypoDescender 所包含的范围之外的额外空间(通常是正值)。
用于为行间留出额外的间距(leading),防止字符在多行排版时相互重叠。
-
总行高公式:
Line Height=(sTypoAscender−sTypoDescender)+sTypoLineGap
这些值用于确定排版系统中每一行文本的高度和行距。 -
在不同操作系统和排版引擎中,sTypoAscender、sTypoDescender 和 sTypoLineGap 是推荐的基准值,用于替代平台特定的字段(如 macOS 的 hhea 表,Windows 的 winAscent 和 winDescent)。
-
与 winAscent 和 winDescent 的区别:
winAscent 和 winDescent 定义了字符渲染的极限范围(即字符可能出现在屏幕上的所有点)。
sTypoAscender 和 sTypoDescender 表达设计推荐的排版范围,通常不考虑装饰性超出(如重音符号)。 -
与 hhea.Ascender 和 hhea.Descender 的区别:
hhea.Ascender 和 hhea.Descender 为 macOS 平台定义的字段,与 sTypoAscender 和 sTypoDescender 类似,但优先级和使用场景不同。
usWinAscent、usWinDescent
这两个字段定义了 Windows 平台 上字体在垂直方向上的 最大显示范围,用于字符渲染的裁剪和基线位置的计算。
-
usWinAscent
表示从基线(baseline)到字体设计中字符可达的 最高点 的距离(正值)。
通常包括字符顶部的重音符号或任何装饰元素的最高位置。 -
usWinDescent
表示从基线(baseline)到字体设计中字符可达的 最低点 的距离(正值)。
通常包括字符底部的装饰性符号或其他附加部分的最低位置。
- usWinAscent 和 usWinDescent 的值通常大于 sTypoAscender 和 sTypoDescender,以包含更多的装饰性或外延字符。
ulCodePageRange1、ulCodePageRange2
这两个字段定义了字体支持的 Windows 代码页(Code Pages)。代码页是一种字符编码方案,用于映射特定语言或区域的字符集。
-
ulCodePageRange1
表示支持的代码页范围的 低位部分(Bits 0 – 31)。
每个位(bit)表示一个特定的代码页。 -
ulCodePageRange2
表示支持的代码页范围的 高位部分(Bits 32 – 63)。
每个位(bit)表示一个扩展的代码页。
sxHeight、sCapHeight
-
sxHeight(x-height)
代表字体中的 x-height,即小写字母 x 的高度,通常用于描述字体中所有小写字母(如 x, e, a, c 等)的基本高度。x-height 是衡量字体可读性和字形比例的重要标准。
x-height 决定了小写字母的显示效果。在不同的字体中,x-height 对字体的可读性和美学有着显著影响。较大的 x-height 会使得字体看起来更加“开阔”和“现代”,而较小的 x-height 则可能让字体显得更加紧凑和传统。
字体大小调节:通过 sxHeight 字段,应用程序或排版工具可以了解该字体的小写字母的标准高度,以便根据需求调整字体的显示效果。 -
sCapHeight(Cap height)
代表字体中的 cap height,即大写字母(如 A, H, T, L 等)的顶部高度。Cap height 是字体设计中的一个重要参数,它决定了大写字母的高度对比小写字母的整体视觉效果。
Cap height 决定了大写字母的高度,影响到字体的整体视觉比例。字体设计师通常会根据大写字母的高度来设定整套字体的比例,尤其是在对大写字母进行强调或排版时。
排版设计:sCapHeight 在调整行高、字母间距、文本行的对齐和样式等方面起着关键作用。
usDefaultChar
usDefaultChar定义了一个默认字符的索引。当某些字符无法在字体中找到时,usDefaultChar 指向字体中的一个 备用字符,该字符通常用来代替无法找到的字符(例如,缺少的字形或者 Unicode 范围外的字符)。
usBreakChar
usBreakChar定义了一个特殊的字符索引,用于标识在文本排版过程中作为 换行符 或 断行符 使用的字符。
usMaxContext
usMaxContext用于指示 最大上下文 字符数。这个字段通常与字体的 字形替代(如字形合并、变形或变体)功能相关。它告诉排版引擎,在执行字符替换、连字或其他字形变换时,最多可以考虑多少个字符的上下文。
usMaxContext 的值指定了字体可以考虑的字符上下文的最大范围。当文本引擎进行字形替换(例如,执行连字、替代或其他复杂排版功能)时,它会查看当前字符前后一定数量的字符。usMaxContext 就是限定了这种上下文的最大长度。例如,如果 usMaxContext 设置为 3,则在考虑字符替换时,排版引擎会最多查看当前字符的前后 3 个字符。
usLowerOpticalPointSize、usUpperOpticalPointSize
usLowerOpticalPointSize、usUpperOpticalPointSize用于定义字体在不同大小下的优化行为,特别是与 光学尺寸(Optical Size)相关的优化。
在字体设计中,光学尺寸 是指为特定点大小的文字优化设计的字体版本。例如,较大的字体大小可能会使用不同的笔画宽度、间距和其他设计细节,以确保在显示时看起来清晰和易于阅读。不同的字体可能会在不同的尺寸范围内进行优化,以适应打印或屏幕显示等不同的使用场景。
-
usLowerOpticalPointSize:
该字段定义了字体在 下限光学点大小 时应用优化的起始点。即,当字体大小低于该值时,字体的设计会在视觉上进行优化,例如增大字母间距、调整线条粗细等,以适应较小的尺寸。 -
usUpperOpticalPointSize:
该字段定义了字体在 上限光学点大小 时应用优化的结束点。当字体大小大于该值时,字体设计将采用适合较大尺寸的优化,通常包括调整笔画宽度和其它设计细节,以确保字体在较大尺寸下仍然清晰可读。
post表
该表包含了在 PostScript 打印机上使用 OpenType™ 字体所需的附加信息。这些信息包括在 Type 1 字体的 FontInfo 字典中找到的某些数据,以及所有字形的 PostScript 名称。
版本 1.0、2.0 和 2.5 的 ‘post’ 表仅在使用 TrueType 或 CFF 版本 2 字形轮廓数据的字体中使用。使用 TrueType 或 CFF 版本 2 数据的字体也可以使用版本 3.0 的 ‘post’ 表。使用 CFF 版本 1 字形轮廓数据的 OpenType 字体只能使用版本 3.0 的 ‘post’ 表。
类型 | 名称 | 描述 |
---|---|---|
Version16Dot16 | version 0x00010000 for version 1.0,0x00020000 for version 2.0,0x00025000 for version 2.5 (deprecated),0x00030000 for version 3.0 | |
Fixed | italicAngle | 斜体角度是指从垂直方向开始,逆时针计算的角度。对于直立文本,斜体角度为零;对于向右倾斜(前倾)的文本,斜体角度为负值。 |
FWORD | underlinePosition | 建议的下划线顶部的 y 坐标。 |
FWORD | underlineThickness | 建议的下划线粗细值。通常,下划线的粗细应与下划线字符(U+005F LOW LINE)的粗细相匹配,并且应与在 OS/2 表中指定的删除线粗细相匹配。 |
uint32 | isFixedPitch | 如果字体是等宽字体,则设置为非零值;如果字体是比例间距字体,则设置为 0。 |
uint32 | minMemType42 | 下载 OpenType 字体时的最小内存使用量。 |
uint32 | maxMemType42 | 下载 OpenType 字体时的最大内存使用量。 |
uint32 | minMemType1 | 当 OpenType 字体以 Type 1 字体格式下载时的最小内存使用量。 |
uint32 | maxMemType1 | 当 OpenType 字体以 Type 1 字体格式下载时的最大内存使用量。 |
注:文章包含AI辅助生成内容,如无意中使用了您的数据,请联系笔者进行处理。
小广告
笔者开源了一款字体设计工具,可以设计字体轮廓并生成otf字体文件,欢迎来玩。源码地址:
github: https://github.com/HiToysMaker/fontplayer
gitee: https://gitee.com/toysmaker/fontplayer