跳转到主要内容

字体编译器。

项目描述

fontc

在这里我们追求氧化(上下文:https://github.com/googlefonts/oxidize)字体制作。关于字体制作从何而来的背景信息,请参阅Mr B goes to Vartown

将源代码转换为IR,然后从IR转换为字体二进制文件。旨在安全、增量且快速。

参考

但是为什么呢?

image

(https://xkcd.com/303/混搭)

入门

安装最新版本的Rust,https://rust-lang.net.cn/tools/install

构建一个简单的测试字体

$ cargo run -p fontc -- resources/testdata/wght_var.designspace

输出IR以启用增量构建

如果您传递了--incremental(或-i)选项,IR将被写入构建工作目录中的磁盘,这样下一次您运行fontc与相同的源文件时,只有更改的部分将被重新构建。

$ cargo run -p fontc -- --incremental resources/testdata/wght_var.designspace
$ ls build/

可玩耍的源

Google Fonts有很多,您可以尝试https://github.com/rsheeter/google_fonts_sources来获取一些。一旦您有了它们,您就可以尝试构建它们

cargo run --package fontc -- ../google_fonts_sources/sources/ofl/notosanskayahli/sources/NotoSansKayahLi.designspace

计划

截至2023年6月4日,我们打算

  • 将Oswald编译与fontmake相匹配
  • 将更多具有源文件的家族编译成与fontmake匹配的格式,或者仅在众所周知的方式上有所不同
  • 提供 Glyphs 插件,以允许一键使用新编译器
  • 一旦没有已知问题,将Google Fonts切换为仅使用fontc字体

我们放弃了之前将fontmake(Python)调用Rust的计划,因为它似乎比最初预期的更复杂,风险也更高。

关于背景信息,请参阅https://github.com/googlefonts/oxidize/blob/main/text/2022-07-25-PROPOSAL-build-glyphs-in-rust.md以及https://github.com/googlefonts/oxidize/pull/33上的讨论。

使用fontations的本地副本

我们经常需要更改https://github.com/googlefonts/fontations以添加功能或修复错误。在发布版本可用之前,修改根目录下的Cargo.toml,指向本地克隆或分支。

# Local copy
[patch.crates-io]
font-types =  { path = "../fontations/font-types" }
read-fonts =  { path = "../fontations/read-fonts" }
write-fonts = { path = "../fontations/write-fonts" }
skrifa =  { path = "../fontations/skrifa" }

# Branch
[patch.crates-io]
font-types = { git="https://github.com/googlefonts/fontations.git", branch="box" }
read-fonts = { git="https://github.com/googlefonts/fontations.git", branch="box" }
write-fonts = { git="https://github.com/googlefonts/fontations.git", branch="box" }
skrifa = { git="https://github.com/googlefonts/fontations.git", branch="box" }

依赖关系图

显示了存储库中crates之间的非开发依赖关系。

%% This is a map of non-dev font-related dependencies.
%% See https://mermaid.live/edit for a lightweight editing environment for
%% mermaid diagrams.
graph
    %% First we define the nodes and give them short descriptions.
    %% We group them into subgraphs by repo so that the visual layout
    %% maps to the source layout, as this is intended for contributors.

   fontc{{fontc\nCLI font compiler}}
   fontra2fontir[fontra2fontir\nconverts .fontra files to our IR]
   glyphs2fontir[glyphs2fontir\nconverts .glyphs files to our IR]
   ufo2fontir[ufo2fontir\nconverts from a \n.designspace to our IR]
   fontir[fontir\nthe IR for fontc]
   fontbe[fontbe\nthe backend of font compilation\nIR -> binary font]
   fea-rs[fea-rs\nParses and compiles\nAdobe OpenType feature files]
   fontdrasil[fontdrasil\nCommon types and functionality\nshared between all layers of fontc]

    %% Now define the edges.
    %% Made by hand on March 20, 2024, probably not completely correct.
    %% Should be easy to automate if we want to, main thing is to
    %% define the crates of interest.
    fontbe --> fontir
    fontbe --> fea-rs
    fontc --> fontbe
    fontc --> fontir
    fontc --> glyphs2fontir
    fontc --> fontra2fontir
    fontc --> ufo2fontir
    fontra2fontir --> fontir
    glyphs2fontir --> fontir
    ufo2fontir --> fontir

使用hyperfine比较分支性能

这种方法只能有效检测相对较大的更改。

# On each branch, typically main and your branch run hyperfine:
$ cargo build --release && hyperfine --warmup 3 --runs 250 --prepare 'rm -rf build/' 'target/release/fontc ../OswaldFont/sources/Oswald.glyphs'

# Ideally mean+σ of the improved branch is < mean-σ for main.
# For example, p2s is probably faster here:
# main Time (mean ± σ):     154.8 ms ±   8.2 ms
# p2s Time (mean ± σ):     132.7 ms ±   6.4 ms

# Report similar to ^ if claiming this as proof your branch is a win.

运行火焰图

flamegraphs对于fontc非常有用。最简单的创建方法是使用cargo flamegraph

# Minimize the impact of logging
$ export RUST_LOG=error
# Symbols are nice, https://github.com/flamegraph-rs/flamegraph#improving-output-when-running-with---release
$ export CARGO_PROFILE_RELEASE_DEBUG=true

# Build something and capture a flamegraph of it
$ rm -rf build/ && cargo flamegraph -p fontc -- ../OswaldFont/sources/Oswald.glyphs

# TIPS

# On macOS you might have to pass `--root` to cargo flamegraph, e.g. cargo flamegraph --root ...as above...

# If you are losing samples you might want to dial down the rayon threadcount
# You'll see a perf error similar to:
Warning:
Processed 5114 events and lost 159 chunks!

Check IO/CPU overload!

Warning:
Processed 5116 samples and lost 35.01%!

# Fix is to lower the threadcount:
$ export RAYON_NUM_THREADS=16

聚焦火焰图

https://blog.anp.lol/rust/2016/07/24/profiling-rust-perf-flamegraph/提供了过滤火焰图的示例。当您想要放大特定操作时,这非常有用。例如,深入了解fea-rs。

# Generate a perf.data
# You can also use perf record but cargo flamegraph seems to have nice capture settings for Rust rigged
$ rm -rf build/ perf.data && cargo flamegraph -p fontc -- ../OswaldFont/sources/Oswald.glyphs

# ^ produced flamegraph.svg but it's very noisy, lets narrow our focus
# Example assumes https://github.com/brendangregg/FlameGraph is cloned in a sibling directory to fontc
$ perf script | ../FlameGraph/stackcollapse-perf.pl | grep fea_rs | ../FlameGraph/flamegraph.pl > fea-flame.svg

贡献

我们包含了一些git钩子,您可以选择使用它们来确保补丁将通过CI;这些位于resources/githooks中。

手动运行pre-push步骤

$ ./resources/githooks/pre-push

如果您希望在提交或推送更改时自动运行这些步骤,可以将此设置为您的git hooksPath。

$ git config core.hooksPath "resources/githooks"

发布

请参阅https://github.com/googlefonts/fontations#releasing

项目详情


下载文件

下载适合您平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

fontc-0.0.1.post5.tar.gz (1.2 MB 查看哈希值)

上传时间

构建分布

fontc-0.0.1.post5-py3-none-win_amd64.whl (4.9 MB 查看哈希值)

上传时间 Python 3 Windows x86-64

fontc-0.0.1.post5-py3-none-win32.whl (4.6 MB 查看哈希值)

上传于 Python 3 Windows x86

fontc-0.0.1.post5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl (6.6 MB 查看哈希值)

上传于 Python 3 manylinux: glibc 2.17+ ARM64 musllinux: musl 1.1+ ARM64

fontc-0.0.1.post5-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl (6.8 MB 查看哈希值)

上传于 Python 3 manylinux: glibc 2.12+ x86-64 musllinux: musl 1.1+ x86-64

fontc-0.0.1.post5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (10.8 MB 查看哈希值)

上传于 Python 3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面