☰
FontForge 常见问题深度解析:从字体编辑、格式转换到跨平台安装实战
2026/9/27 21:25:19 网站建设 项目流程
  • 桌面应用
  • 图形学

【免费下载链接】fontforge

Free (libre) font editor for Windows, Mac OS X and GNU+Linux

项目地址:https://gitcode.com/gh_mirrors/fo/fontforge
点击查看免费下载

FontForge 是一款面向 Windows、macOS 与 GNU+Linux 的免费(自由)开源字体编辑器。本文以官方 FAQ 文档(doc/sphinx/faq.rst)为骨架,逐一拆解用户最常遇到的疑问:为什么需要字体编辑器、字体点大小与 em 单位如何理解、如何在不同操作系统上安装字体、如何进行格式转换、Hinting 指令如何处理、以及大量编辑器内部的怪异行为。读完本文,你将系统掌握 FontForge 的核心概念、跨平台字体安装流程与常见故障的排查思路,并能在实际项目中直接复用这些操作步骤。

关于 FontForge 本身的疑问

为什么还需要一个字体编辑器?

面对"字体已经够多了"的疑问,FAQ 给出了一个明确的回答:字体是艺术品,如同水彩画,永远不会"够多"。从实用角度讲,仍存在大量未被满足的需求:拉丁字体很多,但希腊文、西里尔文、印度系文字、泰文、中日韩等字体的高质量作品相对稀少;研究古文字系统的学者常常需要自行设计字体;而即便是现有字体,也可能缺少连字(ligature)、缺少带音调符号的字形、缺乏配套的西里尔文或希腊文字形。

除了创建与修改字体,FontForge 还被广泛用于:格式转换、从字体文件中提取信息、以及在不安装字体的情况下直接预览字体效果。

为什么用 C 写而不是 C++?

作者坦言自己并不认同面向对象实践,认为 C++ 过于复杂且难以调试。文中列举了几条个人理由:C++ 程序语义难以完整确定(编译器可自由生成临时对象,而临时对象的构造/析构可能带来副作用);外部构造函数执行顺序不确定;单步调试时经常跳入大量意外的内联过程调用;以及各编译器行为存在细微差异。作者曾在 1987–1994 年间为 Green Hills Software 编写过 C++ 前端,属于基于长期实践的判断,而非偏见。

这一选择在仓库中同样可见:核心字体引擎(如 fontforge/splinefont.c、fontforge/tottf.c、fontforge/parsettf.c)以 C 为主,仅在 GUI 绑定、脚本桥接等少量位置使用 C++(如 fontforge/python.cpp)。

为什么采用 BSD 许可证而不是 GPL?

作者的立场非常直白:"我不喜欢强迫别人接受限制"。BSD 许可证的核心诉求只有两点——"不要起诉我,如果用了我的代码请保留版权声明"。作者认为 GPL 将限制强加于人,而他希望 FontForge 被自由使用、修改甚至被嵌入其他项目。文中也提到,其 OpenType 代码曾被某些 TeX 包借鉴,作者也从其他软件包借鉴过校验和生成代码——这种互助正是开源生态的价值所在。

为什么在运行时动态加载库而不是静态链接?

作者不喜欢依赖:下载一个包却被迫再装五六个依赖包是不可接受的。因此 FontForge 尽量自己实现功能,并将二进制包整体发布;对于不得不使用的外部库,则采用运行时dlopen动态加载——在真正需要时才加载。例如用户从不查看 SVG 字形就不需要 libxml2,从不导入 JPEG 图像就不需要 libjpeg。这样既加快了启动速度,又保证了缺失某个库时其余功能照常工作。

为什么没有路线图?

作者坦承自己"不这样思考":不预先规划,而是带着模糊方向边探索边前进。文中以 Python 脚本支持为例描述这种演进:加入 Python 后,随之诞生了用户自定义导入/导出格式的机制,然后是启动脚本、事件脚本、自定义菜单项,最终甚至可以把 FontForge 作为库嵌入 C 程序。许多功能来自用户的真实需求,而不是计划表。

字体的基本概念:点大小、em 单位与行间距

什么是"12 点字体"?

一个字体是 12 点大小,当两行相邻(不加行距)文本的基线距离为 12 点时。点大小并非由任何字形的大小决定——金属活字时代,点大小对应的是承载该字体的金属字模(slug)的高度。因此点大小并不是衡量字形的绝对尺寸,有些字体为音调符、升部或降部预留更多空间,实际字形会显得更小。传统上,英美使用 pica 点(1/72.27 英寸),欧洲使用 didot 点(1/67.54 英寸)——欧洲点稍大,恰好为带音调符号的欧洲语言留出空间。

什么是 em 单位(内部单位)?

当字形实际被绘制时,其大小取决于 em 大小(em-size)。例如一个长度 500 内部单位的 dash 字形,若字体 em 大小为 1000 单位,绘制在 12 点时字形长度为 500/1000 × 12 = 6 点;在 72 dpi 屏幕上即 6 像素。em 大小可通过Element → Font Info → General设置,通常为 1000 或 2048,其含义是排版升部与降部之和(金属活字时代即字模高度、基线到基线的距离)。FontForge 内部即以该坐标系显示轮廓字形。

