字体统一:建公共字体目录,全部改用可免费商用字体 #6

Closed
opened 2026-10-26 15:34:32 +00:00 by laoyang · 2 comments
Owner

现象 / 诉求

当前 7 个模板的字体处理分成两套互不相干的做法:

  • 自带字体:幻灯片/(fonts/ 49MB,鸿蒙 Sans 18 个字重)、科技报告/(font/ 92MB,鸿蒙 32MB + 方正 60MB),用 Path= 指相对路径加载。
  • 调系统字体:试卷/、试卷归档封面/、年度考核登记表/、劳务发放说明表/、课程执行大纲/,全部 \documentclass[UTF8,fontset=none]{ctexart} + 硬编码 SimSun/SimHei/KaiTi/FangSong/Times New Roman。

由此产生三个问题:

  1. 换机器就编译不过。方案 B 的五个模板在 Linux 服务器或 macOS 上找不到 SimSun/SimHei/FangSong,直接报错。
  2. 同一份文档在不同机器上排版不一致。系统字体版本不同、缺字体时的降级路径不同,行宽与断行会漂。
  3. 仓库内混有商业字体。科技报告/font/ 下 5 个方正字体(书宋/小标宋/楷体/仿宋/中等线)共 60MB 是方正商业字体,以 Apache 2.0 随仓库分发属于授权越界;五个方案 B 模板依赖的 SimSun/SimHei/FangSong 与 Times New Roman 同样是商业字体(微软 / 中易 / Monotype),不能随模板分发。

目标:模板库内只用可免费商用的字体,全部随仓库分发,所有人编译结果一致。

需求拆解

1. 建公共字体目录

在仓库根建 fonts/(与 7 个模板目录平级,不在任何模板目录内部),作为唯一字体来源。各模板通过相对路径 ../fonts/ 引用。

字体集合取最小可用集——只保留实际排版需要的字重,不做全家桶。判定标准:每引入一个字重,必须在某个模板的源码里能找到实际调用点。

2. 清退全部商业字体

现有字体 位置 授权状况 处置
方正书宋/小标宋/楷体/仿宋/中等线 科技报告/font/ 方正商业字体 删除,换开源替代
SimSun / SimHei 五个方案 B 模板 微软+中易,系统字体,不可分发 不再引用,换开源替代
FangSong 年度考核登记表等 中易,不可分发 不再引用,换开源替代
KaiTi 试卷/ 中易,不可分发 不再引用,换开源替代
Times New Roman 五个方案 B 模板 + 科技报告 Monotype 商业字体 不再引用,换度量兼容开源替代
HarmonyOS Sans 幻灯片、科技报告 华为官方声明可免费商用 保留

替代字体一律选 SIL OFL / GUST / Apache 等明确允许再分发的许可证,并在 fonts/ 下附 LICENSE 与来源说明。

3. 统一改接 + 全量重编译

七个模板全部改成只从 ../fonts/ 取字体,不再出现任何系统字体名。

改完逐个编译并逐页检查:

  • 编译零错误,页数与改前一致(或差异有明确解释)
  • 版式(行数、断行、页数)不发生非预期漂移
  • 字形本身可接受——若某替代字体在具体位置上明显难看(如伪粗过重、字面过大过小),记录下来单独调整

验收标准

  1. grep 全仓库源码,不再出现 SimSun / SimHei / KaiTi / FangSong / Times New Roman / 方正 等商业字体名。
  2. 七个模板的 .sty/.cls 中所有字体声明都指向 ../fonts/。
  3. fonts/ 下每个字体文件都有对应许可证说明,全部允许免费商用与再分发。
  4. 七个模板在本机全新克隆后零错误编译通过,PDF 内嵌字体全部来自 fonts/。
  5. 各模板 README 的「字体」章节更新为与实际一致。
