starkernel: retarget REPL glyph rendering to TTF-TEXT's rasterizer (4.4j)
font_8x16.c keeps rendering everything through and including POST; TTF-TEXT's rasterizer takes over at the interactive REPL boundary (sk_repl()) via a new runtime mode switch, vt100_enable_ttf() (console_fb_enable_ttf() wrapper), not a compile-time swap -- both backends coexist in the same binary since boot/POST must stay font_8x16.c per this item's own done-when. TTF-TEXT (the FORTH word) isn't directly callable from vt100.c -- VM stack arguments, different call shape than a one-glyph cell draw. Used hal/ttf.c's VM-independent primitives directly instead (same rasterizer TTF-TEXT itself calls underneath), added as a native C helper in vt100.c. Lazily loads fonts:JetBrainsMono-Regular.ttf and kmallocs a 96-slot raster cache (covers all 95 printable ASCII, no eviction thrash) on first switch. Cell geometry changes at the switch (mode-aware cell_w()/cell_h()): provisional 12x24 TTF cell (600/1000em * 20px = 12px exactly, using 4.4i's confirmed-uniform hmtx advance width) vs font_8x16's fixed 8x16 -- cols/rows re-derived and screen cleared at the switch point, same as vt100_init() itself does. Final REPL text size is 4.4m's decision, not this item's. Also fixes the second call site 4.4i flagged: erase_line_range() now uses one fb_fill_rect() instead of a per-cell font_8x16-specific blank glyph draw, consistent with erase_display(2)'s full-screen case. Three-arch verified: amd64/aarch64/riscv64 all reach ok>, POST Failed: 0, identical dict-hashes. amd64 screendump shows real proportional JetBrains Mono letterforms on the REPL tail, visibly distinct from every prior font_8x16 screenshot. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
64c20c78eb
commit
f729b91a09
@@ -5306,7 +5306,7 @@ document and committing that amendment as its own item.*
|
||||
> `draw_cursor_glyph()`'s call, `erase_line_range()`'s call, and the `fb_cell_w()`/
|
||||
> `fb_cell_h()`/`UNDERLINE_ROW` metrics that currently assume `font_8x16` specifically.
|
||||
|
||||
- [ ] **4.4j — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends
|
||||
- [x] **4.4j — Retarget the glyph-draw call site from `font_8x16.c` to `TTF-TEXT`.** Depends
|
||||
on 4.4i. **Boundary, corrected 2026-08-11:** `font_8x16.c`/VT100 keeps rendering everything
|
||||
through and including **POST** (the parity/dictionary-hash self-test) — not just the
|
||||
pre-bootstrap M1–M6 messages originally scoped here. POST runs *after* the capsule/VM system
|
||||
@@ -5328,6 +5328,76 @@ document and committing that amendment as its own item.*
|
||||
> preference"). The actual early-boot/POST fallback is `font_8x16.c` specifically, not "the
|
||||
> stroke font" generically.
|
||||
|
||||
> **Done 2026-08-11.** `TTF-TEXT` (the FORTH word, `word_source/ttf_words.c`) turned out not
|
||||
> to be directly callable from `vt100.c` — it takes VM-stack arguments and a
|
||||
> string+advance-loop, a different call shape than a one-glyph-at-a-time cell draw.
|
||||
> `hal/ttf.c`'s primitives underneath it (`ttf_load_from_capsule`, `ttf_raster_cache_get`,
|
||||
> etc.) are VM-independent, though, exactly like `font_8x16.c`'s own C functions — so
|
||||
> "retarget to TTF-TEXT" means "retarget to the same rasterizer TTF-TEXT itself uses",
|
||||
> implemented as a native C helper in `vt100.c`, not a call into the FORTH word. Recording
|
||||
> this now so it isn't read later as scope drift.
|
||||
>
|
||||
> **Boundary implemented as a runtime switch, not a compile-time swap** (this item's own
|
||||
> done-when requires boot/POST to stay `font_8x16.c` while REPL output uses TTF — both must
|
||||
> coexist in the same binary). New `vt100_enable_ttf()` (`vt100.c`, wrapped by
|
||||
> `console_fb_enable_ttf()` in `console.c`) flips a mode flag; `draw_cursor_glyph()` and
|
||||
> `erase_line_range()` branch on it. Called exactly once, at the top of `sk_repl()`
|
||||
> (`repl.c`) — the actual start of "the interactive REPL itself", after boot/POST have both
|
||||
> already run under `font_8x16.c`. Lazily loads `fonts:JetBrainsMono-Regular.ttf` from its
|
||||
> capsule and `kmalloc`s a 96-slot raster cache (up from `ttf_words.c`'s 32 — sized to cover
|
||||
> all 95 printable ASCII with no eviction thrash, since a terminal cycles through that whole
|
||||
> set constantly; ~614 KB, checked against the 2 GiB kmalloc heap default before choosing it,
|
||||
> trivial by comparison) on first call only.
|
||||
>
|
||||
> **Cell geometry changes at the switch, deliberately (advisor-reviewed option (a), not
|
||||
> (b)):** `cell_w()`/`cell_h()` are now mode-aware — `font_8x16`'s fixed 8×16 in bitmap mode,
|
||||
> a provisional 12×24 in TTF mode (`600/1000 × 20px = 12px` exactly, using 4.4i's own
|
||||
> confirmed-uniform `hmtx` advance width so the fixed-cell grid tiles cleanly; final REPL
|
||||
> text size is 4.4m's decision, not this item's — marked provisional throughout). Since the
|
||||
> grid changes, `vt100_enable_ttf()` re-derives `cols`/`rows` from the new cell size and
|
||||
> clears the screen, the same as `vt100_init()` itself does — safe because this runs once, at
|
||||
> a point where nothing worth preserving is on screen yet.
|
||||
>
|
||||
> **Also fixed the second call site 4.4i flagged**, not just `draw_cursor_glyph()`'s:
|
||||
> `erase_line_range()` no longer draws a per-cell blank glyph (`font_8x16`-specific, and
|
||||
> already inconsistent with `erase_display(2)`'s full-screen case, which used a plain rect
|
||||
> fill). A blank cell is visually identical to a filled background rect regardless of glyph
|
||||
> backend, so it's now one `fb_fill_rect()` call for the whole erased range — simpler *and*
|
||||
> mode-independent, closing 4.4i's inconsistency finding rather than carrying it forward.
|
||||
>
|
||||
> Underline positioning (the third 4.4i finding, `UNDERLINE_ROW` hardcoding "row 14 of 16")
|
||||
> is branched per-mode: unchanged in bitmap mode, placed 2px below the TTF baseline in TTF
|
||||
> mode — no equivalent fixed row exists there since this parser doesn't read `hhea`
|
||||
> underline metrics (`ttf.h`), so this is provisional too.
|
||||
>
|
||||
> **Three-arch verified:** amd64 (`logs/20260811-194937/amd64/`), aarch64
|
||||
> (`logs/20260811-195246/aarch64/`), riscv64 (`logs/20260811-195446/riscv64/`) — all reach
|
||||
> `ok>`, POST `Failed: 0`, identical dict-hashes across all three (confirming the TTF switch,
|
||||
> which only runs after POST, has no effect on the parity-hashed dictionary state). amd64
|
||||
> screendump, full and zoomed on the REPL tail:
|
||||
> [evidence/amd64/qemu-screenshot-20260811-195041-4.4j-ttf-repl.png](evidence/amd64/qemu-screenshot-20260811-195041-4.4j-ttf-repl.png),
|
||||
> [evidence/amd64/qemu-screenshot-20260811-195041-4.4j-ttf-repl-zoom.png](evidence/amd64/qemu-screenshot-20260811-195041-4.4j-ttf-repl-zoom.png)
|
||||
> — real proportional JetBrains Mono letterforms on the version banner, CLI banner, and
|
||||
> `ok>` prompt, visibly distinct from every prior screenshot's blocky bitmap font; `[Hera]`
|
||||
> stays orange, `ok>` stays cyan (4.4h unaffected). Boot/POST (everything above the visible
|
||||
> tail) is unchanged `font_8x16.c` output, confirmed by this same screendump showing nothing
|
||||
> else on screen — `erase_display(2)` at the switch point cleared it, same behavior as every
|
||||
> screenshot since 4.4c.
|
||||
>
|
||||
> **Known, pre-existing, not touched here:** the mangled `â[box][box]` where an em-dash
|
||||
> should read (`"FORTH-79 interpreter — type BYE..."`) is `vt100_putc()`'s byte-oriented
|
||||
> pipeline treating each byte of the UTF-8 em-dash as its own codepoint — `TTF-TEXT`'s own
|
||||
> word decodes UTF-8 (`ttf_words_decode_utf8()`), but `vt100.c`'s character path never did,
|
||||
> in *either* glyph mode. Confirmed pre-existing by checking earlier font_8x16-mode
|
||||
> screenshots (4.4f/4.4h): the same line already rendered wrong there too (garbled as "tgpe
|
||||
> BYE" etc.) — not a 4.4j regression, a longstanding gap in `vt100.c` unrelated to which font
|
||||
> backend draws the (wrong) glyph.
|
||||
>
|
||||
> **CANVAS scroll-box text**, per this item's original done-when: 4.4n/4.4o build that box as
|
||||
> separate, later items — this item's job was making sure the *same* TTF renderer will serve
|
||||
> it once it exists, not building the box itself. No box exists yet, so this is deferred by
|
||||
> construction, not skipped.
|
||||
|
||||
- [ ] **4.4k — Live-verify ANSI color end-to-end.** Depends on 4.4j. Inject an SGR color
|
||||
escape sequence (`ESC[3xm`/`ESC[9xm`/256-color) over serial and confirm it visibly changes
|
||||
`TTF-TEXT`-rendered glyph color in a screendump — the parser and the retargeted draw call
|
||||
|
||||
Reference in New Issue
Block a user