如何设置字体行间距?

这取决于字体类型、目标操作系统乃至"运气":

  • Type1 字体:无法直接设置行间距,应用通常依据字体包围盒(bounding box)推算,这是常见但糟糕的做法。
  • TrueType/OpenType:
    • macOS:行间距由 'hhea' 表的 ascender/descender 决定,而它们又被设置为字体包围盒值。可通过Element → Font Info → OS/2 → Metrics控制。
    • Windows:规范要求使用 OS/2 表中的 Typo Ascent/Typo Descent(两者之和应为 em 大小)。但多数 Windows 应用并不遵循该规范,而是基于 Win Ascent/Descent 计算行距——这些值本应只定义裁剪区域。如果 GPOS 查找可能把字形移出包围盒(如 mark-to-base 定位),裁剪区域应大于包围盒。微软为此在 OS/2 表中加入了一个冗余位,即 OpenType 中的 UseTypoMetrics,FontForge 中对应Element → Font Info → OS/2 → Metrics → Really Use Typo Metrics。
    • Linux:没有统一共识,应用可能采用上述任意一种方案。

FAQ 进一步指出:现代字体常含多种文字系统,各系统行距需求不同(英语几乎不用音调符号,可排得更紧密;德语等语言则需要更多空间)。与其设置一个全局行距,不如使用 OpenType 'BASE' 表按脚本、语言和激活特性(如 'mkmk' 特性增加行距)分别指定。

如何标记等宽字体?

你不需要显式标记。只需保证字体中所有字形具有相同宽度,FontForge 会自动将字体标记为等宽。若错误标记,某些光栅化器会给出奇怪结果。注意这里的"所有字形"包括 Unicode 规定宽度应为 0 的字形——微软建议用 GPOS 完成组合重音,并将任何标记(重音)字形的步进宽度设为 0。如需手动设置 Panose 值(Element → Font Info → OS/2 → Panose),可将 Proportion 字段设为 Monospaced,但这只是必要条件而非充分条件。若不确定是否所有字形宽度一致,可用Element → Find Problems → Random → Check Advance检查。

非整数坐标安全吗?

FontForge 允许以非整数坐标编辑。答案取决于输出格式:

  • TrueType只能表达整数坐标,生成时所有坐标会被取整,曲线产生轻微形变。若需更高精度,可将 em 大小改为 8096。
  • PostScript(Type1、PostScript OpenType、Type2 等)可以表达非整数坐标,但会显著增大文件体积(Type1 比 Type2 更占空间)。FontForge 默认同样取整,但可在 Generate Options 对话框中关闭取整——关闭后文件更大但更精确。OpenType PostScript 字体的 em 大小通常被应用假定为 1000,因此不建议为 OpenType 输出修改 em 大小。

这也解释了 FAQ 中"为什么 OpenType 字体不比 .pfb 文件小多少"的疑问:未在保存前取整时,FontForge 会使用定点数(fixed point)存储坐标,占用远超普通整数。

字体的法律与许可问题

修改字体合法吗?合乎道德吗?

法律因国家而异。FAQ 给出如下要点与指南:

  • 先查看随字体提供的许可协议;
  • TrueType/OpenType(以及潜在 CID-keyed 字体)在 OS/2 表中有 FSType 字段,允许设计者限制他人对字体的操作。若该字段禁止修改,FontForge 会要求你确认持有优先于该字段的协议;
  • 美国:字体设计本身法律保护有限("字母表是公共的"),但设计师可申请设计专利(若获批准保护 14 年,不可续期);字体程序(PostScript 或 TrueType 文件,不包括位图文件)可受版权保护;字体名称可注册商标;
  • 英国:存在类似版权的"design right",保护设计 5 年,可注册续期最多 5 次至 25 年;
  • 欧盟:存在欧盟设计权,具体细节与各国法律(如英国设计权)的交互不明确;
  • 加拿大:字体设计可注册为"工业设计",保护期约 15 年。

作者明确提示:最终结论请咨询律师。

开源字体该用什么许可证?

通用开源软件许可证(见 Open Source Initiative 列表)通常不能满足字体设计的特定需求。FAQ 推荐两种专为字体设计的许可证:

  • SIL Open Font License(OFL)——作者明确推荐,并提供非官方翻译合集供非英语用户理解意图;
  • Bitstream Vera 字体许可证。

GPL 也常被用于字体,但需注意其条款与字体分发的适配问题。这一话题与仓库中 desktop/org.fontforge.FontForge.appdata.xml.in 及根目录 COPYING.gplv3、LICENSE 等许可证文件直接相关——FontForge 自身是自由软件,但用 FontForge 生成的字体可以选择任何合适的许可。

系统要求、内存与稳定性

最低要求是什么?

