The stage-2 GPU application half, framing revision 4:
- apply_font_facts transaction: fail-closed wire validation
(600..=7200 centi-px; deserialized protocol input, not the Lua
courtesy check), painted-before decision from the ACTUAL caret rect
intersected with the drawable code clip, four-style monospace
resolution with total fallback to the sanitized default, derived
metrics + measured advance, atomic re-metric/re-size, status
shaping-cache drop, reshape at the retained scroll, drawable-width
settle pass, conditional caret re-follow, minimap cache drop.
- Advance probe: fixed ASCII digits shaped in the resolved family at
the new code metrics; the NORMAL-face advance is authoritative for
gutter geometry (mono_advance no longer trusts an arbitrary code
glyph once measured), and the selected/default ratio scales the
const-based fallbacks -- the default family is ratio 1 by
construction, so never-set/reset stays byte-identical.
- sync_buffer_dimensions: metrics + REAL drawable dimensions change
atomically on all seven buffers via set_metrics_and_size; the code
buffer wraps at the painter's clip width; resize() routes through
the helper (closes the old four-of-seven skew) and applies the same
painted-before follow policy.
- Rows stay rows: Wrap::None on the menu/minibuffer/completion
buffers at assembly and (idempotently) in the transaction.
- Normalized code-buffer Scroll residual: slice-local line == 0
invariant with a vertical pixel residual; horizontal always
discarded (glyphon 0.11 never applies it). normalize_code_scroll
folds line advances into whole-file scroll_top (strictly advancing
origin, EOF clamp) after EVERY final code shape. BufferSnapshot
resets the residual (buffer-scoped view state); explicit
wheel/minimap jumps clear it -- including a wheel-up whose only
remaining motion IS the residual.
- Byte-to-layout projection: code_byte_to_projected inverts the
line_chunk_cache chunk projection (earliest projected boundary for
adornment anchors, the left-gravity caret), then code_byte_px uses
cosmic-text's layout_cursor so wrap boundaries select the same
visual run shape_until_cursor scrolls to. caret_rect and
completion_anchor_px are now visual-run aware instead of scanning
the source line's first run.
- ensure_caret_painted (coarse source-line follow, then
shape_until_cursor, discard Scroll.horizontal, normalize) shared by
the CursorByte arm (under its existing moved gate -- fixes the
pre-existing wrapped-line follow hole), the optimistic edit
completion, the font transaction, and resize.
- Gutter mirrors the code layout's visual runs: continuation blanks
for wrapped runs plus the same normalized vertical scroll, so line
numbers stay row-aligned when wrapping appears.
- assemble() shapes the initial text through reshape() so the
buffer.lines <-> line_chunk_cache invariant holds from
construction (the projection inversion depends on it).
PMACS_REQUIRE_GPU suite 69/69; clippy -D warnings and fmt clean.
Acceptance tests for items 9-11/13-14/16-19 land in the next commit
with the embedded test faces.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VoiEyuPjoBhvwACf8HAnLB