Skip to content

Release history

Taetype releases

All releases

4 shown

v1.0.0 Breaking risk
⚠ Upgrade required
  • Replace any JS usage of the former wasm‑bindgen bindings with direct calls to `native_api::Font`.
  • Update pipeline steps that pass WOFF2 files; decompress upstream or convert to OTF before feeding Taetype.
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.
Notable features
  • CFF2 variable fonts – full parsing, blend resolution, subroutine inlining and instance‑to‑CFF1 conversion.
  • COLR v1 color fonts – complete paint graph including gradients, transforms, Porter‑Duff composition and recursive glyph painting with subsetting dependency tracking.
  • MATH table support – all 56 constants, per‑glyph italics correction, top‑accent attachment, subscript/superscript kerning and growable‑glyph construction for stretchy delimiters.
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/vsindex resolution 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 static glyf.
  • COLR v1 color fonts – the full paint graph: linear/radial/sweep gradients, transforms, Porter-Duff composition, recursive PaintColrGlyph/PaintGlyph, and variable paints resolved against ItemVariationStore. 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 JstfPriority modification lists, wired into rustybuzz::Feature toggling via a feature-tag heuristic for shape_justified.
  • STAT, BASE, VORG, SVG-in-OpenType – style-linking axis/value taxonomy, script baseline positions, vertical origin (with the spec-correct vmtx+glyf derivation for glyf-outline fonts), and raw SVG document extraction.
  • taerizer::cpu – a from-scratch, zero-unsafe CPU 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 its Font values 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-decompressor for a format most modern pipelines already unwrap upstream; dropping it keeps the dependency tree to just rustybuzz.
  • The wasm-bindgen JS bindings are gone. native_api::Font replaces 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, and categories no longer mention wasm or WOFF2; the crate is rlib only (no cdylib), with an optional std feature for no_std targets.

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-fuzz targets (table extraction, TTC handling, subsetting, instancing, cmap lookup, COLR v1 paint resolution) run against real font corpora.
  • Property-based testing via proptest for 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 a HashMap to a linear-scan Vec: real charstrings only ever see a handful of distinct vsindex values, so hashing cost more than it saved.
  • gvar reuses 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

No immediate action
v0.1.3 Bug fix

post table fix

No immediate action
v0.1.2 Maintenance

Routine maintenance and dependency updates.

No immediate action
v0.1.1 New feature

OpenType font engine

Beta — feedback welcome: [email protected]