FontForge 主要受内存限制(屏幕空间也可能是瓶颈):

  • 处理几百个简单字形(如拉丁字母表)的字体:192MB 绰绰有余;
  • 严肃编辑 CJK 字体:512MB 处于可用性下限。

必须配备彩色(或灰度)显示器,黑白显示器不够用。系统版本方面:Windows 版基于 msys2/mingw-w64 构建,最低支持版本取决于依赖库(写作时为 Windows 7 及以上);macOS 版通过 Homebrew 构建,支持最近的三个大版本(写作时为 macOS 10.13 High Sierra 及以上)。

为什么 FontForge 占用那么多内存?

字体文件格式为体积小、易于光栅化而设计,不适合直接编辑。FontForge 加载字体时会将其展开为更直观、更易编辑的内部表示——功能强大但占用大得多。SFD 文件之所以庞大,正因为它就是这个展开格式的 ASCII 文本表示,其设计目标是可读而非紧凑。重写内存表示理论可行,但工作量巨大。

内存耗尽、系统崩溃怎么办?

FontForge 在内存分配失败时会检查并尝试释放部分内存块(虽然作者坦言"从未见过这段代码被触发")。实用对策有两个:

  • 使用Edit → Remove Undoes清除与字形关联的撤销历史;
  • 通过File → Preferences → Editing → UndoDepth限制每个字形存储的撤销步数。

为什么 FontForge 有时不稳定?

作者坦承自己在 QA 上投入不足,这是已知问题,并欢迎志愿者参与测试工作。

字体安装实战:跨平台操作指南

Unix 与 X Window 系统

  • 轮廓字体与 fontconfig:许多程序(包括 FontForge 自身)通过 fontconfig 查找字体,安装方式很简单——把文件复制到~/.fonts目录即可。
  • 位图字体与原生 X11:将字体放入指定"字体目录",构建 X 所需的数据结构并加入字体路径。以安装 BDF 字体frabnuts-13.bdf为例:
$ mkdir my_fonts $ mv frabnuts-13.bdf my_fonts $ cd my_fonts $ bdftopcf frabnuts-13.bdf >frabnuts-13.pcf $ mkfontdir $ xset fp+ `pwd`

每次启动 X 后需要重新声明字体位置,把xset fp+ /home/me/my_fonts加入.xsession或等价文件中。

  • PostScript 字体:生成 .pfb(二进制 PostScript)文件,将 .pfb 与 .afm 一起放入字体目录并运行type1inst。它可能抱怨字体没有 foundry 或编码不对——可以忽略,或手动编辑 fonts.scale,或修正字体版权信息后在 type1inst 中补充 foundry。
  • TrueType 字体:将 .ttf 移入字体目录并运行 mkttfdir 与 mkfontdir。注意 mkttfdir 几乎总会抱怨不识别 FontForge 生成的字体 foundry(PFED),可安全忽略;如介意,可在 ttmkfdir.c 第 936 行加入{ "PFED", "FontForge" }。部分 X 发行版(如 RedHat)依赖 X 字体服务器而非 X server 本身,此时用 chkfontpath 而非xset fp添加目录,并确保字体目录及父目录对 world 可读。
  • KDE:可使用 kfontinst 工具自动完成配置(作者在 0.9.2 版本上体验时需以 root 运行)。

TeX

TeX 有自己独立于平台的字体安装体系,详见 FAQ 中关于 TeX 安装经验的章节。

Windows

将 TrueType 字体拖入\Windows\Fonts目录即可安装,可能需要设置可执行权限位。两条重要警告:

不要直接把字体生成到\Windows\Fonts目录——这往往不生效(至少在 XP 上如此)。应生成到其他目录,再拖拽安装。

若使用 Type1 字体,需安装 Adobe Type Manager 并按其说明操作;旧系统(Windows 2000 之前)安装 OpenType 字体同样需要 ATM,新系统与 TrueType 安装方式一致。

Mac OS 9

Mac 将字体存于资源分叉(resource fork)并包裹在自己的头结构中,与其他平台不兼容。FontForge 可通过 macbinary 编码创建资源分叉。编辑 Mac 字体的完整流程:

  1. 在System Folder:Fonts中找到文件;
  2. 复制到 Unix 机器(用 Fetch 并指定 macbinary 格式,或用 binhex 等工具);
  3. 在 FontForge 中打开、编辑;
  4. 以 macbinary 格式保存;
  5. 复制回 Mac(Fetch 会自动解开 macbinary 包装);
  6. 放回系统文件夹。

注意:要么替换原字体文件,要么在 FontForge 内重命名字体并(对 PostScript 字体)赋予新的唯一 ID。告诫:PostScript 字体在 Mac 上若无至少一个位图字体相伴则不可用——生成 PostScript 字体时务必同时生成 NFNT(其中含 FOND)。Mac 对 PostScript 文件名很挑剔(依据 PostScript 字体名变换而来,见 Adobe Technical Note 0091):字体名按大写字母分块,首块可带四个小写字母,后续块只能带两个,连字符消失。如 TimesBold → TimesBol,Helvetica-BoldItalic → HelveBolIta。

