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
4.1 KiB
| name | description | metadata | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| schunix-text-rendering | The text layer that replaces the 8x16 character-cell grid — glyph metrics, surfaces, coverage blending, UTF-8. |
|
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_opsbehind 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.hdefinesfont_datarather than declaring it, so including it from a second file duplicates the symbol under-fno-common. text.c declaresextern 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.