创建可变字体

  • by Rainer Erich Scheichelbauer
  • Tutorial

欢迎来到 Glyphs 的可变字体世界!本教程包含近期 Glyphs 版本中的工作流程。我们建议安装最新版的软件,请前往 “Glyphs > 偏好设置 > 更新”,勾选对话框中的两个复选框,然后点击“现在检查”按钮。注意,尽管 Glyphs 可以导出能够正常工作的可变字体,该功能仍然处于测试阶段。在本教程中,我会指出哪里是你仍要注意的地方。

可变字体(Variable Font)是什么?

如果你还没有读过 John Hudson 精彩的介绍文章,立刻停下手头的工作去读一下,真的。

第一步:定义轴

在 “文件 > 字体信息 > 字体” 中,添加名为 “Axes” 的自定义参数。双击其 “值” 区域,在弹出的对话框中点击齿轮按钮来添加或删除轴。在预置的轴(Weight、Width、Italic、Slant、Optical Size)中任选其一,或自定义一个轴。

专业提示:如果你定义了自己的 “私有” 轴,你还需要选择一个四个字母的标签。为了避免与标准更新可能发生的冲突,建议为私有标签使用全大写,例如,微笑(Smile)轴使用 SMIL,旋转(Rotation)轴使用 ROTN。这是因为全大写的标签是官方为私有使用所保留的,预置的轴则均为小写。

你可以随时重新定义轴,在当前版本中,你可以定义多达 6 个轴。本例中,我将专注于 “Weight” 轴上,其标签为 wght

你可以在对话框左下角的齿轮菜单中管理这些轴。

第二步:建立母版

在 “文件 > 字体信息 > 母版” 中,通过窗口左下角的 “+” 按钮添加母版,就像你在多母版项目中所做的一样。本例中,我们添加两个母版,“Light” 和 “Bold”。

为每个母版选择如下设置:

  1. 确保你为每个母版选择了合适的母版名称。本例中,“Light” 和 “Bold” 是不错的选择。母版名称不会导出到最终的字体文件中,但当你在 Glyphs 中工作的时候,可以通过它来找清方向。
  2. 最重要的是,为每个母版设置轴坐标。本例中,即是设置 “Weight” 值,例如,Light 母版为 50,Bold 母版为 200。许多设计师喜欢使用字干的粗度作为 Weight 轴的值,但是你可以输入任何喜欢的值,只要这些值足够不同,以便 Glyphs 可以计算插值子样。本例中,我们可以在 50 到 200 之间计算子样,例如 75、120、182 等。
  3. 也可以选择在窗口右上角的弹出菜单中挑选一个母版图标。你可以从表示各种字重和宽度组合的小写 n 中进行选择。你还可以在底部输入一个字符形名称,Glyphs 将使用相应字符形的图像作为母版图标。同样,这只用于你来找清方向,所以选择自己能够看懂的图标即可。

当然了,如果稍稍向下卷动窗口,你会发现更多设置:对齐区域,字干,自定义参数。你应当将它们设置为适合你设计的数值,只要确保这些数值相互兼容。这意味着如果在一个母版中输入了值,其他母版中也需添加相应的值。例如,如果你在一个母版中设置了标准字干,那么其他母版中也应该有同样数量和顺序的字干数值。

关于轴坐标测试的备注:技术上,每个轴都有一个具有特定语义的数值定义。例如,“Weight” 必须和 usWeightClass 兼容,以便在 CSS 中允许保持样式一致的情况下切换不同的字体。 因此,400 必须是 Regular,700 必须是 Bold,等等。“Width” 类必须以 100 作为常规宽度的坐标,而其他母版的数值需要是和常规宽度的百分比,通常 75 作为 Condensed,125 作为 Extended。

