字体编译器。
项目描述
fontc
在这里我们追求氧化(上下文:https://github.com/googlefonts/oxidize)字体制作。关于字体制作从何而来的背景信息,请参阅Mr B goes to Vartown。
将源代码转换为IR,然后从IR转换为字体二进制文件。旨在安全、增量且快速。
参考
但是为什么呢?
入门
安装最新版本的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"
发布
项目详情
fontc-0.0.1.post5.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a7aad28a01ea30469171ce7dc395819ba10902b4d41d405f9c5ca63fb58cbdf7 |
|
MD5 | 9d52502013e2389348c96fb3561da4e8 |
|
BLAKE2b-256 | 457b85d13fc8978c2d3deb7dd2c3e92ad3e5b2676915035c58bac818a458b51a |
fontc-0.0.1.post5-py3-none-win_amd64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 971b37577d71e22cd74d120c564db0252923c5fba05f5479a86f3e64bddc73bb |
|
MD5 | 0f1b569c789bdcb494156642b3d071d8 |
|
BLAKE2b-256 | 9c1c8c539ce3b67c12071628d45e980b7a80199509caf1993c8a0fe75e346419 |
fontc-0.0.1.post5-py3-none-win32.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a7b952e8979b177780db8251e6e7c0166ca724503ee20a7e25df0299d582a678 |
|
MD5 | e896b7cb4ac17cf624d0fcbfa0f150a7 |
|
BLAKE2b-256 | f4c315114b59fcf6bbf20986d8eb79682af545cd49cf208d2c92b1e9af537589 |
fontc-0.0.1.post5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 304d1bdba4d408a249382c1361d2d9f281ea03e5b09cef1e0645f55ae1dba3ba |
|
MD5 | a0a2565ece23ca443651906d9a63531a |
|
BLAKE2b-256 | 60107688b6198fdaf2237cb033b80ba1695a6759a9bc84495a65096857505cc0 |
fontc-0.0.1.post5-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b49933945e12136fe96ccc546f28984c9ccabc5aa7204ecb1e5ba3dacd79aaf7 |
|
MD5 | afc1dfc4bd6aa2443e6db24d49743dcc |
|
BLAKE2b-256 | 6428dc2a52345a95af27e2addab1d3b6569a03fdb74084cdb47a70ee7526161e |
fontc-0.0.1.post5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9ab0cb9982292678dc0ea461637dacf31d11b7f9494ba9f561056fe1abcebbe6 |
|
MD5 | be32a439e9979a64e5e4ff641382124d |
|
BLAKE2b-256 | 24e737a84c788473f25a3838428aa76c5429df46314835485de22214a4c490be |