## 现象 / 诉求 当前 7 个模板的字体处理分成两套互不相干的做法: - **自带字体**:`幻灯片/`(`fonts/` 49MB,鸿蒙 Sans 18 个字重)、`科技报告/`(`font/` 92MB,鸿蒙 32MB + 方正 60MB),用 `Path=` 指相对路径加载。 - **调系统字体**:`试卷/`、`试卷归档封面/`、`年度考核登记表/`、`劳务发放说明表/`、`课程执行大纲/`,全部 `\documentclass[UTF8,fontset=none]{ctexart}` + 硬编码 `SimSun`/`SimHei`/`KaiTi`/`FangSong`/`Times New Roman`。 由此产生三个问题: 1. **换机器就编译不过**。方案 B 的五个模板在 Linux 服务器或 macOS 上找不到 SimSun/SimHei/FangSong,直接报错。 2. **同一份文档在不同机器上排版不一致**。系统字体版本不同、缺字体时的降级路径不同,行宽与断行会漂。 3. **仓库内混有商业字体**。`科技报告/font/` 下 5 个方正字体(书宋/小标宋/楷体/仿宋/中等线)共 60MB 是方正商业字体,以 Apache 2.0 随仓库分发属于授权越界;五个方案 B 模板依赖的 SimSun/SimHei/FangSong 与 Times New Roman 同样是商业字体(微软 / 中易 / Monotype),不能随模板分发。 目标:**模板库内只用可免费商用的字体,全部随仓库分发,所有人编译结果一致**。 ## 需求拆解 ### 1. 建公共字体目录 在仓库根建 `fonts/`(与 7 个模板目录平级,不在任何模板目录内部),作为**唯一**字体来源。各模板通过相对路径 `../fonts/` 引用。 字体集合取**最小可用集**——只保留实际排版需要的字重,不做全家桶。判定标准:每引入一个字重,必须在某个模板的源码里能找到实际调用点。 ### 2. 清退全部商业字体 | 现有字体 | 位置 | 授权状况 | 处置 | |---|---|---|---| | 方正书宋/小标宋/楷体/仿宋/中等线 | `科技报告/font/` | 方正商业字体 | **删除**,换开源替代 | | SimSun / SimHei | 五个方案 B 模板 | 微软+中易,系统字体,不可分发 | **不再引用**,换开源替代 | | FangSong | 年度考核登记表等 | 中易,不可分发 | **不再引用**,换开源替代 | | KaiTi | `试卷/` | 中易,不可分发 | **不再引用**,换开源替代 | | Times New Roman | 五个方案 B 模板 + 科技报告 | Monotype 商业字体 | **不再引用**,换度量兼容开源替代 | | HarmonyOS Sans | 幻灯片、科技报告 | 华为官方声明可免费商用 | **保留** | 替代字体一律选 SIL OFL / GUST / Apache 等明确允许再分发的许可证,并在 `fonts/` 下附 LICENSE 与来源说明。 ### 3. 统一改接 + 全量重编译 七个模板全部改成只从 `../fonts/` 取字体,不再出现任何系统字体名。 改完逐个编译并逐页检查: - 编译零错误,页数与改前一致(或差异有明确解释) - 版式(行数、断行、页数)不发生非预期漂移 - 字形本身可接受——若某替代字体在具体位置上明显难看(如伪粗过重、字面过大过小),记录下来单独调整 ## 验收标准 1. `grep` 全仓库源码,不再出现 `SimSun` / `SimHei` / `KaiTi` / `FangSong` / `Times New Roman` / `方正` 等商业字体名。 2. 七个模板的 `.sty`/`.cls` 中所有字体声明都指向 `../fonts/`。 3. `fonts/` 下每个字体文件都有对应许可证说明,全部允许免费商用与再分发。 4. 七个模板在本机全新克隆后零错误编译通过,PDF 内嵌字体全部来自 `fonts/`。 5. 各模板 README 的「字体」章节更新为与实际一致。
Author
Owner

收尾核对中新发现并已修复:中文斜体(\textit)失效

在做最后的「全库字体是否还有不合适的地方」核对时,发现了一处回归,不在原需求描述里,但属于同一件事(字体接入),一并修掉。

现象

科技报告 编译报 4 条:

