打开你的 Figma,只要在文本框里打字,那些字符就会默认用 “Inter” 字体。

Inter 是最近特别火的一款拉丁字体,自称是“21 世纪的标准”,原文说:这可能是全世界用得最多的字体之一,电脑界面、广告海报、机场标识、NASA 仪器、医疗设备……到处都在用它。

https://rsms.me/inter/

我做的不少海报作品,基本都直接用了 Inter 这款字体,也是我自己的习惯,懒得反复折腾换字体,最多也就是在它的基础上做一些粗细、大小或排版上的变化。

这次我想聊聊字体本身,不过重点会放在基于 Inter 的一个字体标准,OpenType 上。这篇文章适合对字体感兴趣的朋友。

不需要事先具备专业背景,我会尽量讲得直白易懂。除了 OpenType 本身,我也会适时扯远一点,谈到像 InDesign、Figma 这类软件的实际应用,以及它们与 Unicode 之间的关联。

什么是字体文件?

我们可以从一个比较抽象的概念讲起。

像 Inter-Regular.otf 这样的字体文件,它们本质上就是一串 0 和 1 的二进制数据和一张 image.jpg 图片没什么不同。但不一样的是,字体往往需要在不同软件之间通用,所以它们一般会直接安装在操作系统层级。

也就是说,不管是 Word、InDesign 还是纯文本编辑器,只要你输入一个字符,或者说,一个字符编码,系统就会根据这个编码,在已安装的字体中找到对应的字形,然后显示出来。而这,其实就是数字字体最核心的作用。

比如,当我们通过键盘输入字符时,计算机实际接收的只是一串编码(此时它并不“知道”这个字符长什么样)。如果我们以 Unicode 作为编码标准,那么接收到 Unicode 字符串的应用程序,比如文本编辑器或浏览器,就会去调用已安装的字体文件,从而在屏幕上显示出对应的字形。

这个过程其实发生在几乎所有涉及文字显示的计算机场景中,并不局限于某个软件。可以说,字体文件本质上就是一个“转换表”,它在字符编码和字符形状之间建立起映射关系。

不过,当我们具体谈到 OpenType 这类现代字体格式时,事情会更有意思:这种对应关系并不总是一对一的。也就是说,同一个字符编码可能对应多种不同的字形变体,而同一个字形也有可能由多个不同的字符编码触发呈现。

字符和字形

理解 OpenType 的核心,是要分清什么是字符(character),即字符在编码中的抽象存在,什么是字形(glyph)即字符被实际渲染出来的视觉形态。

正如微软文档所阐述的:“字符是数据中具有数字表示的抽象实体,而字形则是字符被呈现出来的具体形式。”例如,大写字母 A 作为一个字符,在字体 Times New Roman Bold 中就以一个加粗、带衬线的具体字形“A”显示在屏幕上。

https://learn.microsoft.com/en-us/typography/opentype/spec/ttochap1

当某款字体为同一个字符(即同一字符编码)提供了多个不同的视觉变体时,“字形”这一概念就显得尤为重要,这也表明,Unicode 编码与字形之间并不存在严格的一对一关系。

将字符代码映射到字形

OpenType

现在,我们正式进入今天的主题。OpenType 字体格式是当前最主流的字体格式之一,它最大的优势在于遵循了一套通用的标准规则,使得制作出的字体能够稳定兼容于各类应用程序和设备环境。

除了出色的兼容性之外,OpenType 还具备强大的排版功能。这主要得益于其内部采用的 GPOS(Glyph Positioning,字形定位) 和 GSUB(Glyph Substitution,字形替换) 等技术表,借助它们,我们可以为字体注入丰富的排版行为,比如连字、替代样式、位置调整等复杂特性。

理解 OpenType 的第一步,是要先弄清楚它的基础机制:字体文件是如何建立起字符编码与字形之间的映射关系的。这也是我们接下来要探讨的重点。

cmap

cmap 表是 OpenType 字体中的核心结构之一,它的作用是将字符的 Unicode 编码(代码点)映射到对应的字形编号上,这个编号也叫做 GID(Glyph ID)。

