47 个版本 (23 个重大更新)
0.24.1 | 2024 年 8 月 5 日 |
---|---|
0.24.0 | 2024 年 7 月 2 日 |
0.23.0 | 2024 年 7 月 2 日 |
0.20.0 | 2023 年 10 月 15 日 |
0.2.0 | 2019 年 7 月 10 日 |
#26 在 解析器实现
每月 758,795 次下载
用于 1,913 个crate (73 直接)
755KB
18K SLoC
ttf-parser
TrueType、OpenType 和 AAT 的高层、安全、零分配字体解析器。
可以作为Rust或C库使用。
功能
- 为大多数常见属性提供高层API,隐藏所有解析和数据解析逻辑。
- 提供低层但安全的API以访问TrueType表数据。
- 高度可配置。您可以选择禁用大多数功能,从而减小二进制文件大小。您还可以分别解析TrueType表,而无需加载整个字体/外观。
- 零堆分配。
- 零不安全。
- 零依赖。
no_std
/WASM 兼容。- 基本的 C API。
- 快速。
- 无状态。所有解析方法都是不可变的。
- 简单且易于维护的代码(没有魔法数字)。
安全性
- 库不得崩溃。任何崩溃都被视为严重错误,应予以报告。
- 库禁止不安全代码。
- 没有堆分配,因此不可能因OOM而崩溃。
- 所有递归方法都有深度限制。
- 技术上,在最坏情况下应该使用小于64KiB的堆栈。
- 大多数算术运算都进行了检查。
- 大多数数字类型转换都进行了检查。
替代方案
比较不同的库非常困难,因此我们使用表格进行比较。大致上有三种类型的TrueType表
- 具有属性列表的表(如
head
、OS/2
等)。
如果库尝试解析它,则将其标记为受支持。 - 包含单一类型数据的表(
glyf
、CFF(有点像)、
hmtx
等)。
只能支持或不支持。 - 包含多个子表的表(
cmap
、kern
、GPOS
等)。
可以部分支持,并注明哪些子表实际上是受支持的。
功能/库 | ttf-parser | FreeType | stb_truetype |
---|---|---|---|
内存安全 | ✓ | ||
线程安全 | ✓ | ~ (主要可重入) | |
零分配 | ✓ | ||
可变字体 | ✓ | ✓ | |
渲染 | -1 | ✓ | ~(非常原始) |
ankr 表 |
✓ | ||
avar 表 |
✓ | ✓ | |
bdat 表 |
~(没有4) | ✓ | |
bloc 表 |
✓ | ✓ | |
CBDT 表 |
~(没有8, 9) | ✓ | |
CBLC 表 |
✓ | ✓ | |
COLR 表 |
✓ | ✓ | |
CPAL 表 |
✓ | ✓ | |
CFF 表 |
✓ | ✓ | ~(没有seac 支持) |
CFF2 表 |
✓ | ✓ | |
cmap 表 |
~(没有8) | ✓ | ~(没有2,8,10,14; 仅支持Unicode) |
EBDT 表 |
~(没有8, 9) | ✓ | |
EBLC 表 |
✓ | ✓ | |
feat 表 |
✓ | ||
fvar 表 |
✓ | ✓ | |
gasp 表 |
✓ | ||
GDEF 表 |
~ | ||
glyf 表 |
~2 | ✓ | ~2 |
GPOS 表 |
✓ | ~(只有2) | |
GSUB 表 |
✓ | ||
gvar 表 |
✓ | ✓ | |
head 表 |
✓ | ✓ | ✓ |
hhea 表 |
✓ | ✓ | ✓ |
hmtx 表 |
✓ | ✓ | ✓ |
HVAR 表 |
✓ | ✓ | |
kern 表 |
✓ | ~(只有0) | ~(只有0) |
kerx 表 |
✓ | ||
MATH 表 |
✓ | ||
maxp 表 |
✓ | ✓ | ✓ |
morx 表 |
✓ | ||
MVAR 表 |
✓ | ✓ | |
name 表 |
✓ | ✓ | |
OS/2 表 |
✓ | ✓ | |
post 表 |
✓ | ✓ | |
sbix 表 |
~(仅PNG) | ~(仅PNG) | |
SVG 表 |
✓ | ✓ | ✓ |
trak 表 |
✓ | ||
vhea 表 |
✓ | ✓ | |
vmtx 表 |
✓ | ✓ | |
VORG 表 |
✓ | ✓ | |
VVAR 表 |
✓ | ✓ | |
语言 | Rust + C API | C | C |
测试版本 | 0.17.0 | 2.12.0 | 1.24 |
许可证 | MIT / Apache-2.0 | FTL / GPLv2 | 公有领域 |
说明
- ✓ - 支持
- ~ - 部分支持
- 无 - 不支持
备注
性能
TrueType字体设计用于快速查询,因此大多数方法都非常快。主要的例外是字形轮廓。字形可以使用两种不同的方法存储:使用 字形数据格式 和 紧凑字体格式(pdf)。前者相当简单,这使得它处理起来更快。后者基本上是一种小型语言,带有基于堆的虚拟机,这使得它处理起来非常困难。
基准测试 测试了渲染一个字体中所有字形的轮廓需要多长时间。
x86 (AMD 3700X)
表/库 | ttf-parser | FreeType | stb_truetype |
---|---|---|---|
glyf |
0.901ms |
1.171ms |
0.675ms |
gvar |
2.972ms |
4.132ms |
- |
CFF |
1.197ms |
5.647ms |
2.813ms |
CFF2 |
1.968ms |
6.392ms |
- |
ARM (Apple M1)
表/库 | ttf-parser | FreeType | stb_truetype |
---|---|---|---|
glyf |
0.550ms |
0.854ms |
0.703ms |
gvar |
2.270ms |
4.594ms |
- |
CFF |
1.054ms |
5.223ms |
3.262ms |
CFF2 |
1.765ms |
5.995ms |
- |
注意: FreeType 意想不到地慢,所以我担心我搞错了什么。
以下是某些方法的基准测试
test outline_glyph_276_from_cff2 ... bench: 867 ns/iter (+/- 15)
test from_data_otf_cff ... bench: 968 ns/iter (+/- 13)
test from_data_otf_cff2 ... bench: 887 ns/iter (+/- 25)
test outline_glyph_276_from_cff ... bench: 678 ns/iter (+/- 41)
test outline_glyph_276_from_glyf ... bench: 649 ns/iter (+/- 11)
test outline_glyph_8_from_cff2 ... bench: 534 ns/iter (+/- 14)
test from_data_ttf ... bench: 467 ns/iter (+/- 11)
test glyph_name_post_276 ... bench: 223 ns/iter (+/- 5)
test outline_glyph_8_from_cff ... bench: 315 ns/iter (+/- 13)
test outline_glyph_8_from_glyf ... bench: 291 ns/iter (+/- 5)
test family_name ... bench: 183 ns/iter (+/- 102)
test glyph_name_cff_276 ... bench: 62 ns/iter (+/- 1)
test glyph_index_u41 ... bench: 16 ns/iter (+/- 0)
test glyph_name_cff_8 ... bench: 5 ns/iter (+/- 0)
test glyph_name_post_8 ... bench: 2 ns/iter (+/- 0)
test subscript_metrics ... bench: 2 ns/iter (+/- 0)
test glyph_hor_advance ... bench: 2 ns/iter (+/- 0)
test glyph_hor_side_bearing ... bench: 2 ns/iter (+/- 0)
test glyph_name_8 ... bench: 1 ns/iter (+/- 0)
test ascender ... bench: 1 ns/iter (+/- 0)
test underline_metrics ... bench: 1 ns/iter (+/- 0)
test strikeout_metrics ... bench: 1 ns/iter (+/- 0)
test x_height ... bench: 1 ns/iter (+/- 0)
test units_per_em ... bench: 0.5 ns/iter (+/- 0)
test width ... bench: 0.2 ns/iter (+/- 0)
许可证
许可在以下之一下
- Apache许可证,版本2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确表示,否则任何有意提交以包含在作品中的贡献(如Apache-2.0许可证中定义),应以上述方式双授权,不附加任何额外条款或条件。