ttf-parser
A safe, zero-allocation Rust parser for TrueType, OpenType, and AAT font files, with a companion C API.
Repository Health
Technical Analysis
ttf-parser is a Rust library for parsing TrueType, OpenType, and AAT font files without any heap allocations or unsafe code. It exposes a high-level API for common font properties (metrics, glyph outlines, names, variable-font axes) alongside a low-level API for reading individual tables directly, so callers can pull out exactly the data they need instead of loading and interpreting an entire font.
Maintained by the HarfBuzz project, the crate is explicitly hardened against malformed or adversarial font data: every recursive parser enforces depth and per-call work limits, arithmetic and numeric casts are checked, and the crate forbids unsafe code entirely, which makes it a common choice anywhere untrusted font files must be parsed safely. It ships a companion C API (c-api/) for use outside Rust and supports no_std/WASM builds. The crate is currently in maintenance mode (bug fixes only); for new feature development the HarfBuzz project points users toward Google Fonts’ fontations (read-fonts/skrifa).
What You Get
- A high-level API for glyph outlines, metrics, names, and style detection without manual table parsing
- A low-level, safe API to read individual OpenType/TrueType/AAT tables (cmap, glyf, GPOS/GSUB, COLR, gvar, and more) directly
- Optional variable-fonts support (fvar, gvar, avar, HVAR, MVAR, VVAR) for OpenType Font Variations
- A companion C API (
c-api/) with a generated header for embedding the parser in non-Rust codebases no_std/WASM-compatible builds via configurable Cargo features (std, alloc, opentype-layout, apple-layout, variable-fonts, glyph-names)
Common Use Cases
- Building a font rasterizer or renderer that needs glyph outlines and metrics without pulling in a full font engine
- Implementing text shaping support (GPOS/GSUB, AAT kerx/morx) for a layout engine
- Extracting font metadata (family name, style, weight, width) for font pickers or asset pipelines
- Safely parsing untrusted, user-uploaded font files in a server or sandboxed environment
- Reading variable font axes and instantiating specific variation coordinates
Under The Hood
Architecture
Parsing starts from Face::parse, which validates the font’s magic number, locates the table directory via RawFace, and builds a FaceTables struct holding byte-slice references into each recognized table (src/lib.rs, src/tables/mod.rs). From there the API branches into per-table modules under src/tables/ (cmap, glyf, GPOS/GSUB via src/ggg/, AAT via src/aat.rs, variable-font deltas via src/var_store.rs and src/delta_set.rs), each exposing lazy, zero-copy readers (LazyArray16/LazyArray32) built on the shared Stream/Offset primitives in src/parser.rs. Nothing is eagerly decoded or heap-allocated; every accessor re-reads from the original byte slice on demand, so the core abstraction that everything depends on is the FromData/FromSlice parsing traits in parser.rs — changing their contract would ripple through all ~39 table modules.
Tech Stack
The crate is pure Rust, #![no_std] by default with std/alloc as opt-in Cargo features, and has zero runtime dependencies (only an optional core_maths dependency for no_std float operations). Feature flags (opentype-layout, apple-layout, variable-fonts, glyph-names, gvar-alloc) let consumers compile in only the table parsers they need. A separate c-api/ crate wraps the public Rust API behind a C ABI generated with cbindgen, and benches/ and testing-tools/ttf-fuzz/ are separate workspace members for performance and fuzz testing.
Code Quality
The crate has an extensive test suite under tests/tables/ (one file per table, e.g. cmap.rs, cff1.rs, gvar.rs, avar.rs) plus bitmap and integration tests, all run in CI (.github/workflows/rust.yml) across the pinned MSRV and stable Rust, across every meaningful feature-flag combination (no-default, std, alloc-only, variable-fonts, all-features). CI also runs poly lint/poly fmt --check for formatting and linting. Error handling is explicit and typed via FaceParsingError, an enum with named variants (MalformedFont, UnknownMagic, NoHeadTable, etc.) rather than panics or swallowed errors — the crate documents that any panic is treated as a critical bug.
What Makes It Unique Unlike most font parsers, ttf-parser treats malicious or malformed input as a first-class threat model rather than an edge case: recursive structures like composite glyphs, the COLRv1 paint graph, and CFF subroutines all carry both depth limits and bounded total work per call, specifically to prevent small fonts from forcing exponential blowup. Combined with zero heap allocations, forbidden unsafe code, and checked arithmetic throughout, this makes it one of the few font parsers designed to be safely exposed to untrusted input, which is why it underpins other safety-conscious tooling in the Rust font ecosystem.
Used by 2 apps in this directory
OpenPencil
AI Design Tools
An open-source, AI-native vector design tool with concurrent agent teams, design-as-code, a built-in MCP server, and multi-model intelligence — a distinct project from the similarly-named Figma-file-reading "open-pencil" editor.
Zed
Developer Tools · Collaboration · Code Editors
High-performance, multiplayer code editor built in Rust by the creators of Atom and Tree-sitter, with native AI integration and real-time collaboration.