new rendering engine

This commit is contained in:
2026-06-19 02:55:33 +02:00
parent 0a90d6a5d7
commit 81a4167382
53 changed files with 1668 additions and 378 deletions

View File

@@ -0,0 +1,27 @@
# 0004 — Domain-owned rendering, thin DisplayPort
**Status:** accepted
**Date:** 2026-06-19
## Context
Adding text alignment, overflow scrolling, color markup, and theming to the client. These features require text measurement, line wrapping, scroll state management, and markup parsing. The question is whether this logic lives in the domain (client-domain crate) or in each display adapter (ESP32, desktop, terminal).
## Decision
All rendering intelligence lives in client-domain. The DisplayPort trait becomes a thin pixel-pusher with three methods: `draw_text_span`, `fill_rect`, `flush`. The domain's render engine parses markup, wraps text, computes alignment, manages scroll offsets, and emits positioned spans. Adapters only convert `Color(u8,u8,u8)` to native format and draw.
Font metrics are injected into the domain at init as a `FontMetrics` struct (char width/height per FontSize), enabling pure-math text measurement with no hardware callbacks.
## Alternatives considered
**Enriched DisplayPort**`draw_rich_text(spans, bounds, alignment)` with each adapter handling wrapping, alignment, and markup internally. Duplicates complex logic across every adapter. Harder to test — requires hardware or mocks.
**Split ownership** — domain handles markup/scroll, adapter handles wrapping/alignment. Splits a single concern across layers, making behavior inconsistent across clients.
## Consequences
- All text behavior is testable without hardware — pure functions on structs.
- New display adapters are trivial: implement three methods, provide font metrics.
- Domain is coupled to monospace font assumption (width = char_count × char_width). Proportional fonts would require a measurement callback. Acceptable — all current targets use bitmap monospace fonts.
- DisplayPort is a breaking change — existing adapters must be rewritten.