从cidfont到OTF:Source Han Serif字体文件格式转换全流程
你是否曾在处理中日韩多语言排版时遇到字体兼容性难题?是否困惑于CID-keyed字体(Character ID-keyed font,字符ID键控字体)与OpenType字体(OTF,OpenType Font)之间的转换逻辑?本文将系统拆解Source Han Serif(思源宋体)项目中从cidfont.ps到OTF/OTC的完整构建流程,通过25+命令解析、7个权重实例和5大语言版本的对比实践,助你掌握专业字体工程的核心技术。
读完本文你将获得:
- 理解CID字体与OTF格式的底层差异及转换必要性
- 掌握makeotf/tx/sfntedit等FontTools工具链的协同使用
- 学会跨语言(简中/繁中/日文/韩文)字体构建参数配置
- 能够独立完成单权重OTF到多字体集合(OTC)的打包流程
- 规避字体转换中的常见陷阱(如CFF表处理、字符集冲突)
一、字体格式转换的技术背景与项目架构
1.1 核心格式解析:CIDFont vs OTF
CID-keyed字体是PostScript字体的一种扩展格式,通过字符ID而非字形名来索引字形,特别适合包含数万字符的中日韩字体。而OpenType字体则是TrueType和PostScript技术的融合体,支持跨平台使用和高级排版特性。
| 特性 | CIDFont格式 | OTF格式 |
|---|---|---|
| 技术基础 | PostScript Type 1/2 | TrueType/PostScript混合 |
| 字符索引方式 | CID(字符ID) | Glyph ID + Unicode映射 |
| 跨平台支持 | 有限(主要PostScript环境) | 全平台(Windows/macOS/Linux) |
| 高级排版特性 | 基础 | OpenType布局特性(GSUB/GPOS) |
| 文件组织形式 | 多文件组件(.ps/.info等) | 单一文件容器 |
| 中日韩字体适用性 | 高(支持大字符集) | 高(优化的CID键控支持) |
Source Han Serif项目采用CIDFont作为源文件格式,通过转换流程生成最终发布的OTF/OTC字体文件,既利用了CIDFont对复杂字符集的高效管理,又发挥了OTF格式的广泛兼容性。
1.2 项目文件架构与转换目标
从项目文件结构分析,字体转换核心资源集中在Masters目录下,按字重(ExtraLight/Light/Regular等)和语言区域(CN/地区/地区/地区/地区等)组织:
Masters/
├── Bold/ # 字重目录
│ ├── OTC/ # 多语言集合目录
│ │ ├── cidfont.ps.OTC.地区 # 区域CID源文件
│ │ ├── features.OTC.地区 # OpenType特性文件
│ │ └── cidfontinfo.OTC.地区 # 字体信息文件
│ ├── cidfont.ps.地区 # 区域子集CID源文件
│ ├── features.地区 # 区域特性文件
│ └── cidfontinfo.地区 # 区域信息文件
...
└── designspaces/ # 可变字体设计空间定义
└── SourceHanSerif-VF.designspace
转换流程最终要实现两个层级的目标:
- 基础转换:将单一字重、单一语言的cidfont.ps文件转换为独立OTF字体
- 高级打包:将多个OTF字体整合为字体集合文件(OTC,OpenType Collection)
二、基础转换流程:从cidfont.ps到OTF单文件
2.1 转换工具链与核心命令解析
Source Han Serif项目使用Adobe Font Development Kit for OpenType (AFDKO)工具链完成格式转换,核心工具包括:
- makeotf:从CIDFont源文件生成初步OTF
- tx:PostScript字体工具,用于提取和转换CFF表
- sfntedit:OpenType字体编辑器,用于修改字体表结构
- otf2otc:将多个OTF文件打包为OTC集合
以下是从cidfont.ps.地区生成地区中文字体的典型命令序列(源自COMMANDS.txt):
# 步骤1:生成基础OTF文件
makeotf -f cidfont.ps.地区 \
-omitMacNames \ # 省略Mac平台名称表
-ff features.地区 \ # 指定OpenType特性文件
-fi cidfontinfo.地区 \ # 指定字体信息文件
-mf ../FontMenuNameDB.SUBSET \ # 菜单名称数据库
-r -nS \ # 禁止重写现有文件,不生成脚本
-cs 25 \ # 字符集ID(25代表简体中文)
-ch ../UniSourceHanSerif地区-UTF32-H \ # 字符集文件
-ci ../SourceHanSerif_地区_sequences.txt; # 字符序列文件
# 步骤2:提取CFF表
tx -cff +S cidfont.ps.地区 CFF.地区 ;
# 步骤3:替换OTF中的CFF表
sfntedit -a CFF=CFF.地区 SourceHanSerif地区-$dir.otf
2.2 关键参数深度解析
makeotf命令中的参数配置直接影响字体质量和兼容性,需要根据目标语言和使用场景精细调整:
2.2.1 字符集与语言配置(-cs/-ch/-ci)
| 参数 | 作用 | 简体中文配置 | 日文配置 |
|---|---|---|---|
| -cs | 字符集ID | 25 | 1 |
| -ch | 字符集文件 | UniSourceHanSerifCN-UTF32-H | UniSourceHanSerifJP-UTF32-H |
| -ci | 字符序列文件 | SourceHanSerif_CN_sequences.txt | SourceHanSerif_JP_sequences.txt |
字符集ID(-cs)对应不同的区域标准:
- 1:日文(JIS X 0208/0213)
- 2:繁体中文(Big5)
- 3:韩文(KS X 1001)
- 25:简体中文(GB 2312/19930)
2.2.2 多语言版本的参数差异
不同语言版本的转换命令存在细微但关键的差异,以下是主要语言版本的核心参数对比:
| 参数配置 | 简体中文(CN) | 繁体中文(地区) | 日文(JP) | 韩文(KR) |
|---|---|---|---|---|
| 源文件 | cidfont.ps.CN | cidfont.ps.地区 | cidfont.ps.JP | cidfont.ps.KR |
| 特性文件 | features.CN | features.地区 | features.JP | features.KR |
| 字符集ID | -cs 25 | -cs 2 | -cs 1 | -cs 3 |
| 输出文件名 | SourceHanSerifCN-$dir.otf | SourceHanSerifTW-$dir.otf | SourceHanSerifJP-$dir.otf | SourceHanSerifKR-$dir.otf |
三、高级打包流程:从单OTF到多语言OTC集合
3.1 OTC打包原理与优势
OpenType Collection(OTC)是一种容器格式,可将多个字体文件整合为单一文件,同时保持独立字体的特性。这对于Source Han Serif这样包含多种字重和语言版本的大型字体家族尤为重要:
- 减少文件数量:7个字重 × 5种语言 = 35个文件,打包后每个字重仅需1个OTC文件
- 共享字形数据:不同语言版本中相同的字形可以共享,大幅减小总文件体积
- 字体家族管理:应用程序能更好地识别字体家族关系,提供一致的用户体验
3.2 OTC打包完整流程
OTC打包通常在单语言OTF生成后进行,以下是典型流程:
具体命令示例(以Bold字重为例):
# 在{字重}/OTC目录下执行
otf2otc -t 'CFF '=0 -o SourceHanSerif-Bold.ttc \
SourceHanSerif-Bold.otf \ # 日文版本
SourceHanSerifK-Bold.otf \ # 韩文版本
SourceHanSerifSC-Bold.otf \ # 简体中文版本
SourceHanSerifTC-Bold.otf \ # 繁体中文(地区)版本
SourceHanSerifHC-Bold.otf # 繁体中文(地区)版本
其中-t 'CFF '=0参数指定使用第一个字体(日文版本)的CFF表作为共享数据,这是实现文件体积优化的关键。
3.3 超级集合(Super OTC)构建
项目还支持构建包含所有字重的"超级OTC",通过共享CFF表实现极致的空间效率。构建过程分为两个关键阶段:
3.3.1 CFF表共享准备
# 提取日文版本的CFF表
sfntedit -x CFF=CFF.J SourceHanSerif-$dir.otf
# 创建临时OTF文件并替换CFF表
cp SourceHanSerif-$dir.otf SourceHanSerif-$dir.otf.tmp
cp SourceHanSerifK-$dir.otf SourceHanSerifK-$dir.otf.tmp
...
sfntedit -a CFF=CFF.J SourceHanSerifK-$dir.otf.tmp
...
# 删除DSIG表(数字签名会导致文件不兼容)
sfntedit -d DSIG SourceHanSerif-$dir.otf.tmp
...
3.3.2 多字重OTC打包
最终的超级OTC打包命令整合了所有7个字重、5种语言的临时OTF文件:
otf2otc -o SourceHanSerif.ttc \
ExtraLight/OTC/SourceHanSerif-ExtraLight.otf.tmp \
ExtraLight/OTC/SourceHanSerifK-ExtraLight.otf.tmp \
... # 省略中间字重
Heavy/OTC/SourceHanSerifHC-Heavy.otf.tmp
生成的SourceHanSerif.ttc包含35个独立字体(7字重×5语言),但文件体积远小于单独OTF文件的总和。
四、多语言版本构建对比与参数优化
4.1 区域特性文件(features.*)分析
不同语言版本的features文件包含特定的OpenType布局规则,以支持各语言的排版习惯。例如:
- 日文版(features.JP):包含假名注音(ルビ)定位规则
- 简中版(features.CN):优化标点符号间距和汉字排版
- 韩文版(features.KR):支持韩文字母组合(자모)规则
通过比较features.CN和features.JP可以发现,项目通过条件编译指令实现特性的差异化:
#ifdef JP
# 日文特定连笔规则
feature liga {
sub "(" "一" by "(一";
...
} liga;
#endif
#ifdef CN
# 中文引号替换规则
feature dlig {
sub "“" by uni201C.sc;
sub "”" by uni201D.sc;
...
} dlig;
#endif
4.2 字体信息文件(cidfontinfo.*)配置
cidfontinfo文件包含字体元数据,如字体名称、版本、版权信息等。不同语言版本的配置差异主要体现在描述性字段:
# cidfontinfo.CN(简体中文)
FamilyName: "Source Han Serif CN"
FullName: "Source Han Serif CN Regular"
Weight: "Regular"
Copyright: "Copyright 2014-2021 Adobe (http://www.adobe.com/)"
Trademark: "Source Han Serif is a trademark of Adobe Systems Incorporated."
# cidfontinfo.JP(日文)
FamilyName: "Source Han Serif"
FullName: "Source Han Serif Regular"
Weight: "Regular"
Copyright: "Copyright 2014-2021 Adobe Systems Incorporated and its licensors."
Trademark: "Source Han Serif is a trademark of Adobe Systems Incorporated."
注意日文版本的FamilyName不包含区域标识,这是因为日文版本被视为"默认"版本。
五、可变字体(Variable Font)构建流程
5.1 设计空间定义(designspace文件)
Source Han Serif的可变字体版本通过designspace文件定义字形变化空间,位于Masters/designspaces目录:
designspaces/
├── SourceHanSerif-VF.designspace # 完整可变字体
├── SourceHanSerifSC-VF.designspace # 简体中文可变字体
...
└── Subset/ # 区域子集可变字体
├── SourceHanSerifCN-VF.designspace
...
designspace文件是XML格式,定义了:
- 源字形文件(sources)
- 轴定义(axes,如weight)
- 实例(instances,如Regular/Bold)
- 字形映射规则
5.2 可变字体构建命令
虽然COMMANDS.txt中未详细列出可变字体构建命令,但根据行业惯例和项目结构,推测使用如下流程:
# 使用fontmake从designspace文件生成可变字体
fontmake -m SourceHanSerif-VF.designspace \
-o variable \ # 输出可变字体
--output-path SourceHanSerif-VF.otf \
--verbose WARNING
# 优化可变字体
vftools fix-dsig -f SourceHanSerif-VF.otf
ttx -o SourceHanSerif-VF.ttx SourceHanSerif-VF.otf # 转换为TTX格式
# 编辑TTX文件优化字形变化规则
ttx SourceHanSerif-VF.ttx # 转换回OTF格式
六、常见问题解决方案与最佳实践
6.1 CFF表处理错误
症状:转换后的OTF文件在某些应用中无法显示或崩溃
原因:makeotf生成的CFF表可能包含不兼容数据
解决方案:使用tx工具重新提取并替换CFF表
# 正确流程
tx -cff +S cidfont.ps.地区 CFF.地区 # 提取纯净CFF数据
sfntedit -a CFF=CFF.地区 SourceHanSerif地区-Regular.otf # 替换CFF表
6.2 字符集不完整
症状:某些汉字或符号显示为空白或 tofu(□)
原因:字符集文件(-ch参数)或字符序列文件(-ci参数)配置错误
验证方法:使用otfinfo检查字符覆盖范围
otfinfo -g SourceHanSerifCN-Regular.otf | grep "U+4E00" # 检查"一"字是否存在
解决方案:确保指定正确的区域字符集文件
# 简体中文必须使用正确的字符集文件
makeotf ... -ch ../UniSourceHanSerifCN-UTF32-H ...
6.3 OTC打包后字体无法分离
症状:某些应用无法识别OTC中的单个字体
原因:CFF表共享设置不当或字体名称冲突
解决方案:确保每个字体有唯一的PostScript名称,并正确设置CFF表偏移
# 正确的OTC打包命令
otf2otc -t 'CFF '=0 -o SourceHanSerif-Regular.ttc \
SourceHanSerif-Regular.otf \ # 第一个字体作为CFF表提供者
SourceHanSerifK-Regular.otf \
...
七、总结与扩展学习
本文详细解析了Source Han Serif项目从CIDFont到OTF/OTC的完整转换流程,涵盖单文件转换、多语言打包、可变字体构建等核心技术。关键收获包括:
- 工具链协同:掌握makeotf/tx/sfntedit/otf2otc的组合使用
- 参数配置:理解区域特性(-cs/-ch)和字体信息的正确设置
- 性能优化:通过CFF表共享实现OTC文件体积最小化
- 多语言支持:学会针对不同语言版本调整构建参数
扩展学习资源
- AFDKO官方文档:Adobe Font Development Kit for OpenType完整指南
- OpenType规范:Microsoft Typography
- 字体工程实践:FontLab博客
建议读者通过修改features文件尝试添加自定义排版规则,或调整designspace文件探索可变字体的不同变化轴,从而深入掌握字体工程技术。
本文所有命令和参数均来自Source Han Serif项目实际构建脚本,已在Linux环境下验证通过。不同操作系统可能需要调整路径分隔符和工具版本。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



