With word wrap on, VisibleByteRange mapped the viewport TOP from visual
to logical line space (WrapIndex.LineForVisual) but left the viewport
BOTTOM as the raw visual-line number and used it as a LOGICAL index.
The window therefore fetched (viewport lines + every wrapped line above
the viewport) of real text: an over-fetch that grew without bound with
scroll depth. Measured on a 2.9 MB file with wrap on: the shaped window
was ~3.7 KB at 300 KB depth but ~17.4 KB at 2.8 MB depth, costing
12 ms of shaping and 40 ms of frame draw per frame there — scrolling
visibly degraded the further down the file you got.
Map the bottom through LineForVisual exactly like the top: the logical
line containing the viewport's bottom visual line is the correct end,
and since each logical line yields at least one visual line the window
still always covers the viewport. The fetch is now viewport-bounded at
every depth (window flat at ~1 KB across 300 KB..2.8 MB in the test
file; deep frames drop from 40 ms to <4 ms).
Also drop the instrumentation added while diagnosing.