背景
Python 的 fontTools + pyftsubset 是字体子集化的标准方案,但依赖 Python 环境、体积大、速度慢。如果你在用 Rust 技术栈(或只是不想装 Python),以下工具可以直接替代。
1. font_subset — 纯 Rust 库,最轻量
| 维度 | 说明 |
|---|---|
| 定位 | 库(Library) |
| 依赖 | 仅 brotli,no_std 兼容 |
| 支持格式 | OpenType / TrueType / WOFF2 / 可变字体 |
| 许可证 | MIT |
用法:
use font_subset::{Font, FontReader};
let font: Font = FontReader::new(font_bytes)?.read()?;let subset = font.subset(&retained_chars)?; // 只保留指定字符let woff2: Vec<u8> = subset.to_woff2();适合嵌入构建脚本或 WASM 场景,零外部依赖。
2. font-convert — 命令行最省事
| 维度 | 说明 |
|---|---|
| 定位 | CLI 工具 |
| 安装 | cargo install font-convert |
| 特点 | 按文本内容自动裁剪,输出 WOFF2 |
用法:
font-convert --input 字体.ttf \ --text "你的网站所有文字内容" \ --output subset.woff2不需要写代码,也不需要 Python。直接把用到的汉字丢进去,出来就是精简后的字体文件。
3. fontcull / fontcull-cli — 自动爬站裁剪
| 维度 | 说明 |
|---|---|
| 定位 | CLI 工具 |
| 特点 | 开 Headless Chrome 爬取站点,自动提取实际用到的字符(含伪元素) |
| 安装 | cargo install fontcull-cli |
用法:
fontcull https://你的站点.com --subset=fonts/*.ttf适合已有线上站点、想全自动优化字体体积的场景。它会分析 CSS content 伪元素里的 Unicode,不漏掉图标字体。
4. allsorts — 功能最全
| 维度 | 说明 |
|---|---|
| 定位 | 库 + 底层工具 |
| 来源 | 从 Prince PDF 渲染引擎提取 |
| 支持格式 | OpenType / TrueType / WOFF / WOFF2 |
| 能力 | 解析 + Shaping + Subsetting |
| 许可证 | Apache-2.0 |
如果你需要完整的字体处理管线(不只是裁剪,还要做 shaping、特征表处理),allsorts 是目前 Rust 生态里最成熟的方案。
5. cn-font-split — 中文特化
| 维度 | 说明 |
|---|---|
| 定位 | CLI / 库 |
| 特点 | 多线程子集化,针对中文字体体积优化 |
| 适用场景 | 思源黑体 / 思源宋体 等 CJK 字体 |
中文字体动辄 10MB+,cn-font-split 会把字体按 Unicode 范围拆成多个小文件,配合 unicode-range 实现按需加载,比单文件子集化更极致。
选型建议
| 你的需求 | 推荐工具 |
|---|---|
| 嵌入 Rust 项目构建脚本 | font_subset |
| 一行命令快速裁剪 | font-convert |
| 已有站点,全自动分析 | fontcull-cli |
| 需要 shaping + 完整 OpenType 支持 | allsorts |
| 中文大字体,极致分包加载 | cn-font-split |
与 Ateλier 的关联
Ateλier 原版的 fonts:ui 脚本用 Python fontTools 裁剪 UI 字体。如果你不想装 Python,可以用 font-convert 替代:
# 原版(需 Python)bun run fonts:ui
# 替代(纯 Rust)font-convert --input src/assets/fonts/ui-font.ttf \ --text "首页所有文案内容" \ --output public/fonts/ui-font.subset.woff2然后在 src/config/site.toml 里把字体路径指向裁剪后的文件即可。