你可以把 GID 理解成字体中每个字形唯一的“身份证号”,它是一个整数值,按顺序分配给字体中包含的每一个字形。不过要注意的是,并不是所有字形都有对应的字符编码,有些特殊字形(比如装饰符号或连字组合)可能并没有直接的 Unicode 对应,它们只能通过替换规则被调用。

cmap 表本身并不存储任何字形轮廓或图像数据,它更像是一个“路由表”或者“索引目录”:当你输入一个字符,系统就会查询这个表,找到对应的 GID,然后再去字体文件的其它部分(比如 glyf 或 CFF 表)提取真正的字形数据进行渲染。

简单来说:cmap 负责从“字符”找“字形编号”,而不负责存储字形本身。

CFF

CFF 负责存储与 GID(字形编号)对应的实际字形数据。

字形本质上是由数学曲线描述的轮廓路径,如果你使用过 Illustrator 等矢量设计工具,应该对这种路径并不陌生,更专业地讲,这些轮廓通常使用三次贝塞尔曲线构建,操作时常见的“锚点”就是用来调整曲线形态的。

不过,OpenType 还支持另一种存储字形的方式:glyf 。它基于二次贝塞尔曲线来描述轮廓。与三次曲线相比,二次曲线的锚点更少,数学表达也更简单,因此灵活性较低。从理论上讲,由于曲线阶数的差异,无法将三次贝塞尔曲线完美转换为二次曲线,只能用有限精度的方式近似拟合。

这种技术差异其实源于一段字体格式的“路线之争”:Adobe 推出的 PostScript 字体使用三次贝塞尔曲线,而 Apple 的 TrueType 标准则采用二次曲线。两者各有优劣,但 OpenType 的出现,由 Microsoft 和 Adobe 联合推动,最终统一了这两种格式。

OpenType 既可以封装 PostScript 轮廓(使用 CFF 表,文件扩展名常为 .otf),也可以包含 TrueType (使用 glyf 表,扩展名通常为 .ttf),从而实现了对两大字体流派的兼容。

OpenType 为排版增添色彩

到目前为止,我们已经了解了字符编码与字形数据之间是如何建立对应关系的。

在此基础上,如果还掌握了每个字形在水平方向上的宽度信息,那么从理论上讲,你已经可以初步做出一个可用的字体了,尽管实际制作中还会涉及更多辅助表格的配合。

不过,在实际使用 Inter 这类字体时,你可能会遇到一些情况:某些字形无法仅靠基本字符集直接显示,或者你希望在某些场景下主动用一个字形替换另一个字形。

例如下面这些典型情形:

您看这几个例子:左边两个案例的行为,如果脱离前后文,是根本不可能实现的。

比如左上角,虽然“t”这个字符出现了两次,“f”出现了三次,但实际显示出来的字形却各不相同,再看左下角,两对括号和冒号的位置也都根据上下文做了细微调整。

而右边两种情况则更明显:要么是在特定条件下换用了另一个完全不同的字形,要么是把多个字符合并起来,替换成了一个专门的连字字形。

所有这些现象背后,有一个共同点:Unicode 编码序列完全没有改变,改变的是实际显示出来的字形以及它们的排版位置。

那么,是 OpenType 字体中的什么机制在背后支持这种灵活又智能的行为呢?

hmtx和GPOS

我们来聊聊 OpenType 中的两个重要表格,hmtx 和 GPOS。它们虽然都和字形的位置有关,但分工完全不同,承担着不同层面的排版控制。

hmtx(水平度量表)负责记录每个字形的基础水平宽度,也就是“前进宽度”。这个宽度并不只是字形绘制宽度本身,还包含了为视觉平衡而预留的左右侧边距。hmtx 表中的每一项都与一个具体的字形 GID 绑定,只要文字需要显示,这个表就会被调用。

GPOS(字形定位表)则用于处理更复杂、更精细的排版场景,比如连字位置调整、字符间的相对距离微调,或是基于上下文的特殊布局处理。可以说,hmtx 定义了字形“占多宽”,而 GPOS 则在此基础上决定它们“应如何摆放”。

