A complete, ready-to-use stroke (vector) font for Rust: the public-domain
NewStroke font decoded into a reusable glyph-provider contract. Ask for a
char, get its pen-down strokes plus the advance — consumable by any text or
graphics engine.
use glyph::GlyphProvider;
use newstroke::StrokeFont;
let font = StrokeFont::shared(); // decoded once, lazily
let a = font.glyph('A').unwrap();
assert_eq!(a.strokes.len(), 2); // the crossbar + the two legs
assert_eq!(a.advance, 900); // pen step to the next glyph
let m = font.metrics();
assert_eq!(m.ascent, 1050); // cap height- Stroke geometry, not outlines. Each glyph is a list of pen-down polylines
(
Vec<Vec<Point>>) in integer glyph units — the path the pen travels. No fill, no tessellation; the consumer draws or scales the strokes directly. - Unicode-aligned. ~2500 codepoints resolve to a rendering glyph — Latin, Greek, Cyrillic, IPA, punctuation, math, arrows, currency, and more.
- Self-contained. Depends only on
glyph(which has zero dependencies). The font data is embedded withinclude_str!; no build script, no generated tables, no network.
[dependencies]
newstroke = { git = "https://github.com/codepaws/crate_newstroke" }
glyph = { git = "https://github.com/codepaws/crate_glyph" } # the contract typesglyph contract: Point, Glyph, FontMetrics, GlyphProvider (no deps)
↑ depends on
newstroke NewStroke decoded into the contract (deps: glyph only)
↑ depends on
<consumer> a text-layout / graphics engine (deps: glyph only)
A provider depends on the contract, never on the consumer. newstroke
implements glyph::GlyphProvider:
pub trait GlyphProvider {
fn glyph(&self, c: char) -> Option<Glyph>; // None = absent from this provider
fn metrics(&self) -> FontMetrics;
}Scale to a point size with point_size / metrics.units_per_em.
The vendored data is self-describing; the decoder reads it from first principles.
.libglyph libraries (font.lib,symbol.lib,kana.lib) — per-glyph pen-down strokes, named anchors, and cell-edge markers.charlist.txt— the codepoint → glyph map, including:-
Accent composition — a base plus anchor-bound diacritics (
À,Ç, and stacked diacritics likeǕ, where each binding resolves against the original base, not the running composite). -
Transform operators — eleven prefixes (per
vendor/transformations.md):mirror-V flip-H ( y→H−y)rotate 180° — !lowercase (x-height 700) -+uppercase (cap 1050) =%symbol (band 800) ~*plus
^superscript,.subscript, and their mirror-first variants`/,. -
Width variants (
+w/+p) — advance measured across a component that protrudes past the base's cell (e.g.Ά,ľ). -
Built-up ligatures — whole glyphs placed side-by-side into one codepoint (
IJ,DŽ,…,‼,₨).
-
- Metrics — derived from the coordinate grid (baseline
y=0):units_per_em1300,ascent1050 (cap height),descent−250,line_gap250.
Codepoints that map to .notdef (or undecodable constructs) return None; the
decoder never emits a wrong or partial glyph.
A zero-dependency example renders glyph sheets to SVG (open in any browser):
cargo run --example render_sheet -- all # every rendering glyph
cargo run --example render_sheet -- lig # built-up ligatures
# also: ascii | rotate | flip | super | subSheets are written to test_output/.
The glyph data under vendor/ is the NewStroke font by Vladimir Lapygin
(vovanium), released into the public domain under CC0 1.0. It is embedded
verbatim; every decoded value traces to a specific record in those files.
The crate's code is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option. The embedded NewStroke data remains CC0.