Commit Graph

3 Commits

Author SHA1 Message Date
Levi Neuwirth b3d326d937 fix(font): close stage-2 GPU behavioral findings
Normalize source bytes to representable shaped-cluster cursors and
reflow the code buffer whenever gutter or minimap geometry changes.

Measure alternate monospace advances across complete shaped runs and
load hermetic fixture faces before FontSystem construction. Complete
the rendered geometry, popup, caret, snapshot, and fixture acceptance
coverage, and record the review fixes in framing revision 5.
2026-07-18 15:29:25 +01:00
Levi Neuwirth fe65fddae5 test(font): GPU acceptance for apply_font_facts + caret substrate
Twenty-one new headless tests covering the GPU-side acceptance items of
docs/gpu-set-font-framing.md (9-14, 16-19):

-  9: size route re-derives metrics; (None, None) reset reproduces
      the never-set frame byte-for-byte
- 10: 600/7200 bounds render; minibuffer dropdown windows its rows
      above the band at the derived row height; context menu keeps
      the clipped route with coherent hit geometry
- 11: wrapped caret survives 16->72->6 px; an optimistic insertion
      that wraps a new bottom row follows immediately and its
      confirming CursorByte needs no second repair; overscan caret
      never snaps the viewport; narrowing resize re-follows via the
      coarse + visual-run + fold pipeline; adornment projection
      shifts the caret past injected text with left gravity at the
      anchor; the CursorByte arm follows into a wrapped run as a
      normalized sub-line residual; explicit scrolls clear the
      residual (including wheel-up at the clamp edge); the
      minibuffer suspends the follow decision
-  4 (GPU half): BufferSnapshot resets the residual while the font
      preference/metrics survive -- the replacement buffer wraps
      too, so the EOF clamp cannot mask a leaked residual
- 12: unknown + proportional families fall back; the four-style
      gate rejects a proportional BOLD sibling the normal-only
      query would accept; a valid second monospace family resolves,
      changes the ink, and resets cleanly; the parameterized
      sanitizer removes exactly the same-family proportional
      collision
- 13: the "\0" sentinel defeats the status string-equality gates
- 14: a shrinking visible slice re-declares the scoped viewport
- 16: 0/599/7201/u32::MAX reject the whole message, state untouched
- 17: metrics + drawable dimensions atomic on all seven buffers,
      resize symmetric via Buffer::size()
- 18: popup rows never wrap (Wrap::None + unique line_i per run)
- 19: with line numbers and a context menu open over an EMPTY
      buffer, the measured probe advance drives gutter reservation
      and menu hit width (fixture ratio exactly 1.2 vs the bundled
      default); reset restores the exact geometry and frame

Family routing is hermetic: four generated fixture faces under
pmacs-gpu/fonts/test/ (second monospace at 720/1000, a proportional,
and a "Pmacs Test Family" whose NORMAL face is monospaced but whose
BOLD face is proportional), built by the committed generate.py --
provenance and license in LICENSE.txt beside them. fontdb requires a
PostScript name (nameID 6), which the generator sets explicitly.

assemble() now routes construction through sync_buffer_dimensions
too: shape_until_cursor and wrapping must use the painter's clip
from the first frame -- a v16 daemon never sends the FontFacts that
would sync them later (found by the CursorByte-follow test: the
caret parked in the status band at surface-height dims).

Every protection was bitten (temporarily reverted, its test observed
failing, then restored): wire validation, CursorByte visual-run
follow, painted-before gate, projection inversion, Wrap::None,
four-style gate, sanitizer, status sentinel, normalize fold,
scroll_by_lines residual clear, BufferSnapshot residual reset, the
all-seven dimension helper, and the optimistic-completion follow.
The snapshot-reset test was strengthened after its first bite did
NOT fail (a short replacement buffer let cosmic's EOF clamp zero the
residual anyway).

PMACS_REQUIRE_GPU suite 90/90; clippy -D warnings and fmt clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VoiEyuPjoBhvwACf8HAnLB
2026-07-18 11:46:44 +01:00
Levi Neuwirth a706864e04 session 2: pmacs-gpu workspace + wgpu/winit/glyphon hello-world
Adds the pmacs-gpu binary crate to the workspace. wgpu 29.0 + winit
0.30 + glyphon 0.11 (cosmic-text 0.18 via re-export) + pollster +
env_logger; pmacs-protocol in the dep graph but not consumed yet
(session 3 wires the attach loop).

The binary opens an 800x200 window titled 'pmacs-gpu hello-world',
sets up wgpu against its surface, configures glyphon with the bundled
JetBrains Mono Regular, and renders 'hello, pmacs' once per redraw.
Close button or Escape exits. Resize re-configures the surface and
glyphon viewport. Surface acquisition matches wgpu 29's
CurrentSurfaceTexture enum (success/suboptimal render through; lost/
outdated re-configure; timeout/occluded skip the frame).

Bundled assets: pmacs-gpu/fonts/JetBrainsMono-Regular.ttf (268 KB)
and pmacs-gpu/fonts/OFL.txt. Font shipped as required by the SIL
Open Font License 1.1.

One finding surfaced during the move and absorbed under rule (iii)
of the framing pass (small / no structural change): the design doc
recorded JetBrains Mono as Apache 2.0; the actual license has been
OFL since the family's open-source release. Doc corrected in
docs/pmacs-gpu-design.md.

Gates: cargo fmt + cargo clippy --all-targets -D warnings clean for
the whole workspace; cargo test --lib still 1314 (pmacs main crate
untouched); m4_acceptance 83; m11_5_semantic_acceptance --features
crdt 2.

Visual confirmation pending — agent environment is headless, so
'window opens, text renders' is user-side validation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:37:26 -04:00