Mac OS X

OS X 字体放在顶层Library/Fonts(默认/Mac OS X/Library/Fonts/)、System/Library/Fonts或用户目录~/Library/Fonts。资源字体(解开 macbinary 包装的)或 dfont 均可,也可直接使用 ttf/otf。老式 NFNT 位图资源在 10.2 上无法使用(位图字体需包装进 ttf 或 sfnt);但使用资源型 Type1 字体时,系统仍要求先有一个(无用的)位图字体存在。

如何编辑 Mac 字体

OS 9 及更早版本:传统上 Mac 字体存于资源分叉,其他机器没有该概念。macbinary 与 binhex 可将 Mac 文件打包为单一文件,FontForge 能读取这两种格式并提取 PostScript 或 TrueType 字体,也能以 macbinary 输出(macbinary 更简单,故只支持这一种输出格式)。

OS X:可直接运行 FontForge,能直接编辑老格式资源字体与 .dfont 数据分叉字体,也支持普通 .otf/.ttf。

如何创建 Mac 字体族

  • Snow Leopard(10.6)及之后:先在 FontForge 中打开字体族的所有成员,然后File → Generate TTC,比旧方法简单得多。
  • Leopard(10.5)及之前:使用File → Generate Mac Family创建字体族。族内所有字体必须具有相同 Family 名。FOND 资源(源自 1980 年代初的计算机字体技术)只支持 Bold、Italic、Condense、Extend、Underline、Shadow、Outline 的组合(Extend 与 Condense 不能同时出现),不支持 "Black"、"DemiBold"、"Light"、"Thin" 或 "Extra-Condensed"。ATSUI 下,一族由同一资源文件中 FamilyName 相同的所有字体构成。实践中 Apple 在同一文件放置多个 FOND,各含一个相关子族:例如含 Regular/Bold/Italic/Bold-Italic/Condense/Condense-Italic 的族,再为 Oblique、Light、Light-Italic 单独设置 FondName(Element → Font Info → Mac),并将 Light 变体的 Mac Style 设为 Regular、Light-Italic 设为 Italic——即"忘掉 Light",因为 FOND 处理不了。完成设置后Generate Mac Family会把所有字体放入合适的 FOND 并合并到一个文件中。

为什么 ATM 在我的 Mac 字体上不工作?

确保生成字体时使用 Macintosh Latin 编码。这是 ATM 的局限,FontForge 无能为力:若以其他编码生成,Mac 默认强制 PostScript 字体使用 Macintosh Latin 编码;虽有关闭机制,但关闭后 ATM 将完全失效。

为什么字体在 Windows 上装不上?

  • 常见原因之一:Windows 有时要求字体有对应语言的名称(如 SJIS 字体需日文条目)。到Element → Font Info → TTF Names添加相应语言字符串。
  • 另一可能见"为什么 FontForge 的字体在某些 Windows 机器上装不上"。
  • 2009 年的一个 Windows 安全补丁拒绝安装 name 表大于 5K 的字体——常因字体中嵌入了完整许可证文本所致。
  • 从其他机器复制字体时确保设置了可执行权限位(cygwin 下chmod +x foo.ttf)。

为什么生成 OpenType 字体后 Windows 拒绝安装?

Apple、微软与 Adobe 对 Open/TrueType 格式的规范存在分歧。FontForge 的 Generate Font Options 对话框中有[] Apple复选框:为 Mac 生成字体时勾选,为 Windows(通常 Unix 也一样)生成时取消勾选。已知差异包括:NAME 表中的 PostScript 名称条目、位图字体表名、缩放引用的存储方式,以及高级排版表完全不同。

为什么带 OpenType 表的 TrueType 字体在 Windows 上显示 "TT" 图标而非 "O" 图标?

Windows 依据字体是否包含 'DSIG'(数字签名)表来判定 "O" 图标。FontForge 本身不生成数字签名,但可以创建不含签名的 'DSIG' 表,这足以让 Windows 满意。

格式转换实战

轮廓字体互转

最简单的通用流程:File → Open打开现有字体,然后Element → Generate Fonts生成目标格式。PostScript 格式互转(如 pfb → otf)仅此即可。

TrueType(二次样条,ttf)→ PostScript(三次样条,otf/pfb),若要更高质量:

  1. File → Open(打开 TrueType 字体)
  2. Element → Font Info → Layers,勾选 "All layers cubic",OK
  3. Edit → Select → Select All
  4. Element → Simplify → Simplify
  5. Hints → Auto Hint
  6. Element → Generate Fonts

PostScript(三次样条)→ TrueType(二次样条):

  1. File → Open
  2. Element → Font Info → Layers,勾选 "All layers quadratic",OK
  3. Edit → Select → Select All
  4. Hints → AutoInstr
  5. Element → Generate Fonts

