fontc
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.
But why?
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)
Are we there yet?
https://googlefonts.github.io/fontc_crater/ tracks our progress in making the new compiler match the old one.
Getting started
Install the latest version of Rust, https://www.rust-lang.org/tools/install.
Build a simple test font
# 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.fontra
Emit debug output
If you pass the --emit-debug option, additional files that can be helpful
when troubleshooting are written to a debug directory inside the build
working directory.
$ cargo run -p fontc -- --emit-debug resources/testdata/wght_var.designspace
$ ls build/debug/
Sources to play with
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.designspace
Building lots of fonts at once
There 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.
Plan
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 https://github.com/googlefonts/oxidize/pull/33.
Using a local copy of fontations
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" }
Dependency map
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
Evaluation & Testing
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.
Profiling
For tips on profiling, see docs/performance.md.
Contributing
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-push
If 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"
Cargo.lock
Cargo.lock is committed, so a given revision builds the same dependency
graph everywhere, and CI builds with --locked. Dependency updates are
deliberate: run cargo update and open a PR, most naturally at the start of
a release cycle so crater validates the refreshed graph. A weekly CI job
builds with the newest compatible dependencies to surface upstream breakage
early, and audits the pinned graph against RustSec advisories and crates.io
yank status (triaged findings: .cargo/audit.toml).
If Cargo.lock conflicts when merging or rebasing, don't resolve it by hand:
take either side whole and let cargo re-sync it against the merged manifests
(it only changes the entries it has to):
$ git checkout --theirs -- Cargo.lock # either side works
$ cargo check
$ git add Cargo.lock
Releasing
See https://github.com/googlefonts/fontations#releasing
To update the Glyphs plugin see https://github.com/googlefonts/fontc-export-plugin.
Release files for fontc 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fontc-1.0.0.tar.gz | 1.8 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| fontc-1.0.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| fontc-1.0.0-py3-none-win32.whl | Python 3 | none | Windows x86-32 | Details |
| fontc-1.0.0-py3-none-musllinux_1_1_x86_64.whl | Python 3 | none | Linux musl 1.1+ x86-64 | Details |
| fontc-1.0.0-py3-none-musllinux_1_1_aarch64.whl | Python 3 | none | Linux musl 1.1+ ARM64 | Details |
| fontc-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| fontc-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| fontc-1.0.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl | Python 3 | none | macOS 11.0+ ARM64, macOS 10.12+ x86-64, macOS 10.12+ universal2 (ARM64, x86-64) | Details |
Total release size: 57.7 MB
Release files / fontc-1.0.0.tar.gz
| Download URL | fontc-1.0.0.tar.gz |
|---|---|
| Size | 1.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b20c2c453022a9d9b61cd14aa1e15d53a0474e0a7a1985c673d216b70df5958
|
|
BLAKE2b-256 checksum How to use checksums |
84a5041409aec8f3213bc25f968e35b034bb1a3d022883b8103f037288a87320
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-win_amd64.whl
| Download URL | fontc-1.0.0-py3-none-win_amd64.whl |
|---|---|
| Size | 6.5 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
676f5def8749322c8e42cbd5bc8662d7fd601b282a078a77a83e72b397b558db
|
|
BLAKE2b-256 checksum How to use checksums |
71817627a28f8e2edb2d732d4011218ee6a43787229b0b1e9e1d58c687699938
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-win32.whl
| Download URL | fontc-1.0.0-py3-none-win32.whl |
|---|---|
| Size | 6.0 MB |
| Tags | Python 3 Windows x86-32 |
|
SHA-256 checksum How to use checksums |
4e4b326d51cc014b29d5e797c1cb6fb8d9974ab8e27345913de8774ef1ecd80f
|
|
BLAKE2b-256 checksum How to use checksums |
3b1ae7da7ca9ca72a0f3562b940631628b89809abfe308eb9514c9138fd92b67
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-musllinux_1_1_x86_64.whl
| Download URL | fontc-1.0.0-py3-none-musllinux_1_1_x86_64.whl |
|---|---|
| Size | 7.6 MB |
| Tags | Linux musl 1.1+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
4b6f4c50c9004ccf93dd493bbd20ebfb059064f901160ff8a03e303bd88eb75b
|
|
BLAKE2b-256 checksum How to use checksums |
8f974979595aad8151ad5b57cd044f6e9be791f773c291e82a096a27b2567e96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-musllinux_1_1_aarch64.whl
| Download URL | fontc-1.0.0-py3-none-musllinux_1_1_aarch64.whl |
|---|---|
| Size | 7.2 MB |
| Tags | Linux musl 1.1+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
eaa7fee02fcd9003b43ac56da6a220a0c354101568a9b7926adceac282e389ab
|
|
BLAKE2b-256 checksum How to use checksums |
cdec98a21af1e06cbdce20992a9372e78f2ec8ea8de4059830fed8bcb61a107a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | fontc-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 7.4 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
4f97268cb73280dfc80f382617a139c7de8e2e33e48969e0b32d895f266aeed1
|
|
BLAKE2b-256 checksum How to use checksums |
bf747eaee6710fe00c38de1e7d25bfa45ae1b03092a523aad3d30e1340fb02cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | fontc-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 7.4 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
f26866c228df819929013e1b02afaa6ea4a5e2eec6229275d422115f01707a6c
|
|
BLAKE2b-256 checksum How to use checksums |
0c4598ea6a599b9371cfc4f47f30f05feceeb0362eb4da1cc136e2566f61fcce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency logRelease files / fontc-1.0.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
| Download URL | fontc-1.0.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl |
|---|---|
| Size | 13.9 MB |
| Tags | Python 3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
fecf37f93591106de64c6db8b6d77766460a35f4c0a8ca61c0f22bf9f86b04cd
|
|
BLAKE2b-256 checksum How to use checksums |
57a7abd2c2b93b94fd6ff256c8cbd7d864089f5e12dd7518f59249e0a89c939c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.
Transparency log