对于字重轴而言,要实现这个有一点麻烦。你可能需要使用技术文档中定义的范围而非实际的字干粗细,或者添加 “Axis Location” 参数(见下文)来重新映射母版。这两种选择都有这样的缺点:你母版间预设的字重分布不太可能像 usWeightClass 中所设定的那样平均。换句话说,如果你的 Regular 母版在 400 处、Extrabold 母版在 800 处,你不太可能恰好让 Medium 子样位于 500 处、Semibold 子样位于 600 处、Bold 子样位于 700 处,而更有可能中奖挂彩。

理论上讲,你可以通过将子样作为母版插入来规避这一问题。前往 “文件 > 字体信息 > 子样”,逐个选择子样,并从窗口左下角的 “+” 按钮处选择 “将子样作为母版”;然后切换到同一窗口中的 “母版” 选项卡,重新将其 “字重” 坐标设置为 usWeightClass 的数值。回到 “子样” 选项卡删除既有的子样,并通过 “+” 菜单中的 “为每个母版添加子样” 选项重新添加子样。

就目前而言,我们建议仅针对正式发布的字体进行此项操作。如果你只是在进行自己的实验,或是为了特定的定制项目,则无需对此太过在意。

第三步:绘制兼容的字符形

为了使教程简短易懂,本文中我们将专注于大写字母 A。我首先绘制一个字干粗度大约 50 单位的、Light 字重的 A,以及字干粗度 200 单位的 Bold 字重:

最重要的是,确保所有的路径、部件和锚点兼容,就像你在多模板设置中所做的一样

专业提示:你可以通过 “视图 > 显示母版兼容性”(Ctrl-Opt-Cmd-N)来检查兼容性,但是如果你还没有定义任何插值子样(见第四步),Glyphs 会允许轮廓的不兼容。你可以在 “文件 > 字体信息 > 字体” 中添加名为 “Enforce Compatibility Check” 的自定义参数,这样即使两个母版间没有子样,Glyphs 也会将它们用线条连起来:

第四步:添加预设子样

尽管字体是可变的,我们已经获得了无尽数量的子样,但还是可以在设计空间中选择一些位点来作为字体子菜单中的子样。在 “文件 > 字体信息 > 字体子样” 中,添加随意数量的子样作为预设即可。只需通过左下角的 “+” 按钮添加新子样,或者按住 Option 键在左侧边栏中拖动既有子样来直接复制它们。

你需要在每个子样中进行以下操作:

  1. 设置合适的样式名称:本例中为 “Light”、“Regular”、“Medium”、“Semibold”、“Bold”、“Extrabold”。
  2. 从下拉菜单中选择一个字宽和字重类。重要的是,菜单旁边的数字顺序正确,因为这是 Adobe 存储在字体菜单中的顺序。本例中,所有字体的字宽相同(均为 Medium/normal,值为 5),但是字重类型逐步上升(从 Light 到 Extrabold:300、400、500、600、700、800)。对于给定数值之间的子样,你也可以通过添加 “weightClass” 和 “widthClass” 参数为其指定中间数值。阅读字体命名教程来了解更多。
  3. 选择一个样式链接。对于直立的字体,留空即可,唯独 Bold 样式需设置为 “Regular” 的 “Bold”。每个意大利体/斜体需设置为相应直立版本的 “Italic”,例如,Semibold Italic 是 “Semibold” 的 “Italic”。只是要注意:Italic 子样是 “Regular” 的 “Italic”,Bold Italic 是 “Regular” 的 “Bold” 和 “Italic”。 阅读字体命名教程来了解更多。
  4. 为每个轴选择合适的设计空间坐标。阅读多母版(三) 教程了解更多关于子样分布的内容。
  5. 最后我不想说破,但是很多自定义参数在 OpenType 可变字体中不会生效,尤其是那些后期参数,比如滤镜。如果你的字样中有这些参数,那么它们将被软件忽略。这是为什么?因为它们会破坏轮廓的兼容性。

第五步:导出并测试可变字体

选择 “文件 > 导出” 并点击 “Variable Fonts” 选项卡:

如果你有最新版的 Adobe Illustrator 或 Adobe Photoshop CC 2108,你可以导出到 Adobe 字体文件夹,在 “字符” 面板中选择字体,然后打开小小滑块的下拉菜单来测试 “Weight” 轴:

或者,你也可以将字体文件拖拽到以下这些神奇的网页之一来测试字体。我最喜欢的包括 Roel Niesken 优秀的 Wakamai Fondue、ABC Dinamo 的 Font Gauntlet(该网页还可以让你的可变字体以动画展示),当然还有 Laurence Penney 的 Axis Praxis 页面:

或者,你可以安装 mekkablue 脚本并运行 “Test > Variable Font Test HTML”,它能够在最后一次 OT 可变字体旁边创建一个 HTML 文件,并在访达中打开其所在的文件夹。所以,你需要做的只是把它拖拽到浏览器中:

提示:截至本文写作时,最佳的备选浏览器是当前版本的 Chrome 或 Safari,如果你在使用 macOS High Sierra 或更新版本,或者 iOS 11 或更新版本。老版本操作系统上的 Safari 不可用。Firefox 和 Edge 应该也可以,但到确保它们是最新版本的浏览器。

如果你确实想要使用一款与众不同的、或者老款的浏览器,或者在旧版操作系统上测试,请看一下 Axis Praxis 博客:在这里,Laurence Penney 解释了在哪里下载、以及如何设置各种流行浏览器的预览版本。越来越多的浏览器已经添加了对可变字体的支持,或者已经支持了,但你需要在某处打开一些设置。Laurence 在他的文章中有全部的讲解。

避免 Bug

Adobe 对 OT 可变字体的实现还有不少 bug。所以,如果字体在 Illustrator 或 Photoshop 中不能正确插值,那可能不是你字体的错。具体症状可能各有不同,但可能包括:字符静止不动,不随滑块的调节而发生改变;或者随着滑块的移动出现丑陋的瑕疵,比如像这样:

如果发生了这种情况,可以尝试将轮廓设置为不同的起始节点。我们发现有时可以通过这个操作来绕开 Illustrator 的渲染 bug。不论在何种情况下,如果你发现浏览器中不出现同样的瑕疵,那就不是字体的问题。最好把字体文件发送给 Adobe 支持,并附上带有简单测试案例的 AI 文件。

另一个恼人的 bug 处于 Apple 的 CoreText 渲染器深处。在左侧边距变动时,部件的偏移会被错误计算。看一下 a 的正确变化,以及 ä 比它所应该的发生了更多偏移:

这个问题影响所有使用 CoreText 渲染的环境,包括 Mac 上几乎所有的浏览器。在这种情况下,你所能做的最好的操作是,确保导出时所有部件都被释放。最佳做法为:在 “文件 > 字体信息 > 字体 > 自定义参数” 中添加一条 Decompose Components in Variable Font 参数。不用说,所得到的 TTF 文件将会更大,而且不适合网页使用,直到 Apple 修复这个问题为止。

我们已经将此 bug 报告给了 Apple,但是如果你手上有更好的案例,请告知 Apple

更新:Apple 修复了这一问题。确保你已安装了 macOS 10.13 的最新小版本更新,或新的大版本 macOS。

Apple 渲染中的另一个错误:在 Safari 中,“视觉尺寸”(opsz)轴会被错误插值。在滑块的最小端(最左),显示为最大值的渲染结果。这仅发生在 Safari,不会出现在其他浏览器中。同样,请告知 Apple。

此外,由于可变字体会保留轮廓重叠,这会造成一个渲染问题。不算是 bug,但你的用户可能会遇到这样的效果。如果你个图形的边缘由两段(不完全)重叠的路径线段绘制而成,抗锯齿操作会使这段边缘显得深一些,不像只由一段路径绘成的边缘那样“整洁”:

唯一的解决方案是,重新组织轮廓,使得图形的外侧边缘保持 “整洁”,即,任何位置都只由一段路径构成。例如这样:

绝大多数情况下,你可以通过去除重叠并展开角或重新连接节点来解决这一问题。“展开角” 和 “重新连接节点” 这两个功能都位于右键上下文菜单中,取决于所选节点的个数:选中单个节点来展开角;选中两个角节点,重新连接。

如果你会经常用到这两个功能,你可以为它们设置键盘快捷键。为此,我们将这两个命令添加到了 “路径 > 其他” 菜单中。在 “系统偏好设置 > 键盘 > 快捷键 > 应用程序快捷键 > Glyphs” 中设置快捷键。

提示:mekkablue 脚本 “Paths > Rewire Fire” 可以帮你找到需要重新连接的节点。它不能找到全部,但通常能找到大部分类似上述导致不光滑边缘的情况。你需要的是找到 “nodes on top of line segments”(顶端线段上的节点):

可选:添加虚拟轴

假设你需要一个仅在某些字符形中生效的轴。比如说横笔高度,只有 A、E、F、H 等字母中会用到,而 S、D、J、O 等字母以及数字、标点等非字母字符中则不需要。为整个字体绘制一个新的母版不太合适,是吧?相反,你应该仅为那些具有横笔的字符形添加额外的母版。嗯,对于这类情况,我们有一个功能称为虚拟母版

  1. 在 “文件 > 字体信息 > 字体” 中,为 “Axes” 参数添加一个新的轴。因为这不是一个标准的轴,所以名称随意。本例中,我建议命名为 “Crossbar Height”,四字标签为 “CRSB”:

  2. 在同一个窗口选项卡中,添加一个名为 “Virtual Masters” 的自定义参数,将其 “Weight” 轴赋值为 Light 母版中的轴坐标,本例中为 50,“Crossbar Height” 则设为最小值,比如 0:

  3. 在 “文件 > 字体信息 > 字体母版” 中,确保所有母版中的 “Crossbar Height” 轴坐标都不为 0,而是别的值比如 100,只要这个值在含义上合理即可。本例中,0 代表横笔可能出现的最低位置,100 代表最高位置。

现在虚拟母版已经创建,你可以为需要的字符形绘制横笔较低的版本了:

  1. 在编辑视图中打开字符形。
  2. 在 “图层” 面板中,点击 “拷贝” 按钮复制 “Light” 图层。
  3. 将图层副本重命名为 {50, 0},即通过逗号分隔的 Weight(本例中为 Light 的 50)和 Crossbar Height(本例中为横笔最低位置的 0)轴坐标,放在花括号当中。
  4. 现在,更改所绘制的字母,让它看上去像 “Crossbar Height” 为 0 时所该有的样子:

注:除非你想要做精细调整,否则不需要为 Bold 母版添加花括号图层。在可变字体中,两个轴上的变化量(节点的位移)共同作用,并且可以叠加,从而产生横笔较低的粗字重版本。

这就好了。现在你需要做的就是导出,然后在 Illustrator、Axis Praxis 或者可变字体测试的 HTML 脚本中测试字体。看,出现了另一个轴,用来让横笔向靠近基线的方向移动:

实际上,我们是在设计空间增加了第二个维度。如果你这样做了,那么建议将母版置于设计空间中平行四边形框的四角,或者在相对原始母版的水平或垂直方向上偏移则更好。本例中,Bold 母版向 Light 母版水平靠拢(仅第一个横坐标值改变),而横笔较低的母版仅在垂直方向上变化(第二个坐标值改变)。这样你可以让设计更加可控,因为只需通过改变所设置的母版来添加水平或垂直方向上的变化量,就可以到达设计空间中的任何一点上。

可选:可变字体原点

字体中存储的仅是一组轮廓。不支持 OpenType 可变字体的软件中,只能显示这些 “默认轮廓”。这个 “默认” 通常是第一个母版,不过你也可以选择另一个:前往 “文件 > 字体信息 > 字体” 并添加名为 “Variable Font Origin” 的自定义参数,其 “值” 处,选择一个母版,作为可变字体设计空间中的 “原点”:

没错,它必须是一个母版。如果你想将某个子样作为预设的原点,需要将子样添加为新的母版:在 “文件 > 字体信息 > 子样” 中,选择所要作为原点的子样,点击窗口左下角的 “+” 按钮,在弹出的菜单中选择 “将子样作为母版”。现在,在 “文件 > 字体信息 > 字体母版” 中就有了一个新的母版,你可以将它设置为你的 “Variable Font Origin”。

两件事情需要考虑:

  1. 默认外观:在可变字体背后的基本想法是,选择最常用的实例,通常是 Regular 作为默认。在多母版字体中,你会设计最极端的状况(也即最少被使用的子样)并插值出中间的所有情形;而可变字体则相反:它只存储最重要的轮廓,设计空间当中的位置、以及其他所有子样都是从基本轮廓衍生出来的。因此,对于桌面字体而言,选择 Regular 母版,或者在你的字体家族中用户所期望的 “默认字体外观” 作为原点。这样,即是其他内容都不可用,用户也能够使用这个字重下的版本。

  2. 文件大小: 选择中间的母版可能会让节点的增量数据变多,从而使文件增大。对于单一轴的设置而言,应该会至少增加一倍的增量数值。换句话说,对于网页字体而言,选择设计空间的极端位置处的母版作为默认会更好,因为你需要保持较少的文件体积和载入时间。

可选:重新定位轴

在 “文件 > 字体信息 > 母版” 中,你可以添加一个名为 “Axis Location” 的自定义参数。通过这个参数,你可以改变该母版在轴上的坐标。如果你需要如果你希望向用户展示的值与母版或子样中输入的插值有所不同,就可以使用这一参数。

本例中,你可能会觉得从 50 到 200 的滑块会让你字体的用户感到困惑,所以你希望所有的滑块都是从 0 到 100 的,如同百分比一样。比如一个百分比。这样,想两个母版添加 “Axis Location:Light 母版中 Weight 值为 0,Bold 母版中 Weight 值为100。

注:如果添加了 “Axis Location” 参数, 你实际上是改变了导出到可变字体中的轴。这意味着你也需要让 “Virtual Master” 参数(如果有的话)中受影响的轴坐标与其一致。但是,不要改动花括号和方括号图层中的数值,因为它们仍然遵循由原始插值所创建的设计空间。

限制

一些你可能已经熟悉的东西,在可变字体中的工作会和你所期待的不太一样。

  1. 前文中我简单地提到 “文件 > 字体信息 > 子样” 中的所有通过自定义参数进行的后期处理都会被忽略,因为它们很可能会破坏轮廓的兼容性和字符形组中的一致性。这包括滤镜以及重命名参数。
  2. 角部件能够工作,但其方式不同:在可变字体中,它们是在插值之前被应用在轮廓上的,而在传统多母版设置中,它们在插值之后才插入轮廓当中。
  3. 花括号和方括号图层都能够工作,但是在同一个字符形中不能同时应用这两者。在同一字体中,你可以在某些字符形中应用花括号图层,在另一些字符形中应用方括号图层,但不能在同一个字符形中同时应用花括号图层和方括号图层。这一点很抱歉,我们还在努力。

可能是必选:STAT 表

在包括可变字体在内的新字体中,名称信息被存储在 STAT 表中。STAT 是 “样式属性”(Style Attributes)的缩写,其中包括轴、子样的信息,以及所谓的 “显示字串” 和 “名称字串”:它们是轴上各部分的名称,比如字重轴可以分为 Light、Regular、Medium、Semibold、Bold;宽度轴可以分为 Condensed、Regular、Extended。