位图格式互转、轮廓转位图、位图转轮廓

  • 位图 → 位图:打开位图字体,用Element → Generate Fonts生成目标格式。
  • 轮廓 → 位图:加载轮廓字体,用Element → Bitmaps Available生成所需尺寸的位图 strike(此过程称光栅化,小像素尺寸下很难做好)。建议在位图窗口(Window → Open Bitmap Window)检查结果并随手修正,完成后在 Generate Fonts 中关闭轮廓生成、选择位图格式。
  • 位图 → 轮廓:除非是很大的位图字体(如 TeX 字体),否则效果不佳。流程:先安装 potrace 或 autotrace(文档见 doc/sphinx/techref/autotrace.rst 相关章节)→ 新建字体 →File → Import导入位图(务必勾选[] Into Background)→Edit → Select → Select All→Element → Autotrace→Element → Add Extrema→Element → Simplify→ 人工清理 →File → Generate Fonts。

AAT 与 OpenType 互转

  • AAT → OpenType:基本自动完成。加载 Apple 字体,在 Generate 的 Options 对话框中勾选[*] OpenType。FontForge 会转换 Apple feature/setting 与 OpenType feature 匹配的所有非上下文特性(包括非上下文连字,尽管它们位于上下文格式中)。详细信息见 doc/sphinx/techref.rst 中 gposgsub 章节。
  • OpenType → AAT:同样基本自动。加载 OpenType 字体,Generate 时勾选[*] Apple。部分上下文 OpenType 表可转换,与 Apple feature/setting 匹配的非上下文特性也会被转换。注意两种格式表达能力不同,转换可能损失信息。

从 Inkscape 导入字形

在 Inkscape 中:File → Document Properties,单位设为像素(px),画布设为 1000×1000(若字体 em 单位不同则用对应值,1000 是 FontForge 默认)→ 在 200px 处设水平参考线 → 绘制字形 → 存为 SVG。然后在 FontForge:File → Import选择 SVG →Element → Transform,Y 值设为 -200。

Hinting 与 TrueType 指令

提示替换(Hint Substitution)与 Flex Hints

提示替换会自动发生;也可选中某点,通过Element → Get Info → Hint Mask控制提示组变更的位置。Flex hints 同样自动生成:FontForge 会在合适的场合生成 flex hints,需要时向字体添加必要子程序,不需要时则不添加。想确认是否会使用 flex hints,可打开UpdateFlex偏好项并查看字形——FontForge 会在 flex hint 中心点周围显示绿色光晕。

为什么完美提示的字形仍出现不同宽度的笔画、模糊或消失?

PostScript 和 TrueType 都要求字形按顺时针方向绘制。部分光栅化器对此不敏感,但另一些会因逆时针路径产生笔画宽度不一、模糊甚至完全消失。解决方案:生成字体前对所有字形执行Element → Correct Direction。

为什么修改过的 TrueType 字形远不如原始字形好看?

FontForge 读取 TrueType 字体时保留全部原始指令,但一旦以任何显著方式修改字形,原指令即失效(它们与轮廓细节紧密耦合),FontForge 会将其移除。结果就是被修改的字形外观降级。解决方法:用Hints → AutoInstr让 FontForge 自行生成 TrueType 指令。

字体格式与排版进阶

OpenType、PostScript 与 TrueType 的区别

PostScript 和 TrueType 各自定义了文件格式与字形格式。OpenType 使用 TrueType 文件格式承载 PostScript 字形格式(OpenType 也包含 TrueType 字形格式,但按定义此类字体仍应称为 TrueType 字体)。OpenType 中的 PostScript 与 .pfa/.pfb 略有不同:pfa/b 是 Type1 字体,OpenType 用 Type2 字体——Type2 几乎是 Type1 的超集(少量变更、大量扩展),Adobe 基于子程序的 Type1 扩展(flex hints、提示替换、counter hints)在 Type2 中已成为直接指令。OpenType 还能包含额外信息,支持复杂脚本(阿拉伯文、印度系文字等)的排版、字形变体及精细排版。

AAT 与 OpenType 的区别

两者都是基础 TrueType 字体的扩展,可承载复杂脚本排版与字形变体信息,但复杂部分使用完全不同的内部格式,表达能力不同,因此互转必然存在信息损失可能。详见 doc/sphinx/tutorial.rst 与 doc/sphinx/techref.rst 中的相关章节。

为什么在 10.3 正常的字体在 Mac 10.4(Tiger)上出问题?

Tiger 增加了部分 OpenType 支持,部分 OpenType 特性运行时被转换为 AAT 特性;但并非所有特性都有对应的 Apple feature/setting,条件查找(conditional lookups)也无法转换。若字体同时包含 OpenType 与 AAT 特性,Apple 会忽略 AAT 特性——结果本应可用的 AAT 特性不被使用,而支持不全的 OpenType 特性反而被使用。

加载字体后引用变成内联副本,如何找回引用?

从 PostScript 字体推断旧引用非常困难,FontForge 提供了专用命令Edit → Replace With Reference:它会在字体中搜索潜在的引用候选并替换为引用。

FontForge 能读取字距(kerning)信息吗?

