# fonts/ —— 模板库公共字体目录 本目录是**中国海洋大学 LaTeX 模板库唯一的一份字体来源**。仓库里十一个模板全部通过 根目录的 [`../fonts.tex`](../fonts.tex) 取字体,不再有任何模板自带字体、也不依赖 操作系统里装了什么字体。换一台机器、换一个操作系统(Windows / macOS / Linux / Overleaf),编译出来的样子都一样。 ``` fonts/ ├── ouc-serif/ OUC Serif 宋体(衬线正文) 2 个,9.7 MB ├── ouc-sans/ OUC Sans 黑体(无衬线标题) 2 个,7.0 MB ├── ouc-kai/ OUC Kai 楷体 2 个,7.0 MB ├── zhuque-fangsong/ Zhuque Fangsong 仿宋 1 个,8.4 MB ├── tex-gyre-termes/ TeX Gyre Termes 西文 Times 等价 4 个,550 KB ├── cochineal/ Cochineal 西文 Minion 风格 4 个,920 KB ├── harmonyos-sans/ HarmonyOS Sans 鸿蒙(中英各一档) 6 个,16 MB └── fontawesome/ FontAwesome 简历模板的图标符号 1 个,130 KB ``` 合计约 **50 MB**(改造前是 141 MB:幻灯片 49 MB + 科技报告 92 MB 各自带一份, 外加两套重复的字体。现在全库只有这一份,省掉 65%)。 --- ## 一、为什么要把字体打进仓库 原先七个模板是两种做法: | 做法 | 模板 | 问题 | |---|---|---| | 各自带一份字体 | `幻灯片/`(鸿蒙 18 个文件 49 MB)、`科技报告/`(鸿蒙 + 方正 5 款 92 MB) | 两份重复;字体版本一旦不同步,两个模板的样子就会不一致 | | 直接用系统字体 | 其余五个(SimSun / SimHei / FangSong / KaiTi / Times New Roman) | 换台机器(Linux、macOS、精简版 Windows、Overleaf)直接编不出来;而且这些字体**不允许随仓库分发** | 统一成一份公共字体后: - **编译结果可复现** —— 与操作系统、与是否装过某款字体无关。 - **授权干净** —— 全库不含任何商业字体,见第四节。 - **体积可控** —— 只保留实际用到的字重与字符集。 --- ## 二、各字体的来源与授权 全部为**开源或官方允许免费商用**的字体。逐项如下。 ### 1. OUC Serif / OUC Sans / OUC Kai —— 思源系列与霞鹜文楷的子集 | | 上游字体 | 上游作者 | 上游授权 | 字符集 | |---|---|---|---|---| | OUC Serif | 思源宋体 SC(Source Han Serif SC) | Adobe | SIL OFL 1.1 | GB2312,7555 字 | | OUC Sans | 思源黑体 SC(Source Han Sans SC) | Adobe | SIL OFL 1.1 | GB2312,7555 字 | | OUC Kai | 霞鹜文楷(LXGW WenKai) | LXGW | SIL OFL 1.1 | GB2312,7557 字 | > **为什么改名叫 OUC Serif / OUC Sans / OUC Kai?** > SIL OFL 1.1 第 3 条规定:修改版不得使用上游的 Reserved Font Name。 > 思源系列的 RFN 是 `Source`,霞鹜的 RFN 含 `LXGW`。裁剪字符集属于 > "修改版",因此必须改名,且不得暗示原作者为本仓库背书。 > 改名同时改了 **CFF 层**的 `fontNames` / `FamilyName` / `FullName` > —— 只改 name 表是不够的,PDF 里内嵌的字体名取的是 CFF 层。 > 字体 name 表的 13/14 号记录保留了完整 OFL 声明与"本字体为子集、 > 与上游作者无关"的免责说明。 **裁剪范围**:保留 GB2312 全集(6763 汉字)+ 常用标点 + 拉丁字母 + 希腊字母 + 数学符号,约 7555 个字符。**不保留** GBK 扩展区与生僻字。 > ⚠️ 如果将来正文要用 GB2312 之外的生僻字(例如某些人名、地名用字), > 会显示成空白或方框。此时需要重新生成子集,把该字加进去。 > 生成脚本见第七节。 ### 2. Zhuque Fangsong —— 朱雀仿宋 | | | |---|---| | 上游 | 朱雀仿宋(TrionesType / Zhuque Fangsong) | | 授权 | SIL OFL 1.1 | | 字符集 | 12882 字符,**GB2312 全集覆盖** | | 版本 | 0.212(technical preview) | 未做裁剪(原文件 8.4 MB 已经够小,且保留全集更安全)。 **只有常规一档,没有粗体** —— 需要粗体的地方请改用黑体或宋体。 ### 3. TeX Gyre Termes —— 西文 Times 等价字体 | | | |---|---| | 上游 | TeX Gyre Termes(GUST 字体项目) | | 授权 | GUST Font License(GPL + 字体嵌入例外) | | 特性 | 与 Times New Roman **逐字度量兼容** | 用它是为了保证中文模板里原有的西文断行、表格列宽、行内公式对齐不漂移。 实测同一段英文,Termes 与 Times New Roman 的逐词宽度差在 0.03pt 量级。 **全库默认西文字体就是 Termes**(`fonts.tex` 的 `\setmainfont`)。除简历外的 10 个模板都用它。 ### 3b. Cochineal —— 西文 Minion 风格(简历专用) | | | |---|---| | 上游 | Cochineal(Michael Sharpe,据 Minion 设计) | | 授权 | SIL OFL 1.1,可随仓库分发(`cochineal/OFL.txt`) | | 特性 | 笔画比 Times 饱满,与思源宋体灰度更接近 | **为什么加这一款**:中文用思源宋体(中等粗细),Termes 是 Times 的度量兼容替代, 笔画偏细偏紧,中英混排时西文那一段视觉上会「陷进去」。Cochineal 笔画更饱满。 **为什么只有简历用**:它的宽度与 Termes 只差 **1.9%**(225.42 vs 229.68pt @10pt), 断行位置基本不动,所以换过去风险最小。其余候选宽 2.2%~10.8%,会把全库的表格列宽 和断行推着变(数据见 `字体` 一节末尾的对照表)。 ⚠️ **不是全局生效**。`fonts.tex` 里只做了声明: ```latex \oucUseCochineal % 调它才切;不调就还是 Termes ``` 目前只有 `简历/awesome-source-cv.cls` 在 `\AtBeginDocument` 里调用。 **度量对照**(10pt 下同一句英文的排印宽度,供将来换字体时参考): | 字体 | 样句宽 | 相对 Termes | x 高 | cap 高 | |---|---|---|---|---| | Termes | 229.68pt | 100.0% | 0.450 | 0.662 | | **Cochineal** | **225.42pt** | **98.1%** | 0.433 | 0.649 | | Libertinus Serif | 234.62pt | 102.2% | 0.433 | 0.649 | | XCharter | 246.69pt | 107.4% | 0.481 | 0.671 | | TeX Gyre Pagella | 254.40pt | 110.8% | 0.472 | 0.695 | ### 4. HarmonyOS Sans —— 鸿蒙字体 | | | |---|---| | 上游 | HarmonyOS Sans(华为) | | 授权 | 华为官方声明允许**免费商用**(随 HarmonyOS 开发者文档发布) | | 保留原因 | `幻灯片/` 与 `科技报告/` 原有观感就是鸿蒙,换成思源会明显改变这两个模板的视觉 | 只保留实际用到的 6 个文件:`HarmonyOS_Sans_{Regular,Bold}`(西文)、 `HarmonyOS_Sans_{Regular,Bold}_Italic`、`HarmonyOS_Sans_SC_{Regular,Bold}`(中文)。 原目录里的 Black / Light / Medium / Thin 等 12 个字重全库无人引用,已删除。 > ⚠️ 鸿蒙字体的文件名用**下划线**分隔(`HarmonyOS_Sans_SC_Regular.ttf`), > 不是 `族名-字重` 格式。所以在 fontspec 里不能写 `*-Regular` 通配, > 必须显式给完整文件名。 ### 5. FontAwesome —— 简历模板的图标符号 | | | |---|---| | 上游 | Font Awesome 4.x(原项目 Fonticons, Inc.) | | 授权 | SIL OFL 1.1(字体本身)/ CC BY 4.0(图标设计) | | 保留原因 | `简历/` 模板的联系方式行用 `\smartphone` / `\email` / `\address` 等命令,每个前缀都要印一个图标 | | 版本 | 与 TeX Live 2022 内置的那份逐字节相同(md5 `9f6ff7d7cfd6f76d7a9c242bdd48c144`) | 只有 `FontAwesome.otf` 一个文件(130 KB)。TeX Live 里本来就带这份字体,之所以 还是拷进仓库,是为了守住「字体单一来源」这个约定 —— 否则 `简历/` 就成了唯一一个 字体来自 TeX Live 安装的模板,换一台没装 fontawesome 宏包用字体的机器就编不出来。 > ⚠️ 引用它的不是 `fonts.tex`,而是 `简历/fontawesome.sty` 里的 > `\newfontfamily{\FA}[Path=../fonts/fontawesome/,Extension=.otf]{FontAwesome}`。 > 原因:`\FA` 是在 `\RequirePackage{fontawesome}` 时就被定义好的(早于 `.cls` > 后面所有语句),`awesome-source-cv.cls` 里再声明一次会报 `Font \FA already > defined`;所以只能改 `fontawesome.sty` 本体。 --- ## 三、字体是怎么被调用的 所有模板都只做一件事:在导言区 `\input{../fonts.tex}`(幻灯片与科技报告因为 目录层级不同,路径略作调整)。`fonts.tex` 负责: 1. 加载 fontspec / xeCJK; 2. 注册默认族与 `\songti` / `\heiti` / `\kaiti` / `\fangsong` / `\kaishu` / `\tnr` / `\tnrb` / `\hm` / `\hmlatin`; 3. 把 `×` `—` `□` `○` `√` 等「长得像西文、其实该走中文」的符号 归入 CJK 字符类(详见该文件的注释); 4. 提供 `\ouclinespread` 行距工具。 各模板自己**不再写任何** `\setCJKmainfont` / `\setmainfont`。 ### ⚠️ 三个容易踩的坑(都写在 fonts.tex 的注释里了) 1. **必须保留 `fontset=none`。** `\documentclass[UTF8,fontset=none]{ctexart}`。不写的话 ctex 会先按系统字体 配一套(Microsoft YaHei / SimSun / FangSong),再被覆盖,既浪费又有平台 依赖。`试卷/ouckey.sty` 因为继承 ctexart 默认 fontset,所以 fonts.tex 里 用 `\setCJKfamilyfont` + `\def` 而不是 `\newCJKfontfamily`—— 后者是 LaTeX3 的 `\NewDocumentCommand`,命令已存在时会报 `! LaTeX3 Error: Control sequence \songti already defined.` 并中断编译。 2. **`Path=` 是相对编译时的工作目录,不是相对 .sty 文件。** 模板目录下 `xelatex xxx.tex`,所以写 `../fonts/...`。 幻灯片与科技报告的主题文件虽然在子目录里,路径仍按工作目录写 `../fonts/`。 3. **`Path=` 不能写宏。** 它是 fontspec 的参数,必须给字面字符串。 --- ## 四、授权合规自查 - [x] 全库不含方正、SimSun、SimHei、KaiTi、FangSong、Times New Roman、 Microsoft YaHei 等不可分发的商业字体。 - [x] 思源系列与霞鹜文楷的**子集**已改名,符合 OFL 1.1 §3(Reserved Font Name)。 - [x] 子集保留了 OFL 全文(name 表 13/14 号记录),符合 OFL 1.1 §1(随附授权)。 - [x] 改名后的 name 表写明"本字体为子集,与上游作者无关",未暗示背书。 - [x] TeX Gyre Termes 为 GUST Font License,允许随文档分发。 - [x] HarmonyOS Sans 为华为官方允许免费商用。 - [x] 本目录的 [LICENSE](LICENSE) 汇总了各字体的授权原文出处。 > **注意**:OFL 要求"以 OFL 字体排版产生的文档"不受 OFL 约束 > (§5 文档本身不因此被感染)。所以用本模板编译出来的论文、报告、 > 试卷,版权完全属于作者,不受这些字体授权的影响。 --- ## 五、体积 ``` 改造前(字体分散在各模板目录) 幻灯片/fonts/ 49 MB 科技报告/font/ 92 MB 合计 141 MB 改造后(统一到 fonts/) ouc-serif 9.7 MB ouc-sans 7.0 MB ouc-kai 7.0 MB zhuque-fangsong 8.4 MB tex-gyre-termes 0.55 MB cochineal 0.92 MB harmonyos-sans 16.4 MB 合计 50 MB (省 65%) ``` --- ## 六、当前各模板的字体对应关系 | 模板 | 中文正文 | 中文标题/强调 | 西文 | |---|---|---|---| | `试卷归档封面/` | OUC Serif | OUC Sans | TeX Gyre Termes | | `年度考核登记表/` | OUC Serif | OUC Sans | TeX Gyre Termes | | `劳务发放说明表/` | OUC Serif | OUC Sans | TeX Gyre Termes | | `课程执行大纲/` | OUC Serif | OUC Sans | TeX Gyre Termes | | `试卷/` | OUC Serif / OUC Kai | OUC Sans | TeX Gyre Termes | | `简历/` | OUC Serif / OUC Kai | OUC Serif Bold | **Cochineal** | | `幻灯片/` | HarmonyOS Sans SC | HarmonyOS Sans SC Bold | HarmonyOS Sans | | `科技报告/` | OUC Serif | OUC Serif Bold / OUC Kai | HarmonyOS Sans | 「改造前」用的是:SimSun / SimHei / KaiTi / FangSong / Times New Roman(前五个模板), 鸿蒙 + 方正书宋/小标宋/楷体/仿宋/中等线(科技报告)。 --- ## 七、如何重新生成子集 如果需要把 GB2312 之外的字加进来,或上游字体发了新版: ```bash # 依赖:pip install fonttools python -c "import fontTools; print(fontTools.version)" # 1) 裁剪(name_IDs 必须给 '*',否则会丢掉 OFL 声明的 13/14 号记录) python - <<'PY' from fontTools import subset opts = subset.Options() opts.name_IDs = ['*'] # 关键:默认只取 0..6,会丢授权声明 opts.name_languages = ['*'] opts.notdef_outline = True opts.recalc_bounds = True opts.layout_features = ['*'] font = subset.load_font('上游字体.otf', opts) subsetter = subset.Subsetter(options=opts) subsetter.populate(text=open('keep_gb2312.txt', encoding='utf-8').read()) subsetter.subset(font) subset.save_font(font, '裁剪后.otf', opts) PY # 2) 改 CFF 层名字(只改 name 表不够!PDF 内嵌名取的是 CFF 层) python - <<'PY' from fontTools.ttLib import TTFont f = TTFont('裁剪后.otf') cff = f['CFF '].cff cff.fontNames[0] = 'OUCSerif-Regular' td = cff.topDictIndex[0] td.FamilyName = 'OUC Serif' td.FullName = 'OUC Serif Regular' # name 表同步改,并补 13/14 号授权记录与免责声明 f.save('OUCSerif-Regular.otf') PY ``` 改完务必验证 PDF 里内嵌的确实是新名字: ```python import pymupdf d = pymupdf.open('输出.pdf') print({f[3] for p in d for f in p.get_fonts()}) # 期望看到 OUCSerif-Regular / OUCSans-Regular,而不是 SourceHanSerifSC ``` --- ## 八、字体清单速查 | 文件 | 内部族名 | 字符数 | 大小 | |---|---|---|---| | `ouc-serif/OUCSerif-Regular.otf` | OUC Serif | 7555 | 4.6 MB | | `ouc-serif/OUCSerif-Bold.otf` | OUC Serif | 7555 | 4.8 MB | | `ouc-sans/OUCSans-Regular.otf` | OUC Sans | 7555 | 3.4 MB | | `ouc-sans/OUCSans-Bold.otf` | OUC Sans | 7555 | 3.4 MB | | `ouc-kai/OUCKai-Regular.ttf` | OUC Kai | 7557 | 3.4 MB | | `ouc-kai/OUCKai-Bold.ttf` | OUC Kai | 7557 | 3.4 MB | | `zhuque-fangsong/ZhuqueFangsong-Regular.ttf` | Zhuque Fangsong | 12882 | 8.4 MB | | `tex-gyre-termes/texgyretermes-regular.otf` | TeX Gyre Termes | 1053 | 141 KB | | `tex-gyre-termes/texgyretermes-bold.otf` | TeX Gyre Termes | 1053 | 139 KB | | `tex-gyre-termes/texgyretermes-italic.otf` | TeX Gyre Termes | 1053 | 141 KB | | `tex-gyre-termes/texgyretermes-bolditalic.otf` | TeX Gyre Termes | 1053 | 144 KB | | `cochineal/Cochineal-Roman.otf` | Cochineal | 1237 | 227 KB | | `cochineal/Cochineal-Bold.otf` | Cochineal | 1255 | 228 KB | | `cochineal/Cochineal-Italic.otf` | Cochineal | 1186 | 228 KB | | `cochineal/Cochineal-BoldItalic.otf` | Cochineal | 1198 | 219 KB | | `harmonyos-sans/HarmonyOS_Sans_Regular.ttf` | HarmonyOS Sans | 874 | 147 KB | | `harmonyos-sans/HarmonyOS_Sans_Bold.ttf` | HarmonyOS Sans | 874 | 146 KB | | `harmonyos-sans/HarmonyOS_Sans_Regular_Italic.ttf` | HarmonyOS Sans | 807 | 141 KB | | `harmonyos-sans/HarmonyOS_Sans_Bold_Italic.ttf` | HarmonyOS Sans | 807 | 141 KB | | `harmonyos-sans/HarmonyOS_Sans_SC_Regular.ttf` | HarmonyOS Sans SC | 29063 | 8.3 MB | | `harmonyos-sans/HarmonyOS_Sans_SC_Bold.ttf` | HarmonyOS Sans SC | 29063 | 8.2 MB |