使用 fontforge 和 fonttools 创建轻量级后备字体

Posted

技术标签:

【中文标题】使用 fontforge 和 fonttools 创建轻量级后备字体【英文标题】:Creating a lightweight fallback font with fontforge and fonttools 【发布时间】:2017-04-25 06:14:20 【问题描述】:

对于 web 应用程序,如果我的 web 字体不包含字符,我需要一种方法来防止浏览器回退到另一种字体。似乎这样做的唯一方法是向字体堆栈添加另一种字体,其中包括“所有”可能的字符1。

已经存在fallbackfonts,但它们更多的是调试助手,因为它们将代码点显示为数字,因此它们非常重(> 2MB)。

我的用例的后备字体应该只显示类似于框的东西来表示丢失的字符。

我的想法是生成一种只有一个字形的简单字体,并应用一个功能文件,该文件将用这个字形替换所有字形。

我的 fontforge 脚本:

import fontforge
import fontTools.feaLib.builder as feaLibBuilder
from fontTools.ttLib import TTFont

font_name = 'maeh.ttf'
font = fontforge.font()
glyph = font.createChar(33, "theone")
pen = glyph.glyphpen()
pen.moveTo((100,100))
pen.lineTo((100,500))
pen.lineTo((500,500))
pen.lineTo((500,100))
pen.closePath()

for i in range(34, 99):
    glyph = font.createChar(i)
    glyph.width=10

font.cidConvertTo('Adobe', 'Identity', 0)  # doesn't make a difference

font.generate(font_name)

font = TTFont(font_name)
feaLibBuilder.addOpenTypeFeatures(font, 'fallback.fea')
font.save("fea_"+font_name)

我的功能文件:

languagesystem DFLT dflt;

@all=[\00035-\00039];
#@all=[A-Z]   this works 

feature liga 
    sub @all by theone;
 liga;

但上面的结果是

KeyError: ('cid00037', 'SingleSubst[0]', 'Lookup[0]', 'LookupList')

cid00037 的号码不断变化。

如果我使用 Feature 文件中注释掉的 A-Z 就可以了,所以这种方法似乎并没有完全错误。

如果我以 CID 表示法指定范围,为什么 fonttools 无法找到字形? 是否有另一种方法可以为包含所有字形的 OpenType 功能文件创建一个类?

【问题讨论】:

在我们继续之前:为什么需要防止字体回退?因为这就是网站应该做的事情,所以你为什么要尝试对抗 CSS 的工作方式,而不是为你的代码编写一个离线验证器来告诉你选择的字体是否有间隙? @Mike'Pomax'Kamermans 我需要这个用于测试字体的网站。如果字形不是字体的一部分,则应该很明显它丢失了。 那么...为什么不exploit字体回退,回退到Adobe's blank font或Adobe's notdef font?这实际上就是它们的用途(排版验证)。也就是说,测试字形存在是您可以合理地 执行任何类型的前端的事情:您只需通过整形器运行您的页面代码,看看它是否会出现“您喂给我字符串 X而且我应该使用的这种字体没有字形索引/索引”,无需在客户端中执行此操作。但如果必须:使用空格。 【参考方案1】:

在解决上述问题时,有人提示我使用 Adobe NotDef 字体,这正是我所寻找的。由于某种原因,我无法使用 fontforge 将 Adob​​e NotDef 的 .otf 转换为 woff 或 woff2。此外,所有用于创建网络字体文件(如 fontsquirrel)的在线工具都失败了。为了创建 woff 文件,我使用了 woff-tools 包中的 sfnt2woff。对于 woff2 文件,我使用了https://github.com/google/woff2。

【讨论】:

Font Forge 的哪个版本? Adobe blank 和 Adob​​e notdef 都依赖于新的 CMAP 表,因此如果您仍在使用旧版本,那么它可能根本不了解应该如何处理该 CMAP 数据。 FontForge 自 2010 年以来一直支持 WOFF,因此这应该不是问题,但仅在 2018 年 6 月 15 日才添加了 WOFF2 支持。

以上是关于使用 fontforge 和 fonttools 创建轻量级后备字体的主要内容,如果未能解决你的问题,请参考以下文章

fontforge - 合并字体以添加字形的脚本

fontforge字体开源项目

FontForge 汉化教程

利用fontforge制作自己的字体

Ubuntu gnome安装Monaco字体,FontForge module is probably not installed

用于将 TTF/OTF 字体转换为 SVG 的命令行工具