ttf.c: glyph outline extraction, simple and composite (item 4.3.7a)
ttf_glyph_outline() decodes simple-glyph flag/coordinate runs and recursively resolves composite components into a caller-supplied point/ contour-end buffer, in Q48.16. Composite scale/rotation/skew transforms are rejected with TTF_ERR_UNSUPPORTED rather than mis-rendered, since the shared q48_mul/q48_div are unsigned-only; translation-only composites (the only kind the v1 glyph repertoire uses) apply cleanly via q48_add. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5f6cc054d4
commit
70b6918279
@@ -4712,11 +4712,46 @@ document and committing that amendment as its own item.*
|
||||
> compile check above is what stands in for it, per this item's own "done when" clause
|
||||
> (which never asked for a kernel boot).
|
||||
|
||||
- [ ] **4.3.7a — Glyph outline extraction.** Simple and composite glyph outlines from `glyf`
|
||||
- [x] **4.3.7a — Glyph outline extraction.** Simple and composite glyph outlines from `glyf`
|
||||
— on-curve/off-curve point lists, quadratic Bézier control points, composite glyph
|
||||
transforms — in Q48.16. *Done when:* outline point lists for a handful of test glyphs
|
||||
(including at least one composite, e.g. an accented character if the test font has one)
|
||||
match reference-tool output within Q48.16 rounding tolerance. *Refs:* §27.7.
|
||||
> **Done 2026-08-10.** `ttf_glyph_outline()` in `src/starkernel/hal/ttf.c`/`ttf.h`: flags
|
||||
> run-length decode, delta-decoded x/y coordinates (simple glyphs), and recursive composite
|
||||
> component resolution, into caller-supplied point/contour-end buffers (no allocation in
|
||||
> this module). Points are stored in raw font design units shifted into Q48.16
|
||||
> (`q48_from_i32`, a local two's-complement left-shift — deliberately not routed through
|
||||
> `q48_mul`/`q48_div`, see below).
|
||||
>
|
||||
> **Known gap, reported not fixed, per this repo's rule against modifying a shared/tested
|
||||
> module without being asked:** `src/starkernel/math/q48_16.c`'s `q48_mul`/`q48_div` are
|
||||
> unsigned-only (`q48_div` saturates via an unsigned overflow check on `a`; `q48_mul` does a
|
||||
> plain unsigned widen-multiply) — confirmed by reading the source before writing any of
|
||||
> this, not assumed. A composite glyph's transform can carry a signed F2Dot14 scale/
|
||||
> rotation/skew, which needs a *signed* fixed-point multiply that function doesn't provide.
|
||||
> Resolution taken here: `decode_composite_glyph()` applies (dx,dy) translation only (plain
|
||||
> `q48_add`, safe under two's-complement regardless of the unsigned typing) and explicitly
|
||||
> **rejects** any component with a non-identity scale/2×2 transform or point-matched
|
||||
> (non-xy-offset) args, returning `TTF_ERR_UNSUPPORTED` rather than silently mis-rendering
|
||||
> it. Checked, not assumed: every composite in `fonts/JetBrainsMono-Regular.ttf` (11 sampled
|
||||
> accented Latin glyphs: `ÁÉÍÓÚÑéáñüö`) uses identity-scale translation-only components, so
|
||||
> this doesn't block the v1 repertoire (§27.6.4) — but it's a real limitation for an
|
||||
> arbitrary future font, and fixing it means either giving `q48_16.c` a signed multiply
|
||||
> variant or doing the scale math locally the same way translation already is. Whoever picks
|
||||
> that up next should decide which, not silently patch it in passing.
|
||||
>
|
||||
> Verified against `/tmp/.../scratchpad/ttf_outline_ref.py` (not committed, reproducible
|
||||
> from this note) — a second from-scratch Python decoder sharing no code with `ttf.c`,
|
||||
> covering the same "no `fonttools` installed" substitution already recorded under 4.3.7.
|
||||
> Three glyphs checked point-for-point (coordinates, on/off-curve flags, contour-end
|
||||
> indices) via the extended `tools/ttftest.c`: `.` (12 points, 1 contour, simple), `A` (17
|
||||
> points, 2 contours, simple), and `á` (43 points, 3 contours, a genuine 2-component
|
||||
> translation-only composite exercising the recursive path) — all match exactly.
|
||||
> `gcc -std=c99 -Wall -Wextra -Werror`, zero warnings; single-file freestanding compile
|
||||
> against the real amd64 `Makefile.starkernel` flags also re-checked clean. Same "not a
|
||||
> kernel-boot change yet" posture as 4.3.7 — no FORTH/capsule wiring exists for this module,
|
||||
> so no three-arch QEMU acceptance applies here either.
|
||||
|
||||
- [ ] **4.3.7b — Font data ingestion.** `.ttf` bytes encoded (hex or base64 — pick one, record
|
||||
why) into capsule blocks per the resolved design decision (§27.7), decoded into a `kmalloc`
|
||||
|
||||
Reference in New Issue
Block a user