Sixty-five headers sat side by side in include/, so `#include "irq.h"` said nothing about where irq.h was or what it belonged to, and errno.h, stat.h and fcntl.h at the top shadowed the system's for any host tool built with -I./include. They are in folders now -- arch/ core/ fs/ dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and every include names the folder, as Linux's do: "core/proc.h". Done mechanically and checked the hard way: the kernel built from this tree disassembles identically to the one built from the tree before it. The full image boots, and userland is the same set of programs. Paths in docs and comments follow; docs/guides/layout.md has a table of what is where, and tools/fix-includes.py rewrites old-style includes from the folders in the tree, for code written before this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
84 lines
4.1 KiB
Markdown
84 lines
4.1 KiB
Markdown
---
|
|
name: schunix-text-rendering
|
|
description: "The text layer that replaces the 8x16 character-cell grid — glyph metrics, surfaces, coverage blending, UTF-8."
|
|
metadata:
|
|
node_type: memory
|
|
type: project
|
|
originSessionId: 9d8a2aef-bcf0-47a0-96c6-f706efab4a95
|
|
modified: 2026-08-08T22:45:34.934Z
|
|
---
|
|
|
|
Built 2026-08-09. `include/gfx/text.h` + `kernel/dev/text.c`. Nexoniarz: "using ANSI
|
|
fonts in 2026 is a not funny joke."
|
|
|
|
**The font was never the problem — the grid was.** The console indexes
|
|
`font_data[256][16]` and steps the cursor eight pixels. A grid cannot do
|
|
variable-width glyphs, cannot position text off a multiple of eight, cannot
|
|
anti-alias, and cannot represent a codepoint above 255. A nicer bitmap fixes
|
|
none of that.
|
|
|
|
Three decisions that make the layer worth having:
|
|
|
|
- **Glyphs carry metrics** (`w`, `h`, `bearing_x/y`, `advance`). Variable-width
|
|
text *is* that; everything else follows. `text_measure()` exists because you
|
|
cannot centre or lay out anything without it.
|
|
- **Draws into a `struct surface`, not the screen.** `{pixels, stride, width,
|
|
height}`. A compositor draws off-screen and presents; rendering that writes
|
|
straight to the VGA aperture is useless to it. Works on the virtio-gpu back
|
|
buffer, a window buffer, or the VGA aperture, none of which know about each
|
|
other.
|
|
- **`struct font_ops` behind an interface, and glyphs carry 8-bit *coverage*,
|
|
not bits.** The bitmap font fills it with 0 and 255 only, which costs nothing
|
|
— and a TrueType rasteriser then plugs in with no caller changing, because it
|
|
already has somewhere to put anti-aliased edges. `blend_px()` reads the
|
|
destination for the same reason.
|
|
|
|
Pen position is on the **baseline**, as every non-terminal text API does, so
|
|
glyphs of different heights sit on a common line.
|
|
|
|
**Verified** with `echo t > /proc/sysrq` + `tools/textshot.ps1`: text at x=61
|
|
and x=63, a checkerboard background visible *around* the glyphs (no cell boxes),
|
|
`┌─┐ █▓▒░ ° ± → •` above U+00FF, and a string measured at 160 px then centred on
|
|
it. The old console renders in the same screenshot with solid cell backgrounds —
|
|
a useful side-by-side.
|
|
|
|
## Traps hit
|
|
|
|
- `include/gfx/font.h` **defines** `font_data` rather than declaring it, so
|
|
including it from a second file duplicates the symbol under `-fno-common`.
|
|
text.c declares `extern unsigned char font_data[256][16];` instead; the header
|
|
is generated data and is better left alone.
|
|
- The built-in font is **CP437, not Latin-1** (known trap in this codebase).
|
|
`to_cp437()` maps the ~25 codepoints worth having — box drawing, blocks,
|
|
arrows, degree. **That table exists to be deleted** when a real font lands; it
|
|
is a bridge, not a design.
|
|
- A missing glyph draws U+25A1 or `?`, never nothing. Silently shorter text
|
|
hides the fault.
|
|
- `utf8_next()` always advances, even on malformed input — a decoder that does
|
|
not is a hang, not a rendering artefact. Rejects surrogates and overlong
|
|
encodings.
|
|
|
|
## The typefaces, decided 2026-08-09
|
|
|
|
- **Roboto** for the DE / WM / compositor. **Apache-2.0** -- the same licence as
|
|
Schunix, so it needs only a NOTICE entry.
|
|
- **JetBrains Mono** for the terminal / TTY. **SIL OFL 1.1**, and it declares
|
|
**no Reserved Font Name** (checked: the copyright line names none; the only
|
|
"reserved font name" hit in OFL.txt is the licence defining the term). So a
|
|
modified version may keep the name -- which matters, because pre-rasterising
|
|
a font into bitmaps at build time *is* a modification and an RFN would have
|
|
forbidden keeping the name on the result.
|
|
|
|
OFL keeps the font under OFL inside an Apache-2.0 system, does not reach
|
|
anything else, and only forbids selling the font on its own. Both fetched and
|
|
verified at source, not assumed. Full note in `docs/licensing.md` ("Fonts").
|
|
|
|
Neither is in the tree yet -- there is no rasteriser to use them, and shipping
|
|
a TTF nothing can read would be dead weight.
|
|
|
|
## Not done
|
|
|
|
The console still uses the old path; nothing is ported to this yet. Porting
|
|
`vga_putc` onto it is the obvious follow-up and would delete the cell grid for
|
|
good. A TTF rasteriser is a separate provider behind `font_ops` — the layer is
|
|
what was blocking it, and it no longer is.
|