swash

Pure Rust crate for font introspection, complex OpenType/AAT text shaping, and glyph rendering with zero-copy, no_std support.

Library
Cargo
v0.2.10
871stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
68/100Good
Development Activity52
Maintenance56
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
70/100Good
Architecture82
Code Quality70
Innovation78
Learning Curve50

Swash is a pure Rust, cross-platform crate that provides font introspection, complex text shaping, and glyph rendering for building high-performance text layout and rendering systems. It exposes a borrowed, zero-copy FontRef representation with no opinions about resource management, so applications retain full control over how font data is loaded and cached, while thread-friendly ShapeContext and ScaleContext objects hold all mutable acceleration structures and caches separately from font data itself.

On the shaping side, swash implements full OpenType advanced typography (GSUB/GPOS), the Unicode Universal Shaping Engine for complex scripts such as Devanagari and Malayalam, Arabic joining, and Apple advanced typography (morx glyph metamorphosis and most of kerx extended kerning). On the scaling side, it produces hinted, variation-aware outlines and rasterized glyph images across TrueType, PostScript, and embedded color/bitmap formats (Apple sbix, Google CBLC/CBDT, Microsoft COLR/CPAL). It deliberately avoids text layout and glyph composition, leaving those application-specific concerns to consuming crates.

What You Get

  • Zero-copy, zero-allocation font introspection: names, metrics, variation axes, color palettes, character maps, and writing-system/feature enumeration
  • A ShapeContext-based shaping engine implementing OpenType GSUB/GPOS, Apple AAT (morx/kerx), and the Unicode Universal Shaping Engine for complex scripts
  • A ScaleContext-based scaler that produces hinted, variation-aware outlines or rasterized glyph images from TrueType, PostScript, and embedded bitmap/color sources
  • Full variable-font support across introspection, shaping, and scaling, including named instances and per-axis variation settings
  • no_std compatibility with feature-gated std/libm/scale/render builds validated in CI on embedded targets

Common Use Cases

  • Implementing a custom text layout engine that needs precise control over shaping and rasterization without a bundled layout algorithm
  • Building GPU-accelerated text rendering by requesting raw scalable outlines and feeding them into a separate tessellation/rendering pipeline
  • Supporting complex, non-Latin scripts (Arabic, Devanagari, Malayalam) in an editor, browser engine, or game UI
  • Rendering emoji and color fonts by resolving the best-fit glyph source across bitmap strikes and COLR/CPAL layers
  • Multithreaded batch text processing where per-thread shaping/scaling contexts avoid lock contention on a shared cache

Under The Hood

Architecture Swash is organized as a single crate with clearly layered modules: font.rs and internal/ provide low-level, zero-copy OpenType table parsing (FontRef, TableProvider, internal::parse) directly over borrowed byte slices; attributes.rs, metrics.rs, charmap.rs, palette.rs, strike.rs, and variation.rs build introspection APIs on top of that raw parsing layer; shape/ (mod.rs, at.rs, aat.rs, buffer.rs, cache.rs, cluster.rs, engine.rs, feature.rs, partition.rs) implements the complex text shaping engine around a ShapeContext/ShaperBuilder pattern that owns LRU caches to avoid transient heap allocations; scale/ implements a parallel ScaleContext/ScalerBuilder pattern for outline scaling, hinting, and rasterization; and text/ implements Unicode text analysis (script/cluster segmentation) that the shaper consumes upstream. Data flows one direction, from raw font bytes through borrowed parse structures into the introspection, shape, and scale layers, with contexts rather than individual calls owning all cache and scratch-buffer state so the same font data can be reused across many operations without reallocation. Because every downstream module keys off borrowed table slices rather than owned data, the FontRef/internal::parse borrowing model is the crate’s central abstraction.

Tech Stack Swash is a pure Rust crate (edition 2021) built on skrifa (a low-level OpenType parsing foundation) as its required base dependency, with yazi (bitmap decompression) and zeno (path rasterization, gated behind the scale/render features) as optional dependencies, plus core_maths for libm-based math on targets without a standard math library. It supports no_std via extern crate alloc and feature-gated std/libm/scale/render combinations, with CI validating builds against embedded targets (x86_64-unknown-none, thumbv7m-none-eabi). There are no async runtimes, build scripts, or external service dependencies — it is a self-contained parsing and numerical library meant to be embedded inside larger text-rendering pipelines.

Code Quality No #[test]-annotated unit test files exist under src/; correctness instead leans on module-level doc-tests (runnable examples embedded in shape/mod.rs and scale/mod.rs) and a CI matrix that runs cargo test across Windows, Linux, and macOS on stable and nightly toolchains plus a dedicated cargo miri test job for undefined-behavior detection — a meaningful gap in conventional unit coverage for a crate this widely embedded, offset by heavier reliance on integration-style and Miri verification. Error handling favors Option-returning APIs over panics, consistent with a no_std-compatible design. Naming is consistent, idiomatic Rust with builder patterns throughout, and a .clippy.toml plus workspace-level clippy lints (doc_markdown, semicolon_if_nothing_returned) and a .typos.toml config enforce style and catch documentation typos; CI also runs a cargo doc job and a build-no-std job across multiple feature/target combinations.

API Design The public API centers on two symmetric builder patterns, ShapeContext::builder(font) and ScaleContext::builder(font), both configured with chained methods (.script(), .size(), .features(), .variations()) before producing a Shaper or Scaler. This consistency lowers the learning curve once one side is understood. Feature and variation settings accept ergonomic tuple shorthand like ("dlig", 1) or ("wght", 520.5) alongside typed Setting values. Getting started requires understanding the context-per-thread model and the borrowed-lifetime FontRef type, which is a deliberate but real amount of upfront conceptual overhead for a library this low-level; extensive module-level documentation with runnable code snippets offsets that cost.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search