This release includes 3 breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+6 more
Summary
AI summaryUpdates New, Verification, and Breaking changes across a mixed release.
Full changelog
taetype 1.0.0 is the first release built to be a complete font engine, not a subsetting utility with extras bolted on. Every table format, every table, and every code path below is real, exercised by real fixture fonts, and covered by tests — see Verification in the README for exactly how that's checked.
New
- CFF2 variable fonts – Top DICT/FDArray/FDSelect parsing,
blend/vsindexresolution against an axis location, full subroutine inlining. A CFF2 font instances to a static CFF1 table the same way a TrueType variable font instances to staticglyf. - COLR v1 color fonts – the full paint graph: linear/radial/sweep gradients, transforms, Porter-Duff composition, recursive
PaintColrGlyph/PaintGlyph, and variable paints resolved againstItemVariationStore. Subsetting chases v0 layer and v1 paint dependencies through a shared fixed-point closure with GSUB, so a color reference never gets left with a blanked-out glyph. - MATH table – all 56 constants, per-glyph italics correction and top-accent attachment, sub/superscript kerning, and growable-glyph construction for stretchy delimiters.
- JSTF – extender glyphs and
JstfPrioritymodification lists, wired intorustybuzz::Featuretoggling via a feature-tag heuristic forshape_justified. - STAT, BASE, VORG, SVG-in-OpenType – style-linking axis/value taxonomy, script baseline positions, vertical origin (with the spec-correct
vmtx+glyfderivation forglyf-outline fonts), and raw SVG document extraction. taerizer::cpu– a from-scratch, zero-unsafeCPU rasterizer. Turns any outline (TrueType or CFF/CFF2, at any instanced axis position) into a grayscale anti-aliased coverage bitmap with no third-party rasterizer dependency.- A schema-driven GSUB/GPOS/GDEF subsetting engine – every real lookup type (GSUB 1–8, GPOS 1–9, GDEF's five subtables) now subsets through one generic parse/build engine driven by declarative shape descriptions, instead of a hand-written function per lookup type. Differentially verified against the hand-written implementations it replaced, which are kept on as a standing test oracle.
- A plain-Rust public API (
native_api::Font) – no global registry, no wasm-bindgen; a caller owns itsFontvalues directly and it works the same whether you're targeting native or wasm32.
Breaking changes
- WOFF2 input is no longer supported. Decompression pulled in
brotli-decompressorfor a format most modern pipelines already unwrap upstream; dropping it keeps the dependency tree to justrustybuzz. - The wasm-bindgen JS bindings are gone.
native_api::Fontreplaces the old registry-based API. If you were calling taetype from JS through the generated bindings, this is a real migration, not a drop-in swap. - Package metadata changed to match:
description,keywords, andcategoriesno longer mention wasm or WOFF2; the crate isrlibonly (nocdylib), with an optionalstdfeature forno_stdtargets.
Verification
- 1,400+ unit and integration tests.
- Differential testing against real fontTools for decoding, instancing, and subsetting — variable fonts, CID-keyed CFF, COLR v0/v1, CBDT/sbix bitmaps, MATH tables — checked byte-for-byte or value-for-value.
- Fuzzing – six
cargo-fuzztargets (table extraction, TTC handling, subsetting, instancing, cmap lookup, COLR v1 paint resolution) run against real font corpora. - Property-based testing via
proptestfor invariants that need to hold across the whole input space, not just fixed cases. - Real sanitizer validation – demo and differential-test output fonts are checked with
opentype-sanitizer(OTS), the same sanitizer Chromium uses to reject malformed fonts. - Mutation testing on parsing/bounds-checking logic via
cargo-mutants.
#![forbid(unsafe_code)] is enforced at the crate root on every path above — a crafted or malicious font file cannot corrupt memory in this crate, full stop.
Internals
- CFF2's
blend-scalar cache switched from aHashMapto a linear-scanVec: real charstrings only ever see a handful of distinctvsindexvalues, so hashing cost more than it saved. gvarreuses its per-glyph delta buffers across the whole instancing pass instead of reallocating them per glyph.
Full diff: https://github.com/silly-tae/taetype/compare/v0.1.3...v1.0.0
Breaking Changes
- WOFF2 input is no longer supported (removes `brotli-decompressor` dependency).
- The wasm‑bindgen JS bindings are gone; migrate to the new pure‑Rust `native_api::Font` API.
- Package metadata updated: description, keywords, categories no longer mention wasm or WOFF2; crate is now `rlib` only with an optional `std` feature.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About Taetype
All releases →Related context
Related tools
Beta — feedback welcome: [email protected]