capsules/fonts: JetBrainsMono-Regular.ttf as a raw-blob capsule (item 4.3.7b)

mkcapsule.c already ingests arbitrary non-.4th files as raw byte blobs
(validate_forth_blocks only applies to .4th filenames), so no hex/base64
text-encoding or tool changes are needed -- corrects the design premise
in FABRIC.md's 4.3.7b item text (see the FABRIC.md correction note this
commit carries). ttf_load_from_capsule() resolves the font capsule by
name, validates its content hash, and points ttf_font_t at the capsule
arena bytes directly, zero-copy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-10 21:50:35 -04:00
co-authored by Claude Sonnet 5
parent 70b6918279
commit 2ef8d26c6f
5 changed files with 139 additions and 2 deletions
+46 -1
View File
@@ -4753,10 +4753,31 @@ document and committing that amendment as its own item.*
> 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
- [x] **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.
> **Done 2026-08-10, on the corrected design (§27.7's 2026-08-10 correction, not the
> hex/base64 premise this item's own text was written against — see that note for the
> full story of why).** `capsules/fonts/JetBrainsMono-Regular.ttf` added; `mkcapsule.c`
> ingests it unmodified as capsule `fonts:JetBrainsMono-Regular.ttf` (raw bytes, no text
> encoding, no tool changes needed — it already handles arbitrary files). Verified two ways:
> `mkcapsule --lint capsules/` passes clean (29 `.4th` files, 0 violations — the `.ttf`
> isn't `.4th` so lint correctly skips it rather than misapplying text-block rules to it);
> and a byte-exact round-trip check — built `capsule_generated.c`, extracted the
> `capsule_arena[]` bytes at the font's descriptor `offset`/`length` (270224 bytes) back out
> with a throwaway script, `cmp`'d against the source `.ttf`: identical.
>
> No `kmalloc` copy, since none is needed: `ttf_load_from_capsule()` (new, in `ttf.c`/`ttf.h`,
> `#ifdef __STARKERNEL__`-gated) resolves the capsule via `capsule_find_by_name()`, validates
> its content hash via `capsule_validate(..., verify_hash=1)`, and points `ttf_font_t` at the
> `capsule_arena` bytes directly (`capsule_get_payload()`) — zero-copy, since the arena is
> already a `const` array baked into the kernel image and `ttf_parse()` only ever reads
> through a `const uint8_t*`. Compiles clean (`-Wall -Werror -Wextra`) both with and without
> `-D__STARKERNEL__`, against the real amd64 `Makefile.starkernel` flags including
> `-include include/starforth_config.h -DPARITY_MODE=0`. Not callable from FORTH yet — no
> capsule-birth/init.4th wiring exists for it; that's 4.3.7e's job once `TTF-TEXT` needs it.
> Same "not a kernel-boot change" posture as 4.3.7/4.3.7a; no three-arch QEMU run applies.
- [ ] **4.3.7c — Rasterization.** Bézier curve flattening to line segments (reusing the
existing `LINE`/Bresenham primitive where practical), then fill. Antialiasing approach is
@@ -5561,4 +5582,28 @@ font (not chosen yet — needs a licensing check before any specific font is emb
SIL OFL 1.1 (permissive, embedding/redistribution allowed) — resolves the licensing-check
blocker above.
**Correction 2026-08-10, superseding both the paragraph above and decision #3:** the
"open question" recorded above was wrong — a grep-shallow check (`grep -n "blob\|binary"`)
missed the actual mechanism. A full read of `tools/mkcapsule.c` shows raw-binary-blob
ingestion already exists, end to end, and decision #3's hex/base64-encoding premise is
unnecessary:
- `process_file()` reads *any* regular file under `capsules/` (recursively, via `nftw`) into
a `CapsuleEntry` as raw bytes. `validate_forth_blocks()` — the 64-char/16-line text check —
only runs when the filename ends in `.4th`; every other file is accepted as-is, unvalidated
and unmodified.
- `generate_output()`'s payload-arena emission (`const uint8_t capsule_arena[] = { 0x%02X, ...
}`) is a plain byte array, not a string literal — binary-safe, no NUL-termination
assumption, already exercises correctly on non-text content.
- Kernel-side, `capsule_find_by_name()` (`include/starkernel/capsule.h`) returns a
`CapsuleDesc*` (`offset`/`length` into the arena) independent of `capsule_exec_payload()`
(`capsule_loader.h`) — lookup and FORTH execution are already separate calls. A caller can
fetch a capsule's raw bytes by name and simply never call `capsule_exec_payload()` on it.
So: drop `.ttf` bytes into `capsules/` as-is (e.g. `capsules/fonts/JetBrainsMono-Regular.ttf`
→ capsule name `fonts:JetBrainsMono-Regular.ttf`), fetch via `capsule_find_by_name()`, done —
no hex/base64 text-encoding, no `mkcapsule.c` changes, no parallel asset mechanism. Decision
#3 is superseded by this. 4.3.7b's remaining work is just wiring a `kmalloc` copy (or
direct-arena reference — 4.3.7b's own call) behind that lookup.
*Refs:* §25.5 (punch list), GAP-B2.