分情况:

  • TrueType/OpenType:能。字距存于 'kern' 或 'GPOS' 表,FontForge 均可读取(包括 Apple 对 TrueType 规范的一系列扩展)。
  • 非 Mac 的 PostScript Type1:Type1 文件本身不存字距,而是存在同名的 .afm 文件。FontForge 读取 PostScript 字体时会查找关联 afm 文件并读入字距。
  • Mac 上的 PostScript Type1:不能。字距存于位图字体文件,但 Mac 上无法猜测关联位图文件名。
  • AFM/TFM 文件、含 FOND 资源的 Mac 资源文件、Adobe Feature 文件:FontForge 都能直接读取字距/特性信息并应用到字体,通过File → Merge Feature Info菜单命令。

如何设置 OS/2 表(或其他表)的某一位?

FontForge 本身不做此事,作者编写了配套程序mensis(拉丁语意为"关于表"),提供 UI 与脚本两种方式按位访问表。

什么是 cidmap 文件?

背景:PostScript 初期每个字形有名称、编码由 256 元素数组指定。面对 CJK 巨量字形集,为上万字形起名字既不省空间也无意义,于是 Adobe 创建了 CID-keyed 字体:无字形名、无编码,每个字形只有一个索引(CID),字体外部另有 cmap 资源提供编码(可支持 SJIS 等复杂编码方案)。Adobe 为标准 CID 赋予了固定含义(JIS208、JIS212、韩文、中文香港/台湾、中文大陆/新加坡、Identity(Unicode) 共 5~6 套标准),例如 CID 1 是空格、CID 935 是"Katakana ka"。仓库中 contrib/cidmap 目录就存放着这些映射文件(Adobe-Japan1-6.cidmap、Adobe-GB1-5.cidmap、Adobe-CNS1-6.cidmap 等)。cidmap 文件提供 Adobe CID 与 Unicode 的映射,让 FontForge 知道正在处理哪个字形;缺失时字体视图会显示 "?",也无法重编码为 Unicode。它们只对处理 CID-keyed CJK 字体的人有用。

什么是 SFD 文件?

SFD 是 FontForge 自有格式:文本文件,体积大但人可读,仅使用 ASCII 字符(老邮件程序传输不会变形),是注册 MIME 类型application/vnd.font-fontforge-sfd。格式概览见 doc/sphinx/techref.rst 中 sfdformat 章节。它体积大正是因为它是内存展开格式的 ASCII 表示,设计目标是可读而非紧凑。

字体名称都有什么含义?

Element → Font Info的 Names 面板包含 PostScript 字体使用的名称;另有 TTF Names 面板对应 sfnt(TrueType、OpenType 等文件格式)中的名称。一个字体可能"PostScript 包装在 sfnt 中",同时有两套名称,通常应保持一致。

  • 名称(Name for humans):如 "ITC New Century Schoolbook Italic #4",应用用于向人展示;
  • Fontname:PostScript 内部标识字体用的编程语言名称,字符受限(不能有空格、不能像数字、无括号)且有长度限制,如 "ITCNewCenturySchoolbook-Italic";
  • Family name:字体族名,如 "ITC New Century Schoolbook";
  • Base Filename:仅用于方便,控制生成字体时的默认文件名(默认是 fontname 加扩展名,如 ITCNewCenturySchoolbook-Italic.ttf),与字体内容无关;
  • Weight string:如 "Bold"、"Black"、"Thin",不含 Italic 或 Condensed 等风格变体;
  • Copyright:版权声明。

TTF Names 面板则包含 Family(对应 PostScript Family)、SubFamily(类似 weight 但涵盖全部风格变体,如 "Bold Italic"、"Condensed")、Fullname(对应名称)、Copyright。通常 FontForge 会自动设置;不满意时可右键选择与 PS 名解除关联。此外还有 WWS Family/WWS SubFamily(微软认为必要,多数情况应与 Family/SubFamily 相同从而省略)、CID fontname(仅构建 CID-keyed 字体时使用)、Compatible Fullname(作者认为应与 Fullname 相同而省略)。TTF Names 支持多语言:最常被翻译的是 SubFamily,如 Italic 在法语为 Italique、德语为 Kursiv、荷兰语为 Cursief。

数学问题:精度与样条转换

Simplify 命令会损失精度吗?

会,但不多。它用一组样条替换原样条,保证任意点与原样条偏差不超过局部坐标系中的 1 单位。若需更高精度,可在轮廓视图中先Edit → Select → Select All→Element → Transform → Transform放大 1000%,Simplify,再缩小 10%——最终偏差不超过 0.1 单位。

三次样条如何转换为二次样条(生成 TrueType 时)?

可能损失精度。FontForge 先检查样条是否已是二次的(刚读取 TrueType 字体或"奇迹般"生成的曲线即如此);否则将原样条分段,寻找与原三次曲线任意点偏差不超过 1 单位的二次样条组(两端点及端点斜率确定后,其间只存在一条二次样条)。

二次样条如何转换为三次样条(读取 TrueType 时)?