LaTeX Font Warning: Font shape `TU/OUCSerif(0)/m/it' undefined
(Font)              using `TU/OUCSerif(0)/m/n' instead on input line 56.
LaTeX Font Warning: Font shape `TU/OUCSerif(0)/b/it' undefined

report.tex 里「斜体的字体是……就像这样:\textit{这里是中文斜体}」这句,中文斜体实际被静默替换成常规体——印出来根本看不出是斜体。\textbf{\textit{粗体斜体}} 同理,粗斜体退化成只有粗体。

根因

中文没有真正的斜体字形,中文排版惯例是「楷体代斜、仿宋代粗斜」。改造前的 科技报告/cls/font.cls 本来就是这么配的:

\setCJKmainfont[
  BoldFont=fangzhengxiaobiaosong_GBK.TTF,
  ItalicFont=fangzhengkaiti_GBK.TTF,          ← 斜体=楷体
  BoldItalicFont=fangzhengfangsong_GBK.TTF,   ← 粗斜=仿宋
]{fangzhengshusong_GBK.TTF}

我改造时只写了 UprightFont + BoldFont 两档,把 ItalicFont / BoldItalicFont 丢了,于是斜体无处可落,xeCJK 就按 undefined 处理。

修复

在 fonts.tex 的 \setCJKmainfont 上补回这两档,语义与原版一致(楷体 → OUC Kai,仿宋 → Zhuque Fangsong):

\setCJKmainfont{OUCSerif}[
  Extension   = .otf,
  Path        = ../fonts/ouc-serif/,
  UprightFont = *-Regular,
  BoldFont    = *-Bold,
  ItalicFont  = OUCKai-Regular,
  ItalicFeatures = {Extension=.ttf, Path=../fonts/ouc-kai/,
                    UprightFont=*-Regular, BoldFont=*-Bold},
  BoldItalicFont = ZhuqueFangsong-Regular,
  BoldItalicFeatures = {Extension=.ttf, Path=../fonts/zhuque-fangsong/,
                        UprightFont=*-Regular},
]

有个坑记一下:各档位的字体在不同目录,不能共用主选项的 Path/Extension,必须在该档位的 *Features 里单独写一套。否则 fontspec 会拿 ../fonts/ouc-serif/ 去拼 OUCKai-Regular.ttf,报 The font "OUCKai-Regular" cannot be found。

验证

  • 编译后 TU/OUCSerif(0)/m/it、/b/it 两条 undefined 警告消失
  • 解压 PDF 流确认斜体真的落在 OUCKai-Regular、粗斜落在 ZhuqueFangsong-Regular(不是被替换成常规体)
  • 剩余 2 条 TU/OUCSerif(0)/m/sc 警告是小型大写字母(\textsc),中文字体本就没有该字形,改造前也有,不属于本次范围

顺带修掉的演示文字

科技报告/report.tex 的「字体」一节是印在 PDF 上的说明正文,原来还写着「字体在 font 文件夹中」「方正小标宋」「方正楷体」等旧描述,与实际不符,已改为思源宋体/霞鹜文楷/朱雀仿宋/思源黑体,并注明「全部开源可商用,不使用正方正、微软雅黑等商业字体」。

## 收尾核对中新发现并已修复:中文斜体(`\textit`)失效 在做最后的「全库字体是否还有不合适的地方」核对时,发现了一处**回归**,不在原需求描述里,但属于同一件事(字体接入),一并修掉。 ### 现象 `科技报告` 编译报 4 条: ``` LaTeX Font Warning: Font shape `TU/OUCSerif(0)/m/it' undefined (Font) using `TU/OUCSerif(0)/m/n' instead on input line 56. LaTeX Font Warning: Font shape `TU/OUCSerif(0)/b/it' undefined ``` `report.tex` 里「斜体的字体是……就像这样:`\textit{这里是中文斜体}`」这句,中文斜体实际被**静默替换成常规体**——印出来根本看不出是斜体。`\textbf{\textit{粗体斜体}}` 同理,粗斜体退化成只有粗体。 ### 根因 中文没有真正的斜体字形,中文排版惯例是「楷体代斜、仿宋代粗斜」。改造前的 `科技报告/cls/font.cls` 本来就是这么配的: ```latex \setCJKmainfont[ BoldFont=fangzhengxiaobiaosong_GBK.TTF, ItalicFont=fangzhengkaiti_GBK.TTF, ← 斜体=楷体 BoldItalicFont=fangzhengfangsong_GBK.TTF, ← 粗斜=仿宋 ]{fangzhengshusong_GBK.TTF} ``` 我改造时只写了 `UprightFont` + `BoldFont` 两档,把 `ItalicFont` / `BoldItalicFont` 丢了,于是斜体无处可落,xeCJK 就按 undefined 处理。 ### 修复 在 `fonts.tex` 的 `\setCJKmainfont` 上补回这两档,语义与原版一致(楷体 → OUC Kai,仿宋 → Zhuque Fangsong): ```latex \setCJKmainfont{OUCSerif}[ Extension = .otf, Path = ../fonts/ouc-serif/, UprightFont = *-Regular, BoldFont = *-Bold, ItalicFont = OUCKai-Regular, ItalicFeatures = {Extension=.ttf, Path=../fonts/ouc-kai/, UprightFont=*-Regular, BoldFont=*-Bold}, BoldItalicFont = ZhuqueFangsong-Regular, BoldItalicFeatures = {Extension=.ttf, Path=../fonts/zhuque-fangsong/, UprightFont=*-Regular}, ] ``` 有个坑记一下:各档位的字体在**不同目录**,不能共用主选项的 `Path`/`Extension`,必须在该档位的 `*Features` 里单独写一套。否则 fontspec 会拿 `../fonts/ouc-serif/` 去拼 `OUCKai-Regular.ttf`,报 `The font "OUCKai-Regular" cannot be found`。 ### 验证 - 编译后 `TU/OUCSerif(0)/m/it`、`/b/it` 两条 undefined 警告消失 - 解压 PDF 流确认斜体真的落在 `OUCKai-Regular`、粗斜落在 `ZhuqueFangsong-Regular`(不是被替换成常规体) - 剩余 2 条 `TU/OUCSerif(0)/m/sc` 警告是**小型大写字母**(`\textsc`),中文字体本就没有该字形,改造前也有,不属于本次范围 ### 顺带修掉的演示文字 `科技报告/report.tex` 的「字体」一节是**印在 PDF 上的说明正文**,原来还写着「字体在 font 文件夹中」「方正小标宋」「方正楷体」等旧描述,与实际不符,已改为思源宋体/霞鹜文楷/朱雀仿宋/思源黑体,并注明「全部开源可商用,不使用正方正、微软雅黑等商业字体」。
Author
Owner

完成

提交 8aa9797,已推送 main。

最终结构

ouc_latex_template/
├── fonts/              ← 49MB,全库唯一一份
│   ├── ouc-serif/          宋体(思源宋体 SC 子集)
│   ├── ouc-sans/           黑体(思源黑体 SC 子集)
│   ├── ouc-kai/            楷体(霞鹜文楷子集)
│   ├── zhuque-fangsong/    仿宋(朱雀仿宋)
│   ├── tex-gyre-termes/    西文(Times 度量兼容)
│   ├── harmonyos-sans/     幻灯片/科技报告主字体
│   ├── README.md           来源、字符集、子集重建方法
│   └── LICENSE             逐字体授权原文
└── fonts.tex           ← 唯一允许声明字体的地方

幻灯片/fonts/(18 个文件 49MB)与 科技报告/font/(92MB,含 5 款方正)已删除。
字体总体积 141MB → 49MB。

七个模板的接入方式

全部 \input{../fonts.tex},各自只保留"哪一族当默认"的选择,字体文件路径一律指向 ../fonts/。
试卷/oucexam.sty、试卷/ouckey.sty、课程执行大纲/ouccourse.sty、试卷归档封面/oucksfm.sty、
年度考核登记表/ouckhtb.sty、劳务发放说明表/ouclw.sty、幻灯片/theme/beamerfontthemeOUCSlide.sty、
科技报告/cls/font.cls —— 全部改完,\sunfont / \fzss / \ccfang 这类旧命令名保留,调用点零改动。

全量重编结果

模板 页数 错误 Overfull Underfull 缺字
试卷归档封面 1 0 0 0 0
年度考核登记表 2 0 0 0 0
劳务发放说明表 1 0 0 0 0
课程执行大纲 5 0 1(6.39pt) 0 0
试卷题型示例 6 0 0 0 0
参考答案 3 0 1(0.2071pt) 0 0
幻灯片 30 0 0 1 0
科技报告 10 0 0 1 0

两条 Overfull、两条 Underfull、两条 Font shape pcr undefined、两条 Font shape sc undefined
全部经改造前版本对照确认是原有问题(改造后反而是减少的,科技报告 Underfull 从 2 条降到 1 条)。

与改造前的逐行 A/B 对照

导出 HEAD 版本单独编译作为基准,逐页逐行取 (页码, 文本, x, y) 比对:

  • 幻灯片 30 页 362 行逐行完全一致,零漂移 —— 最强的等价性证明
  • 年度考核登记表 / 劳务发放说明表 / 试卷题型示例 / 参考答案 —— 全文字符完全相同
  • 课程执行大纲 —— 仅 2 处断字连字符(through-/through、process-/processing),词本身未变
  • 科技报告 —— 差异全部来自「字体」演示章节的说明文字改写(原文写着方正系列,已改为新字体名)

字符集覆盖

扫描全库正文(剔除注释)857 个非 ASCII 字符:

  • OUC Serif / Sans / Kai(含粗体)缺失 0
  • 朱雀仿宋缺全角「+」,该字符只出现在注释里,不参与排版
  • 鸿蒙 SC 缺失 0

顺带修的

  • 中文斜体 \textit 失效(漏配 ItalicFont/BoldItalicFont)—— 已补,实测落在 OUCKai-Regular
  • 科技报告/report.tex 的字体演示正文还在写「方正小标宋」等旧名 —— 已改为思源宋体/霞鹜文楷/朱雀仿宋/思源黑体
  • 试卷/_bak/ 备份目录(含旧 setmainfont{SimSun})—— 已删

验收页面:.workbuddy/字体总览/index.html

## 完成 提交 `8aa9797`,已推送 main。 ### 最终结构 ``` ouc_latex_template/ ├── fonts/ ← 49MB,全库唯一一份 │ ├── ouc-serif/ 宋体(思源宋体 SC 子集) │ ├── ouc-sans/ 黑体(思源黑体 SC 子集) │ ├── ouc-kai/ 楷体(霞鹜文楷子集) │ ├── zhuque-fangsong/ 仿宋(朱雀仿宋) │ ├── tex-gyre-termes/ 西文(Times 度量兼容) │ ├── harmonyos-sans/ 幻灯片/科技报告主字体 │ ├── README.md 来源、字符集、子集重建方法 │ └── LICENSE 逐字体授权原文 └── fonts.tex ← 唯一允许声明字体的地方 ``` `幻灯片/fonts/`(18 个文件 49MB)与 `科技报告/font/`(92MB,含 5 款方正)已删除。 字体总体积 141MB → 49MB。 ### 七个模板的接入方式 全部 `\input{../fonts.tex}`,各自只保留"哪一族当默认"的选择,字体文件路径一律指向 `../fonts/`。 `试卷/oucexam.sty`、`试卷/ouckey.sty`、`课程执行大纲/ouccourse.sty`、`试卷归档封面/oucksfm.sty`、 `年度考核登记表/ouckhtb.sty`、`劳务发放说明表/ouclw.sty`、`幻灯片/theme/beamerfontthemeOUCSlide.sty`、 `科技报告/cls/font.cls` —— 全部改完,`\sunfont` / `\fzss` / `\ccfang` 这类旧命令名保留,调用点零改动。 ### 全量重编结果 | 模板 | 页数 | 错误 | Overfull | Underfull | 缺字 | |---|---|---|---|---|---| | 试卷归档封面 | 1 | 0 | 0 | 0 | 0 | | 年度考核登记表 | 2 | 0 | 0 | 0 | 0 | | 劳务发放说明表 | 1 | 0 | 0 | 0 | 0 | | 课程执行大纲 | 5 | 0 | 1(6.39pt) | 0 | 0 | | 试卷题型示例 | 6 | 0 | 0 | 0 | 0 | | 参考答案 | 3 | 0 | 1(0.2071pt) | 0 | 0 | | 幻灯片 | 30 | 0 | 0 | 1 | 0 | | 科技报告 | 10 | 0 | 0 | 1 | 0 | 两条 Overfull、两条 Underfull、两条 `Font shape pcr undefined`、两条 `Font shape sc undefined` **全部经改造前版本对照确认是原有问题**(改造后反而是减少的,科技报告 Underfull 从 2 条降到 1 条)。 ### 与改造前的逐行 A/B 对照 导出 HEAD 版本单独编译作为基准,逐页逐行取 `(页码, 文本, x, y)` 比对: - **幻灯片 30 页 362 行逐行完全一致,零漂移** —— 最强的等价性证明 - 年度考核登记表 / 劳务发放说明表 / 试卷题型示例 / 参考答案 —— **全文字符完全相同** - 课程执行大纲 —— 仅 2 处断字连字符(`through-`/`through`、`process-`/`processing`),词本身未变 - 科技报告 —— 差异全部来自「字体」演示章节的说明文字改写(原文写着方正系列,已改为新字体名) ### 字符集覆盖 扫描全库正文(剔除注释)857 个非 ASCII 字符: - OUC Serif / Sans / Kai(含粗体)**缺失 0** - 朱雀仿宋缺全角「+」,该字符只出现在注释里,不参与排版 - 鸿蒙 SC 缺失 0 ### 顺带修的 - 中文斜体 `\textit` 失效(漏配 `ItalicFont`/`BoldItalicFont`)—— 已补,实测落在 `OUCKai-Regular` - `科技报告/report.tex` 的字体演示正文还在写「方正小标宋」等旧名 —— 已改为思源宋体/霞鹜文楷/朱雀仿宋/思源黑体 - `试卷/_bak/` 备份目录(含旧 `setmainfont{SimSun}`)—— 已删 验收页面:`.workbuddy/字体总览/index.html`
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/ouc_latex_template#6