Wherein we pursue oxidizing fontmake. For context around where fontmake came from see Mr B goes to Vartown.
Converts source to IR, and then IR to font binary. Aims to be safe and fast.
References
- Intermediate Representation (IR)
- Editor perspective note from Just
- Units
- Fonts have all the best units; distinguishing between them turns out to matter.
Two main reasons:
- Speed
- The python compiler is too slow and we don't think we can plausibly make it fast enough
- A key part of Google Fonts technical strategy is to get off both Python and C++, consolidating on Rust
- Rust enables us to write fast code that integrates well with our serving stack
- See https://github.com/googlefonts/oxidize
So, Rust compiler time!
(https://xkcd.com/303/ remix)
https://googlefonts.github.io/fontc_crater/ tracks our progress in making the new compiler match the old one.
Install the latest version of Rust, https://www.rust-lang.org/tools/install.
# Build a .designspace file
$ cargo run -p fontc -- resources/testdata/wght_var.designspace
# Build a .glyphs file
$ cargo run -p fontc -- resources/testdata/glyphs3/WghtVar.glyphs
# Build a .fontra file
$ cargo run -p fontc -- resources/testdata/fontra/minimal.fontraIf you pass the --emit-ir option, the IR will be written to disk inside
the build working directory. This can be helpful when troubleshooting.
$ cargo run -p fontc -- --emit-ir resources/testdata/wght_var.designspace
$ ls build/Google Fonts has lots, you could try https://github.com/rsheeter/google_fonts_sources to get some. Once you have them you could try building them:
cargo run -p fontc -- ../google_fonts_sources/sources/ofl/notosanskayahli/sources/NotoSansKayahLi.designspaceThere is an included fontc_crater tool that can download and compile multiple
fonts at once; this is used for evaluating the compiler. For more information,
see fontc_crater/README.md.
We focus on making the compiler better and more robust, ensuring it can handle the full variety of font sources in the Google Fonts ecosystem.
Our progress is tracked via fontc_crater, which compares fontc against fontmake for thousands of fonts.
Key milestones reached:
- Oswald compilation matches
fontmake. - Glyphs integration with the fontc-export-plugin.
We are currently:
- Ensuring ever more font families compile correctly and match
fontmakeoutput (or differ in well-understood ways). - Moving towards using
fontcexclusively for all Google Fonts builds.
For context see https://github.com/googlefonts/oxidize/blob/main/text/2022-07-25-PROPOSAL-build-glyphs-in-rust.md and the discussion on googlefonts/oxidize#33.
It is quite common to find we need changes in https://github.com/googlefonts/fontations to add a feature
or fix a bug. Prior to a release being available modify the root Cargo.toml to point to either a local
clone or a branch:
# 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" }Shows the non-dev dependency relationships among the crates in the repo.
%% 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
We use several tools to evaluate the correctness of fontc compared to fontmake:
- fontc_crater: A tool for compiling thousands of fonts and generating a compatibility report.
- ttx_diff: A Python tool for comparing the XML representation of fonts (via
ttx) produced byfontcandfontmake. - otl-normalizer: A tool for normalizing OpenType Layout subtables for easier comparison.
For tips on profiling, see docs/performance.md.
We have included a few git hooks that you may choose to use to ensure that
patches will pass CI; these are in resources/githooks.
To run the pre-push step manually:
$ ./resources/githooks/pre-pushIf you would like to have these run automatically when you commit or push changes, you can set this as your git hooksPath:
$ git config core.hooksPath "resources/githooks"See https://github.com/googlefonts/fontations#releasing
To update the Glyphs plugin see https://github.com/googlefonts/fontc-export-plugin.