你可能会注意到,中西方字体在宽度设计上有一个很有趣的区别。

西文字体(比如英文)中,每个字母的宽度通常是不同的,比如字母 "m" 明显比 "i" 要宽,这样的变动宽度让西文排版显得自然而流畅。

而中文字体则大多采用统一的字宽,也就是几乎所有汉字在同一个字体中都被设置为同样的水平宽度。这样做不是为了方便,而是为了确保排版的基础,稳定的文字排列。

正因为每个字占位一致,你现在所阅读的每一行文字,纵向才能如此整齐对齐,整段内容显得便于阅读。

GPOS(字形定位表) 让字体能够更灵活、更精细地控制字符的排版位置。在像 Inter 这样的现代字体中,它主要发挥两大作用:一是字距调整,二是特殊符号的精准添加。

如果“Ta”后面跟着符号“ ”,则字距也会调整。

字距调整指的是根据不同字符组合动态微调它们之间的间距。

如果只依赖 hmtx 表所提供的固定字宽和边距,某些字母组合(比如 "VA" 或 "Ty")可能会显得间距过大或过紧,看起来不太协调。而借助 GPOS,字体可以针对这些特定组合单独调整距离,从而实现更均衡、更舒适的视觉排版效果。

要注意的是字距调整功能是否生效,取决于你所使用的软件设置。例如在设计类应用(如 Figma 或 InDesign)中,可自行开启或关闭字距调整,而在大多数操作系统或常见文本环境中(例如浏览器或系统界面),西文字体的字距调整通常是默认开启的。

Figma( 字体设置 > 详情)

GSUB

介绍的最后一个,也是最有趣的一个表,是 GSUB(字形替换表)。顾名思义,它的核心功能就是替换字形:在保持文本底层 Unicode 编码完全不变的前提下,改变屏幕上实际显示的字形(也就是改变其 GID)。

理解 GSUB 可以从两个维度进行分类(请注意,这些分类名称并非官方术语,但有助于理解):

按替换机制分类

一对一替换:将一个字形替换为另一个字形。

例如:竖排文本中,括号方向会自动变化;或根据设计偏好,将普通零 0 替换为带斜线的零 Ø。

多对一替换:将多个字形组合替换为一个独立的字形。

例如:将连续的 f 和 i 替换为美观的连字 fi。

一对多替换:将一个字形分解替换为多个字形。

例如:将某个连字断开,恢复成原始的两个独立字符(较为少见)。

上下文替换:根据字符的上下文环境,智能地替换其中一部分字形。

例如:在“冒号+数字”的组合中(如 :1),自动将冒号替换为垂直居中的版本,以适应数字排版。

按功能分类

它指的是我们在软件中看到的那些可以一键开启或关闭的排版功能组。

例如,“所有连字”可以作为一个功能组,而“上标数字”或“风格替代字”则可以作为另一个独立的功能组。设计师会将这些属于同一视觉风格或功能的替换规则打包在一起,并赋予它们一个清晰的标签(如 liga 代表标准连字,sups 代表上标)。

为了实现这种灵活的开关控制,字体文件内部通过 功能 和查找子表来协同工作:

功能表:定义了一系列功能,每个功能都有一个四个字母的标签(如 liga, sups),这就是你在软件下拉菜单中看到的功能名称的来源。

查找表:描述了具体的替换规则。一个功能(如“所有连字”)可以调用一个或多个来完成其替换任务。

所以,当你勾选或取消勾选软件中的“连字”选项时,实质上是在控制 GSUB 中对应的 Lookup 规则是否生效。 值得一提的是,我们之前介绍的 GPOS 表也采用了完全相同的结构来管理其定位功能。

以下是 Inter 的一些特点

最后

感谢您读到这里。

Inter 不仅设计优秀、审美现代,它的特别之处在于,它是一款免费开源字体,却完整融入了丰富的 OpenType 高级排版功能。我只是众多用户之一,但我由衷欣慰地看到,它正逐步超越许多经典字体,真正成长为它所自称的——“21 世纪的标准”。

2
0