FABRIC.md: scope TrueType rendering as adjunct to stroke font (4.3.7)
Not implementation -- documentation-only. Reviewing the 4.3.6 stroke font's full 113-glyph repertoire (mid-4.3.6g checkpoint) prompted the decision to add TrueType rendering as an adjunct path rather than continue refining strokes alone. Stroke font stays; nothing reverted. Adds 4.3.7-4.3.7f (parser core, outline extraction, font data ingestion, rasterization, glyph cache, TTF-TEXT entry point, three-arch checkpoint) plus §27.7 documenting four resolved design decisions: C implementation layer, Q48.16 fixed-point (not float -- confirmed real via Makefile.starkernel grep that GAP-B2's hypothesized FP-register-clobber-on-interrupt risk is real on all three architectures, not just hypothetical), capsule-block-encoded font data, and TrueType as the primary text path once built. 4.3.6g itself stays open -- paused mid-verification when a real cross-arch framebuffer-resolution difference (aarch64 800x600 ramfb vs amd64 1280x800 GOP) surfaced; not yet re-run with corrected coordinates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2960989100
commit
28731b8536
@@ -4641,6 +4641,62 @@ document and committing that amendment as its own item.*
|
||||
correctly positioned, on all three architectures, matching the 4.3.3b/4.3.4 completion
|
||||
pattern (screendump-verified, not just non-crashing). Three-arch acceptance boot clean,
|
||||
logs committed. *Refs:* §27.6.
|
||||
> **Paused 2026-08-09, mid-verification.** amd64's 113-glyph grid screendump (1280×800 GOP
|
||||
> framebuffer) looked correct. Re-running the same grid on aarch64 surfaced a real,
|
||||
> previously-unaccounted-for cross-arch difference: aarch64 boots with an 800×600 `ramfb`
|
||||
> device, not amd64's 1280×800 linear GOP framebuffer — the grid's Y coordinates (laid out
|
||||
> for 800px height) ran off the top of the smaller screen. Not yet re-run with corrected,
|
||||
> screen-size-aware coordinates on any architecture. This checkbox stays open.
|
||||
>
|
||||
> The review this checkpoint exists for happened here, ahead of schedule: seeing the
|
||||
> stroke-rendered repertoire together prompted the decision to add TrueType rendering as
|
||||
> an adjunct rather than continue refining the stroke system alone — see 4.3.7 below. The
|
||||
> stroke font itself is being kept, not reverted; this item still needs to finish (grid
|
||||
> fixed, all three arches, screendump-verified) before REPL wiring (M8) is scoped, per its
|
||||
> own "Done when."
|
||||
|
||||
- [ ] **4.3.7 — TTF parser core.** A C module (not FORTH — parsing and rasterization are
|
||||
impractical to interpret) reading a `.ttf`'s `sfnt` directory plus `head`/`maxp`/`loca`/
|
||||
`glyf`/`cmap` tables, resolving a codepoint to a glyph index and its outline data. All
|
||||
scaled/derived values in Q48.16, not float — see §27.7. *Done when:* given an embedded test
|
||||
font's bytes in memory, the parser resolves at least one ASCII codepoint to the correct
|
||||
`glyf` table offset and reads its outline header (contour count, bounding box), verified
|
||||
against values independently read from the same font with a reference tool (e.g.
|
||||
`fonttools`/`ttx`), not just "doesn't crash." *Refs:* §27.7.
|
||||
|
||||
- [ ] **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.
|
||||
|
||||
- [ ] **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`
|
||||
buffer at capsule load time. *Done when:* a font capsule loads cleanly (`mkcapsule --lint`),
|
||||
and the decoded in-memory bytes checksum-match the original `.ttf` file. *Refs:* §27.7.
|
||||
|
||||
- [ ] **4.3.7c — Rasterization.** Bézier curve flattening to line segments (reusing the
|
||||
existing `LINE`/Bresenham primitive where practical), then fill. Antialiasing approach is
|
||||
an open question — not decided here, resolve when this item is picked up. *Done when:* a
|
||||
single glyph outline rasterizes to a recognizable filled (or outlined, if AA is deferred)
|
||||
shape on the CANVAS, screendump-verified. *Refs:* §27.7.
|
||||
|
||||
- [ ] **4.3.7d — Glyph raster cache.** Rasterizing on every draw call is too slow for
|
||||
repeated text; cache rasterized bitmaps keyed by (font, codepoint, size). *Done when:*
|
||||
drawing the same codepoint/size twice measurably hits the cache on the second call (e.g. a
|
||||
counter or timing difference), verified live, not just "code that should cache." *Refs:*
|
||||
§27.7.
|
||||
|
||||
- [ ] **4.3.7e — `TTF-TEXT` entry point.** `TTF-TEXT ( c-addr u x y size color -- )`,
|
||||
analogous to 4.3.6f's `TEXT` but TrueType-backed — becomes the primary text-rendering path
|
||||
per the resolved relationship to the stroke font (§27.7); `TEXT`/the stroke system remain
|
||||
available, not deprecated. *Done when:* a UTF-8 string renders correctly via `TTF-TEXT` in
|
||||
one call, screendump-verified, proportional spacing correct. *Refs:* §27.7.
|
||||
|
||||
- [ ] **4.3.7f — Checkpoint: TTF rendering, all three architectures.** Same posture as
|
||||
4.3.6g. *Done when:* a single screendump per architecture shows a representative sample
|
||||
string rendered correctly via `TTF-TEXT`, three-arch acceptance boot clean, logs committed.
|
||||
*Refs:* §27.7.
|
||||
|
||||
⋯ *(4.3.x is open-ended — more items get appended here as Console work is scoped item by*
|
||||
*item, developed on the fly per §25.0. 4.4 below is unaffected by anything added above*
|
||||
@@ -5369,3 +5425,53 @@ exhausted. Presented at the algorithm level, same caveat as `DECODE-UTF8` — th
|
||||
construction is 4.3.6f's own implementation work, not settled here.
|
||||
|
||||
*Refs:* §25.5 (punch list).
|
||||
|
||||
### 27.7 TrueType rendering, adjunct to the stroke font (4.3.7–4.3.7f)
|
||||
|
||||
Scoped 2026-08-09, immediately after the 4.3.6g checkpoint review (which surfaced this
|
||||
decision ahead of that item finishing — see 4.3.6g's paused note). **Adjunct, not a
|
||||
replacement:** the stroke-drawn font system (4.3.6–4.3.6g) stays; nothing from it is being
|
||||
reverted or deprecated by this work.
|
||||
|
||||
**Four design decisions resolved 2026-08-09, before any implementation:**
|
||||
|
||||
1. **Implementation layer: C, not FORTH.** TTF parsing (table lookups, glyph index
|
||||
resolution) and rasterization (Bézier flattening, scanline fill) are impractical to write
|
||||
as interpreted FORTH — same reasoning that put `LINE`/`CIRCLE`/`ARC`/`ELLIPSE` (4.3.3b) in
|
||||
C rather than FORTH. A new C module, parallel to those, exposes a handful of new words to
|
||||
FORTH.
|
||||
|
||||
2. **Q48.16 fixed-point throughout, not float.** Checked before deciding, not assumed.
|
||||
**GAP-B2** (this doc, §"unverified prerequisites") already flagged the *question* —
|
||||
"if the kernel is not built with `-mgeneral-regs-only` (aarch64) / soft-float (riscv64),
|
||||
a C interrupt handler may clobber FP registers" — as unverified, one grep away from
|
||||
settled. That grep was run while scoping this item: `Makefile.starkernel`'s
|
||||
`ARCH_CFLAGS` show amd64/aarch64 with no explicit FPU disable and riscv64 built `lp64d`
|
||||
(a hard-float ABI, not soft-float) — so hardware FP is implicitly available on all three,
|
||||
and GAP-B2's hypothesized risk is real, not hypothetical: none of the three
|
||||
architectures' ISR paths save/restore FP register state. This resolves GAP-B2's open
|
||||
question (confirmed real) but does not fix the underlying gap itself, which stays open
|
||||
for whatever eventually does need hardware FP. There is no documented project-wide
|
||||
"no float" policy — this is a targeted decision for this item. Building the rasterizer in
|
||||
Q48.16 sidesteps the risk for this work specifically (it never touches FP hardware), and
|
||||
incidentally keeps it consistent with the determinism convention the rest of the runtime
|
||||
(Compudynamics, the geometry primitives) already uses Q48.16 for.
|
||||
|
||||
3. **Font data storage: encoded into capsule blocks.** A `.ttf` is binary; capsule blocks are
|
||||
text (64 chars/line, 16 lines/block, per `tools/mkcapsule.c`'s `validate_forth_blocks()`).
|
||||
Chose hex/base64 encode-at-build/decode-at-load over a parallel build-time embedded-binary
|
||||
asset (like `capsule_generated.c` bakes in capsule text) specifically to keep font data
|
||||
inside the existing content-addressed capsule system rather than introduce a second,
|
||||
parallel asset-embedding mechanism. Hex vs. base64 not yet chosen — 4.3.7b's own call.
|
||||
|
||||
4. **Relationship to the stroke font: TrueType becomes the primary text path.** Once
|
||||
`TTF-TEXT` (4.3.7e) exists, it's the intended path for real text rendering; `TEXT`/the
|
||||
stroke system (4.3.6f) remain available and are not deprecated — useful for early boot
|
||||
(before the capsule/VM bootstrap, same reason `font_8x16.c` stays per §27.6), low-memory
|
||||
contexts, or diagnostic/geometric use. Both continue to exist; callers choose.
|
||||
|
||||
**Explicitly not decided here, left to the item that owns them:** antialiasing approach
|
||||
(4.3.7c), hex vs. base64 encoding (4.3.7b), which `.ttf` file serves as the v1 test/default
|
||||
font (not chosen yet — needs a licensing check before any specific font is embedded).
|
||||
|
||||
*Refs:* §25.5 (punch list), GAP-B2.
|
||||
|
||||
Reference in New Issue
Block a user