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.
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.
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.
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.
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.