2 releases
| 0.0.12 | Apr 10, 2026 |
|---|---|
| 0.0.11 | Apr 10, 2026 |
#2317 in Parser implementations
1MB
31K
SLoC
fontcore for Rust
fontcore is a Rust library for loading fonts, selecting a face, shaping text, and exporting SVG.
Japanese: README.ja.md
What To Use First
Most users only need these three types.
FontFile- Opens a font file, TTC, or in-memory buffer
- Lets you choose a face
FontFace- Represents one face
- Exposes metadata such as
family(),full_name(),weight(),is_italic()
FontEngine- Shapes text, measures text, and renders SVG
- Main entry point for direction, locale, variant, and variable-font axes
The old low-level parser surface still exists behind features = ["raw"].
Supported Formats
- TrueType
- OpenType / CFF
- TTC
- WOFF
- WOFF2
Default features include layout and cff.
Features
layout- GSUB / GPOS shaping
- Vertical flow, RTL, locale, and variant selection
cff- OpenType / CFF outlines
raw- Legacy low-level parser API
svg-fonts- OpenType-SVG fonts are limited implementation
- Provisional support for converting OpenType
SVGglyphs into glyph layers - Currently regression-tested mainly against
EmojiOneColor.otfandNotoColorEmoji-Regular.ttf - Simple shapes are pathified, while payloads that cannot be pathified are kept as
GlyphLayer::Svg - Full path conversion and CSS / text interpretation are not implemented yet
Install
[dependencies]
fontcore = "0.0.12"
If you need the low-level parser API:
[dependencies]
fontcore = { version = "0.0.12", features = ["raw"] }
If you also want provisional SVG emoji font support:
[dependencies]
fontcore = { version = "0.0.12", features = ["svg-fonts"] }
Quick Start
use fontcore::{FontFile, ShapingPolicy};
let face = FontFile::from_file("fonts/YourFont.ttf")?.current_face()?;
let engine = face
.engine()
.with_shaping_policy(ShapingPolicy::LeftToRight)
.with_font_size(32.0)
.with_svg_unit("px");
println!("{}", face.family());
println!("{}", engine.measure("Hello")?);
println!("{}", engine.render_svg("Hello")?);
println!("{}", engine.shape("Hello")?.glyphs.len());
# Ok::<(), Box<dyn std::error::Error>>(())
Common Tasks
- Show metadata
face.family()face.full_name()face.weight()face.is_italic()
- Shape text
engine.shape(text)
- Measure text
engine.measure(text)
- Render SVG
engine.render_svg(text)
- Vertical flow
engine.with_vertical_flow()
- RTL shaping
engine.with_right_to_left()
- GSUB variant selection
engine.with_font_variant(...)
- Variable-font axes
face.variation_axes()engine.with_variation("wght", 700.0)
More runnable examples live in doc/api-recipes.md.
About SVG Color Fonts
sbix is exposed as raster layers, COLR/CPAL as path layers, and the OpenType SVG table is pathified first under svg-fonts, falling back to Svg layers only when needed.
The current svg-fonts implementation converts simple path, rect, circle, ellipse, line, polyline, and polygon elements into PathGlyphLayer values. It includes minimal defs / use, fill / fill-rule / stroke / stroke-width, clipPath / clip-path, simple mask, translate / scale / rotate / skewX / skewY / matrix, linearGradient / radialGradient / stop, and preserved gradientUnits / gradientTransform support, and keeps a GlyphLayer::Svg fallback not only for payloads that cannot be pathified, but also for payloads that still contain unsupported constructs such as pattern, complex mask, or filter.
On the 0.0.12 line, the paintcore renderer tracks the public fontcore layer model closely enough to preserve clip_commands and gradient paint values across the fontcore -> paintcore conversion.
See doc/SVFONTSPEC.md for the exact current scope, limitations, and the paintcore handoff contract.
Examples
High-level examples that work without raw:
api_overviewfontmetadatafontcore
Low-level inspection examples that require --features raw:
fontcmapsfontcolorfontgkanafontgsubfontheaderfontloadfontnamefontsbixfontsvgfonttestfonttypetategaki
Shared CLI flags:
-f,--font: font path-d,--dir: font directory-i,--index: face index inside a collection-o,--output: output file path-s,--string: inline text-t,--text-file: text file path--vertical: top-to-bottom flow--variant: variant shortcut such asjp78,jp90,trad,nlck
Run a high-level example:
cargo run --example api_overview -- -f path/to/font.ttf -s "Hello"
Run a raw example:
cargo run --example fontheader --features raw -- -f path/to/font.otf
cargo doc
The crate has rustdoc on the public API surface.
cargo doc --no-deps
If you want to open it immediately:
cargo doc --no-deps --open
The crate-level docs and type docs are the best entry point for:
FontFileFontFaceFontEngineFontFamilyFontVariantShapingPolicy
WebAssembly
The crate supports wasm32-unknown-unknown.
- Prefer
load_font_from_buffer()orload_font(FontSource::Buffer(...)) load_font_from_file()andload_font_from_net()returnErrorKind::Unsupportedonwasm32
Documentation Map
- Overview of the extra docs: doc/README.md
- Public API recipes: doc/api-recipes.md
- Current implementation status and limitations: doc/feature-status.md
- CFF2 investigation notes: doc/cff2-investigation.md
Dependencies
~8MB
~292K SLoC