Rust native font outlines

Status: accepted at commit a1d6d95. This slice extracts unscaled glyph outlines from caller-supplied OpenType bytes. It is deliberately separate from shaping, text placement, KiCad render-cache construction, system-font discovery, and browser packaging.

Dependency and boundary decision

The implementation uses ttf-parser 0.25.1 for safe, read-only OpenType parsing and outline callbacks. It supports TrueType glyf/gvar and PostScript CFF/CFF2 outlines without exposing its face, glyph, tag, or builder types from kicad-monkey-core. The public boundary remains a package-owned request, limits, stable error category, and generated TypeSpec command union. The crate continues to forbid package-owned unsafe code.

This is an appropriate mature dependency rather than an in-house font parser: the security-sensitive binary-table work spans multiple OpenType outline formats and variation tables. The package still owns validation, resource policy, command publication, parity vectors, and all KiCad-specific transforms. No shaping or rendering framework was added.

The Cargo edge disables default features and enables only std and variable-fonts. OpenType/Apple layout and glyph-name parsing are not pulled into the core merely because the upstream default bundle includes them.

Coordinate and command semantics

extract_font_outline_a0 verifies the out-of-band font hash, parses the requested face, validates unique variation tags against the face's indexed axes, applies finite coordinates, and extracts one OpenType uint16 glyph ID. It returns native move, line, quadratic, cubic, and close commands in unscaled font design units plus units per em. It performs no Y inversion, KiCad internal-unit scaling, flattening, stroke, fill, placement, or shaping.

The language-neutral oracle uses FontTools' atomic BasePen quadratic and cubic callbacks. For TrueType glyf, the implicit closing edge is emitted as an explicit line before close to match the parser's callback stream. CFF retains its native close callback behavior. CFF2 character strings end without an explicit endchar operator; the package closes any still-open final contour after successful extraction so consumers receive the same semantic path produced by FontTools. Integer records use exact comparison; variation and CFF records permit only the declared small absolute coordinate tolerance.

Resource and failure policy

Caller-selected font-byte, metadata-byte, variation-count, and command-count ceilings are inclusive. Defaults are permissive safety ceilings—256 MiB of font input and over sixteen million commands—not KiCad compatibility restrictions. Font and metadata limits are checked before hashing or parsing. The callback builder retains at most max_commands; additional callbacks only mark the operation as exceeded, and the operation returns a resource-limit error without publishing partial commands.

ttf-parser can invoke outline callbacks before discovering a malformed glyph and returning no bounding box. The bounded builder records whether any callback occurred: a zero-callback result remains a genuine missing outline (for example a space), while a result after one or more callbacks is an invalid-font error. Partial commands are never published or silently treated as whitespace.

Hash mismatch, invalid face, contract metadata, unsupported variation axis, out-of-range glyph ID, missing outline, and resource exhaustion have stable categories. The parser may continue walking the selected glyph after the command ceiling is reached because its callback cannot cancel; retained memory remains bounded by the ceiling and work remains bounded by the already-preflighted font and one glyph.

Evidence and deferrals

The fixed corpus includes the tracked KiCad stroke TTF, a deterministic in-house quadratic variable TTF whose wght coordinate changes a real control point, a transformed composite TrueType glyph, a two-face TTC selected at face index one, and deterministic cubic CFF and CFF2 OTFs. Rack validates every record through generated schema and Python decoding, verifies exact font hashes and deterministic regeneration, and runs the focused Rust suite. Production variable fonts, shaping-to-outline composition, final render-cache parity, and WASM packaging remain separate expansion work.