FontTools 字体合并操作手册:3 种场景的命令行合并与边界
【免费下载链接】fonttoolsA library to manipulate font files from Python.项目地址: https://gitcode.com/gh_mirrors/fo/fonttools
本文讲解 FontTools 的 merge 模块做字体合并:fonttools merge命令行操作、Merger API 调用与边界条件。你拿到的是 3 个最小可运行操作、以及坑点的具体报错与处理方式。
场景速览
| 使用场景 | 前置条件 | 输出/效果 |
|---|---|---|
| 双语字体(拉丁+阿拉伯)合并 | 两字体 unitsPerEm 相同 | 单份 OTF,cmap 合并,重复字形去重 |
| 多语言字形冲突消歧 | 同一 Unicode 映射到不同字形,字体含 GSUB | 冲突字形改名parenleft.1,注入locl替换 |
| 批量合并字体列表 | 一行一个路径的文本文件 | --input-file批量输出,支持 # 注释 |
| 变量字体实例整合 | designspace 描述轴与实例 | varLib builder 出变量字体,可导出实例 |
机制速览
Lib/fontTools/merge/init.py 中的 Merger 类用 TTFont 加载各字体后,先由computeMegaGlyphOrder计算覆盖全部字体的超级字形顺序,再建统一 cmap 并记录“同码位不同字形”冲突;随后按表标签逐个调用对应表类的merge()聚合字段:hhea.ascent取 max、head.unitsPerEm要求严格相等;最后向 GSUB 注入locl查找表消解冲突,输出一个可save()的 TTFont。
分场景实战
命令行合并操作:合并同 em 值的两字体
merge 子命令注册在 fonttools 入口,输出默认名 merged.ttf,可用--output-file覆盖。
前置条件:✅ 两个 ttf/otf 文件,unitsPerEm 一致,可用ttx -t head核对。
fonttools merge latin.ttf arabic.ttf --output-file=merged.ttf --verbose预期结果:日志打印Merging 'cmap'.等行,生成 merged.ttf,包含两字体全部字形与合并后的 cmap。
另外注意:输出 sfntVersion 取第一个输入文件,TTF 与 OTF 混合并会导致表结构不一致,保持两字体同为 TTF 或 OTF。
批量合并字体文件列表
字体超过 3 个时,路径写进列表文件更稳:一行一个路径,#开头的行按注释忽略。
前置条件:准备 list.txt,每行一个待合并字体路径。
# list.txt: 每行一个字体路径 fonttools merge --input-file=list.txt --output-file=merged.ttf --drop-tables=DSIG预期结果:生成 merged.ttf;--drop-tables按标签跳过表格(大小写敏感),合并日志中每个表标记Merged或Dropped。
Python API 合并与元数据注入
程序化场景直接用 Merger;merge()返回 TTFont 对象,可改表后保存;命令行等价路径是--import-file=meta.ttx,Python 里则调用importXML()。
前置条件:Python 环境已安装 fonttools。
from fontTools.merge import Merger font = Merger().merge(["latin.ttf", "arabic.ttf"]) font.save("merged.otf")预期结果:save生成单份输出;若提供 TTX,name 表等元数据按 TTX 覆盖。
坑与边界
⚠️ 以下 4 条是实际会打出来的报错/告警:
- AssertionError: Expected all items to be equal: [1024, 2048]→
head.unitsPerEm的合并逻辑是equal,upem 不一致直接断言失败 → 先用 Lib/fontTools/ttLib/scaleUpem.py 把字体缩放到同一 upem 再合并。 - Warning "Have non-identical duplicates to resolve ... but no GSUB"→ 该字体存在待消解的重复字形但没有 GSUB 表,冲突无法自动处理 → 合并前确认字体带 GSUB 表,否则冲突码位只映射到第一个字体的字形。
- Warning "Dropped mapping from codepoint 0x0028 to glyphId"→ 同一字体内同码位映射了两个不同字形,且已被其他字符重定向 → 检查源字体 cmap,移除重复映射。
- Warning "Dropped cmap subtable from font ... format 14"→ 非标准 cmap 子表(format 4/12/14 之外)被丢弃 → 属预期行为,除非依赖该子表,否则无需处理。
选型参考
- 命令行 merge 覆盖“同 upem、cmap 取并集、GSUB/GPOS 合并”的常规需求;只合并 cmap 一张表时,直接用 ttLib 操作
TTFont["cmap"]更快。 - 需要改轮廓或从零造字体时,换 Lib/fontTools/fontBuilder.py 的 FontBuilder 方案,或用 ufoLib + designspace 建变量字体。
- 变量字体的 designspace 合并与拆分降级,见 Lib/fontTools/designspaceLib/split.py。
FontTools merge 子命令覆盖约 80% 的常规合并需求;涉及变量字体轴合并或轮廓重建时,应交给 varLib 与 ufoLib 处理。
【免费下载链接】fonttoolsA library to manipulate font files from Python.项目地址: https://gitcode.com/gh_mirrors/fo/fonttools
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考