doc: note GlyphLayout window-relative offset invariant

Add the invariant that GlyphLayout offsets are relative to
IMEWindowStartByte and that cursor positioning must add/subtract the window
base. Record the second tap-to-cursor fix (base offset) alongside the earlier
tapLocalY fix in the development plan.
This commit is contained in:
Greg Pomerantz 2026-08-16 20:59:42 -04:00
parent 3bc3ed3530
commit 16c39f4221
2 changed files with 15 additions and 4 deletions

View File

@ -210,6 +210,14 @@ Only the visible byte range is shaped and drawn each frame:
memory to ~1 GB for a 10 MB file. Shaping ~50 lines keeps it small and flat.
- The renderer reports `GlyphLayout` back via `LayoutChan`; logic derives
`LastLineY` for scroll clamping and the max scroll offset.
- **`GlyphLayout` offsets are window-relative.** The shaper only sees the
visible window, so `GlyphLayout.ByteOffsets` (and `VisualLineStarts`, `Y`)
are relative to `IMEWindowStartByte`, not the file start. Any logic-goroutine
code that maps a glyph offset to the absolute `CursorPosition` (tap-to-position,
Home/End, vertical cursor move) must add the window base
(`IMEWindowStartByte`) before storing the cursor and subtract it before
searching the offsets. For a whole-file window the base is 0 (a no-op).
Getting this wrong snaps the cursor to the window top on scrolled large files.
### 6.3 IME (Android soft keyboard)

View File

@ -16,11 +16,14 @@ rapid-commit desync fix (snippet/selection dedup). Phase 6 (2026-08-16) added a
default-off in-app performance profiler and verified: scroll does not degrade at
large offsets (10 MB file), scroll clamping is exact across 2→130,955-line
files, and memory plateaus ~250 MB (no leak). Phase 7 (2026-08-16) verified
tap-to-position-cursor on-device and found + fixed a real bug: for large files
scrolled deep, `SetCursorFromPoint` clamped the cursor to the bottom of the
tap-to-position-cursor on-device and found + fixed two real bugs: (1) for large
files scrolled deep, `SetCursorFromPoint` clamped the cursor to the bottom of the
viewport (a content-space vs window-relative Y mismatch from the Phase 3 windowing
refactor); it only worked on small files by luck. Fixed (`tapLocalY`), with
regression tests. Remaining: real-device swipe/autocorrect sign-off (the
refactor); fixed with `tapLocalY`. (2) the `GlyphLayout` byte offsets are
window-relative but the four cursor functions (tap, Home, End, vertical move)
treated them as absolute, so the cursor snapped to the window top; fixed by adding
the `IMEWindowStartByte` window base at each cursor boundary (`glyphBase`). Both
have regression tests. Remaining: real-device swipe/autocorrect sign-off (the
emulator's AOSP/Gboard keyboard is a proxy).
## 1. Decision summary (updated)