很简单:任何二次样条都可表示为三次样条(三次项恒为 0)。不过控制点可能不再位于整数坐标,保存为三次格式时会有一定精度损失。

编码与字形命名

如何告诉 FontForge 一个新的编码?

通常 OpenType/TrueType 字体用标准 Unicode 编码即可,但确有需要时流程如下:

  1. 弄清目标编码的样子(如天城文可参考 ISCII 编码资料),这些编码通常只展示顶部 96 个字符,其余假定与 US ASCII 相同;
  2. 创建编码文件(如 "Devanagari.ps"),首行写/Devanagari {,随后列出所有字符名(前置斜杠)——先 32 个 .notdef,然后是 space、exclam……直至 unicode 字形名,如:
/Devanagari { /.notdef /.notdef ... /.notdef /space /exclam /quotedbl ... /braceright /asciitilde /.notdef ... /.notdef /uni0901 /uni0902 ... /uni096F }
  1. 用Encoding → Load Encoding将该文件载入 FontForge 的编码列表,再应用到目标字体。

从源码看,这一过程由 fontforge/encoding.c 中的ParseEncodingFile()(fontforge/encoding.c#L686-L765)实现:它会自动识别文件格式——以#或0开头的是联盟编码文件(Consortium encoding file),否则按 PostScript 样式的名称列表解析;无 UI 环境下无名编码会被拒绝,带 UI 时会逐一询问编码名称,最后把新编码并入全局编码列表。同一函数同时服务于 Python 接口loadEncodingFile(fontforge/python.cpp#L597-L606)与脚本命令LoadEncodingFile(fontforge/scripting.cpp#L3377-L3391),并支持文件名与可选编码名两个参数。

如何添加一个新名称的字形?

以向 ISO-8859-1 字体添加 "dotlessi" 为例,两种途径:

  1. Encoding → Add Encoding Slots...,输入额外字形数(通常 1)→ OK → 滚动到字体末尾找到新槽 → 选中 →Element → Glyph Info→ 在 "Unicode Name" 输入 dotlessi → 点 "Set From Name" → OK → 绘制字形。
  2. Encoding → Reencode → ISO-10646-1→View → Goto输入 dotlessi → 绘制字形 → 再次Encoding → Reencode改回原编码。

为什么 FontForge 给某些字形错误的名称?

FontForge 遵循 Adobe 的命名约定(为兼容旧编码存在已知问题):

  • Delta→ U+2206 INCREMENT,而非 U+0394 GREEK CAPITAL LETTER DELTA(可能因 Increment 在旧 MacRoman 编码中);
  • Omega→ U+2126 OHM SIGN,而非 U+03A9;
  • mu→ U+00B5 MICRO SIGN,而非 U+03BC(Micro Sign 在 ISO-Latin1 和 MacRoman 中);
  • omega1→ Unicode 称之为 GREEK PI SYMBOL(看起来像 omega);
  • Tcommaaccent/tcommaaccent→ U+0162/U+0163(T WITH CEDILLA)而非 U+021A/U+021B(T WITH COMMA BELOW),源于早期 Unicode 规范的混淆;
  • dotlessj→ U+F6BE(私有区)而非 U+0237,因为 Adobe 在 Unicode 之前就定义了该字形并占用私有区槽位。

这解释了"为什么我的希腊字体里没有叫 mu 的字符":Adobe 为 Unicode 编码命名希腊字母时更注重向后兼容——"mu" 指向 Micro Sign 而非希腊字母 μ,Delta 指向 Increment,Omega 指向 Ohm Sign;U+03D6 被命名为 "omega1" 而非更贴切的 "pi1"。

如何设置字体的默认字形?

若名为 ".notdef" 的字形含样条(无引用),它将被用作默认字形(即请求未编码字形时使用的字形)。例外:在(PostScript)OpenType 字体中,默认字形使用 "space" 字形而非 .notdef(这是规范如此)。

GUI 与系统怪癖

如何改变 FontForge 的灰色背景?

通用机制见 X Resources 文档,doc/sphinx/ui.rst 的 misc 章节提供了若干配色组合示例。

GUI 字体太小/太大怎么办?

X server 常对屏幕分辨率估计不准。可在~/.Xdefaults中声明真实屏幕尺寸:

Gdraw.ScreenWidthInches: 14.7 Gdraw.ScreenWidthCentimeters: 37.3

仍嫌字体小,可以"谎报"更小的屏幕尺寸——字体将随之变大。

为什么点击最小化视图时窗口却图标化了?

某些窗口管理器(如 gnome-sawtooth)会截获 meta(alt)点击。此时无法用 meta-中键-点击缩小字形,请改用View 菜单 → Zoom Out。

为什么生成字体并退出后 FontForge 还问是否保存?

两个原因:

  1. FontForge 可能需要对一个或多个字形(重新)生成提示信息——例如这些字形在更早的会话中修改过但此后未生成提示,新提示会把字体标记为已更改;
  2. 若字体 Font Info 中有 XUID 字段,每次生成 PostScript 字体时 FontForge 都会递增 XUID 末位数字——这也算一次更改(Adobe 建议如此,可避免字体缓存问题)。

为什么 Build Accented Glyph 是灰色的?

要构建 cacute(ć)这类合成字形,字体中必须同时存在字母 c 与COMBINING ACUTE ACCENT(而不是 MODIFIER LETTER ACUTE ACCENT,后者通常位于圆圈符号区)。两者齐备后选项才会激活。想知道某字形需要哪些组件,在Element → Glyph Info左侧查看 components,FontForge 会列出合成字形的组成。

为什么希腊扩展区(U+1F00-U+1FFF)字形选择了错误的音调符?

Unicode 将希腊与拉丁音调符统一了,尽管二者形态迥异。FontForge 遵循简单的 Unicode 定义时可能为希腊字形选中拉丁音调符。解决办法:Unicode 自 U+1FBD 起有希腊音调符码位,把这些码位填上合适的希腊音调符,FontForge 就会优先使用它们。

为什么 "u"、"y" 上方的音调符没有居中?

某个笔画略高于另一个。FontForge 将音调符居中于字形最高点,若有多个等高点则取平均值。把所有笔画高度统一后即可正确居中。

为什么 Remove Overlap 后重叠部分反白(反转)?

参与合并的路径方向相反——可能翻转过字形再合并。解决:选中出问题的形状,执行Element → Reverse Direction。

为什么说 "EPS file is too complex to be understood"?

多数程序把 EPS 当黑盒:读入内存后原样输出给 PostScript 打印机。FontForge 不能这样做——它必须理解并转换 EPS 为更简单格式,因此要逐句解释 PostScript,而解释全部 PostScript 是巨大工程,FontForge 的能力有限,遇到无法处理的文件就会报此错。

为什么 ttf2afm 在 FontForge 生成的 ttf 文件上崩溃?

FAQ 记录的调查结论是:作者 RedHat 7.3 分发的 ttf2afm 确实崩溃,但从 CTAN 下载源码自行构建(带调试)后不崩溃,判定这是 ttf2afm 的 bug 且已被修复;另指出 ttf2afm 生成的 afm 文件不合 Adobe 规范。

为什么 kaiu.ttf 或 mingliu.ttf 的轮廓看起来完全不像?

这类 TrueType 字体未存储正确轮廓,而是依靠指令移动点来生成轮廓(轮廓未经网格拟合、仅被定位)。FontForge 读取字体时不会处理指令——对大多数字体这是正确的行为,且难以判断何时需要处理。

为什么 TeX 无法使用我的字体?

TeX 链(如 dvips)期望字体按 TeX Base 编码(TeX 文档有时误称其为 "Adobe Standard")。若遇到打印问题、缺字形等,将字体编码改为 TeX Base:Element → Font Info→ Encoding 标签 → 从下拉列表选择 TeX Base。

为什么 FontForge 不让我编辑 '.mf' 文件?

正如 Knuth 所言:"所见即所得的问题在于……所见就是所得的全部。"考虑 MetaFont 定义top1y2 = CapHeight,当用户拖动点 2 时,FontForge 该如何解释?改 CapHeight?改笔宽?改方程为CapHeight - 30?还是(CapHeight + XHeight)/2?——无法合理消歧,故不支持直接编辑 .mf。

为什么 Edit → Copy 不复制字形名?

FAQ 的三点理由:定义自定义编码是复制字形名的更好方式;多数情况下你并不想要名称;美学上复制应只处理数据而非元数据。但鉴于问的人够多,已在Edit → Copy From → Char Name提供了可改变默认行为的模式。若Edit → Paste抱怨名称重复,多半是勾选了Edit → Copy From → Copy Metadata,取消勾选即可。

为什么在 Xgl/Compiz 下 FontForge 很难看?

原因未知,但可通过为 FontForge 设置环境变量XLIB_SKIP_ARGB_VISUALS=1修复。

结语

FAQ 文档以诙谐而务实的笔触覆盖了从哲学疑问到实操细节的完整光谱:字体点大小的真正含义、OS/2 表的行距字段之争、macbinary 与 FOND 的复杂历史、TrueType 指令对编辑的约束,乃至"为什么没有路线图"。理解这些问题的底层原理——例如ParseEncodingFile如何解析自定义编码、hhea/OS/2 指标如何参与行距计算、指令与轮廓的耦合关系——能帮助你在使用 FontForge 时少走弯路。若你正被某个诡异现象困扰,先查 FAQ 往往比盲目调整更高效:答案很可能就在其中。

  • 桌面应用
  • 图形学

【免费下载链接】fontforge

Free (libre) font editor for Windows, Mac OS X and GNU+Linux

项目地址:https://gitcode.com/gh_mirrors/fo/fontforge
点击查看免费下载

相关推荐

上一篇:PP-OCRv6_tiny_det实战教程:10个场景下的文字检测应用案例
下一篇:gh_mirrors/1o/1on1-questions前端框架选型:React vs Vue的性能对比

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询