FABRIC.md item 4.4z: draw the scroll box's visible border

draw_box_border() (vt100.c) strokes four 1px edges around the 640x480
CANVAS box, reusing the same border-gray constant the REPL strip's
border lines use (renamed VT100_STRIP_BORDER_GRAY -> VT100_BORDER_GRAY
since it's now shared -- one pinned color decision, 4.4w, not two).
Called from erase_display()'s box-scoped branch so the border survives
every box clear (the initial one and any later ESC[2J), not just the
first.

Verified: three-arch clean QEMU boot + logs, amd64 screendump showing a
full rectangle outline around the box, visually distinct from the strip
below it.

Punch list §25 item 4.4z complete.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-12 15:07:04 -04:00
co-authored by Claude Sonnet 5
parent 91742e02f4
commit b21aa50a14
11 changed files with 33998 additions and 4 deletions
+27 -3
View File
@@ -113,7 +113,10 @@ static ttf_raster_cache_t g_ttf_cache;
* --------------------------------------------------------------------- */
#define VT100_STRIP_GAP_PX 15u /* baseline-to-border-line gap, both sides, mirrored */
#define VT100_STRIP_BOX_GAP_PX 8u /* gap between the strip's top border and the box's bottom edge */
#define VT100_STRIP_BORDER_GRAY FB_RGB(0xAA, 0xAA, 0xAA) /* FB_ANSI_PALETTE[7] */
#define VT100_BORDER_GRAY FB_RGB(0xAA, 0xAA, 0xAA) /* FB_ANSI_PALETTE[7]; shared by the
strip's border lines (4.4x) and
the box's own border (4.4z) --
same pinned decision (4.4w) */
#define VT100_STRIP_TEXT_WHITE FB_RGB(0xFF, 0xFF, 0xFF)
#define VT100_STRIP_LEFT_MARGIN_PX(fbw) (((fbw) - VT100_BOX_W) / 2u) /* aligned under the box */
@@ -344,8 +347,8 @@ void vt100_strip_draw(const char *text)
VT100_STRIP_TEXT_WHITE, VT100_DEFAULT_BG);
}
fb_fill_rect(0, top_line_y, fbw, 1u, VT100_STRIP_BORDER_GRAY);
fb_fill_rect(0, bottom_line_y, fbw, 1u, VT100_STRIP_BORDER_GRAY);
fb_fill_rect(0, top_line_y, fbw, 1u, VT100_BORDER_GRAY);
fb_fill_rect(0, bottom_line_y, fbw, 1u, VT100_BORDER_GRAY);
}
static void draw_cursor_glyph(uint8_t ch)
@@ -679,6 +682,26 @@ static void erase_line_range(uint32_t row, uint32_t c0, uint32_t c1)
fb_fill_rect(px_of(c0), py_of(row), (c1 - c0) * cell_w(), cell_h(), g_vt.bg);
}
/* FABRIC.md item 4.4z: stroke the scroll box's own visible border. 4.4t
* confined text to the box's coordinate space but never drew a rectangle
* outline on it -- the edges were implicit (where text stops), not
* drawn. Four thin edges, 1px each, same gray as the strip's border
* lines (4.4x/4.4w -- one shared color, one design decision). Called
* from erase_display()'s box-scoped branch below, so the border survives
* every box clear (the initial one at vt100_enable_ttf() time and any
* later ESC[2J), not just the first. */
static void draw_box_border(void)
{
fb_fill_rect(g_origin_x, g_origin_y,
VT100_BOX_W, 1u, VT100_BORDER_GRAY);
fb_fill_rect(g_origin_x, g_origin_y + VT100_BOX_H - 1u,
VT100_BOX_W, 1u, VT100_BORDER_GRAY);
fb_fill_rect(g_origin_x, g_origin_y,
1u, VT100_BOX_H, VT100_BORDER_GRAY);
fb_fill_rect(g_origin_x + VT100_BOX_W - 1u, g_origin_y,
1u, VT100_BOX_H, VT100_BORDER_GRAY);
}
static void erase_display(int mode)
{
if (mode == 0) {
@@ -701,6 +724,7 @@ static void erase_display(int mode)
* full-screen in bitmap mode as before (boot/POST unaffected). */
if (g_glyph_mode == VT_GLYPH_TTF) {
fb_fill_rect(g_origin_x, g_origin_y, VT100_BOX_W, VT100_BOX_H, g_vt.def_bg);
draw_box_border();
} else {
fb_fill_rect(0, 0, fb_width(), fb_height(), g_vt.def_bg);
}