#font #fontconfig #xml-parser #font-loader #system-fonts

无 std rust-fontconfig

最小依赖,纯 Rust 的 font-loader 和 servo-fontconfig 的替代品

8 个版本

0.1.7 2024 年 1 月 18 日
0.1.6 2023 年 4 月 28 日
0.1.5 2021 年 4 月 18 日
0.1.3 2021 年 3 月 6 日
0.1.2 2021 年 2 月 28 日

#103 in GUI

Download history 116/week @ 2024-04-27 158/week @ 2024-05-04 121/week @ 2024-05-11 123/week @ 2024-05-18 156/week @ 2024-05-25 61/week @ 2024-06-01 78/week @ 2024-06-08 209/week @ 2024-06-15 152/week @ 2024-06-22 221/week @ 2024-06-29 119/week @ 2024-07-06 125/week @ 2024-07-13 137/week @ 2024-07-20 317/week @ 2024-07-27 151/week @ 2024-08-03 202/week @ 2024-08-10

832 每月下载量
用于 bestool

MIT 许可证

25KB
490

rust-fontconfig

Linux fontconfig 库的纯 Rust 重写(无系统依赖) - 使用 allsorts 作为字体解析器来解析 .woff.woff2.ttc.otf.ttf

注意:也适用于 Windows 和 macOS - 无外部依赖!

动机

我有几个原因想要拥有一个纯 Rust 版本的 fontconfig

  • 带有所有依赖的 fontconfig(expat 和 freetype)大约有 190,000 行 C 代码(对于其功能来说过于庞大)
  • fontconfig、freetype、expat 以及基本上任何 C 中的解析都是一个常见的攻击向量(通过恶意制作的字体)。Rust 版本(allsorts)在访问内存之前检查边界,因此通过字体文件进行的攻击应该更少。
  • 它消除了在 Linux 上构建 azul 所需的 cmake / cc 依赖
  • fontconfig 实际上不是一个“硬”库来重写,它只是解析字体并根据名称选择字体
  • Rust 有现有的 xml 解析器和字体解析器,只需使用它们即可
  • 它允许 fontconfig 库完全静态链接
  • 字体解析/加载可以很容易地进行多线程(并行解析字体文件)
  • 它将 azul 在 Linux 上所需的非 Rust 依赖项数量减少到 0
  • fontconfig(或至少 Rust 绑定)不允许你存储内存缓存,只能存储磁盘缓存,每次查询都需要磁盘访问(较慢)
  • 是否有潜在的对 no_std 的支持,以生成最小二进制文件?

现在来说一些更实际的原因

  • libfontconfig 0.12.x 有时会出现挂起和崩溃(查看问题
  • libfontconfig 与 cmake / cc 引入了构建问题(查看问题
  • 为了支持基于 Unicode 范围的 CSS 选择器和文本运行中的字体回退,你必须对 C 进行多次调用,因为 fontconfig 无法处理该功能
  • Rust 重写使用多线程和内存映射,因为这样可以比逐个读取文件更快
  • Rust 重写只解析选择名称所需的字体表,而不是整个字体
  • 该Rust重写版本使用的分配非常少(一些是必要的,因为涉及UTF-16/UTF-8转换和多线程生命周期问题)

用法

use rust_fontconfig::{FcFontCache, FcPattern};

fn main() {
    let cache = FcFontCache::build(); let result =

    cache.query(&FcPattern {
      name: Some(String::from("Arial")),
      .. Default::default()
    });

    println!("font path: {:?}", result);
}

性能

  • 缓存构建:约90毫秒,用于约530种字体
  • 缓存查询:约4微秒

许可

MIT

依赖项

约12MB
约285K SLoC