如果一个显示字串和其他显示字串组合,则会被认为是 “可省略的”。通常这种情况发生在默认样式名称上,比如 Regular、Normal 或类似名称。Semibold 字重和常规宽度结合时通常只叫做 Semibold 而非 Semibold Regular,常规字重的 Italic 版本只叫做 Italic 而非 Regular Italic。因此,显示名称 “Regular” 被认为是可省略的。

通常,Glyphs 会通过分析预设子样的名称,聪明地照料这些事项。不过,如果你发现 STAT 表的条目中,显示字串没有正确地在文件中存储,可以使用 “文件 > 字体信息 > 子样” 中的这两个参数来加以控制:

  • Style Name as STAT entry:将子样的样式名称作为轴范围的组合显示字串。“值” 处使用显示字串所应用的轴的四字母标签。仅当子样在某一个轴上是非常规而其他所有轴上均为常规时使用这种方式,因为常规属性具有可省略的名称,不会在样式名称(如 Semibold 或 Condensed)中出现。例:在 Light 子样中,使用该参数,值设为 “wght”,因为 Light 是字重(weight)轴上的值。

  • Elidable STAT Axis Value Name:为参数 “值” 中指定的轴声明其子样的样式名称为可省略的。“值” 处填写相应轴的四字母标签。通常,你需要在 Regular 样式中使用这一参数,并为名称为可省略显示字串的每个轴都添加一个。例:名为 Regular 的子样中有两个 “Elidable STAT Axis Value Name” 参数,其一值为 “wght”,另一个为 “wdth”。

专业提示:STAT 表正变得越发重要。在不久的将来,许多应用程序会首先需要它来加载一款字体。不要问我从哪里听到的消息,但让我告诉你如果你要为 Windows 开发(或更新)字体,你就需要为所有字体都设置好 STAT。提示提示:这也包括 Italic 轴(ital)来区分直立(值为 0)和斜体(值为 1)。

实用脚本

mekkablue 脚本集 (link includes readme with installation instructions)中,你可以找到一系列用于可变字体制作工作的实用脚本:

  1. Interpolation > Compound Variabler:在由部件组成的“复合字符形”中,复用其中部件的方括号和花括号图层设置。使得方括号和花括号图层在复合字符形中也起作用。

     

  2. Kerning > Zero Kerner:如果某个母版中没有设置字偶间距,但其他母版中设置了,那么会在没有设置的母版中添加值为 0 的字偶间距组。以便 OpenType 可变字体导出时可以为字偶间距插值。如果你发现某些母版中没有设置字偶间距,尤其是只在某些母版中设置了字偶间距的情况下,请使用这一脚本。

附加资源

想要深入了解更多关于可变字体的内容?我们为你准备了一些链接:


STAT 表示例字体:Plantago by Viktor Solt-Bittner and Schriftlabor。
多谢 Rob McKaughan 对本教程的评论和建议。

2018-03-16 更新:修正一些录入错误(感谢 Jeff Kellem)。
2018-06-22 更新:明确了实例值的措辞(感谢 Karl)。
2018-11-20 更新:更新了 “Variable Font Origin” 参数的名称。
2019-02-15 更新:添加了 Font Gauntlet 和 Wakamai Fondue 的链接。更新了测试脚本和浏览器支持信息。添加了“避免 bug”。
2019-03-13 更新:添加了“附加资源”。
2019-03-04 更新:修正录入错误,将导出窗口中的 “Variation Fonts” 改为 “Variable Fonts”(感谢 Nathalie Dumont)。
2019-03-20 更新:修正录入错误,将 “Add Instance as Maste” 改为 “Instance as Master”,并修正了 Nick Sherman 的 V-Fonts 链接(感谢 Nathalie Dumont)。
2019-10-23 更新:添加了 “实用脚本”。
2019-12-04 更新:添加了关于抗锯齿问题的一节。
2020-03-08 更新:添加了关于 Safari opsz 错误的一段,关于 Rewire Fire 脚本的提示,在资源中增加了 Samsa。

Chinese translation by Willie Liu (刘育黎) from 3type (三言).