feat(fonts): system TrueType support with shaping and fallback

Add a TrueType/OpenType render path alongside the LFF stroke engine so
users can pick fonts installed on their machine for text and MText.

- Discover system families via fontdb (sysfont) and list them in the
  text-style picker.
- Extract glyph outlines with ttf-parser, flattened into wire strokes
  normalized to the same 9-unit cap-height space as LFF glyphs.
- Shape runs with cosmic-text (ligatures, Arabic joining, kerning, bidi)
  plus automatic font fallback: a glyph missing from the chosen family
  is taken from another installed font.
- Unify both sources behind a single Face type; a shared run tokenizer
  drives the stroke (per-glyph) and shaped (TTF) renderers identically.
- Stroke fonts now fall back to a system TTF (cosmic-text picks it) for
  characters no LFF font covers, replacing the unicode/iso3098 chain.

Also trim the embedded LFF set from 47 to 26, keeping the AutoCAD-SHX
equivalents and dropping LibreCAD-only fonts now covered by TrueType.

LFF builtins keep priority over same-named system fonts so DXF text
renders identically across machines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-16 11:18:17 +03:00
commit cd048165a9
31 changed files with 1027 additions and 763568 deletions

View file

@ -42,6 +42,18 @@ truck-shapeops = "0.4"
# Fast non-cryptographic hasher. Handle/u64 keys dominate the hot block,
# hatch, draw-depth and wire caches; the default SipHash is overkill there.
rustc-hash = "2"
# TrueType/OpenType support: fontdb enumerates the user's installed system
# fonts; ttf-parser extracts glyph outlines we flatten into CAD wire strokes.
# Both are already in the tree transitively via iced's cosmic-text, so pinning
# them here adds no new downloads.
fontdb = "0.23"
ttf-parser = "0.25"
# Full text-layout engine: shaping (ligatures, Arabic joining, kerning), bidi
# reordering, and — crucially — automatic font fallback (a glyph missing from
# the chosen family is shaped from another installed font). We use it only to
# obtain positioned (font, glyph-id) runs; outlines come from ttf-parser and
# render through our own wire pipeline.
cosmic-text = "0.15"
[target.'cfg(target_os = "windows")'.dependencies]
# Win32_System_Com — COM behind "Set as default app"