Each batch of new output re-wrapped all N visible lines glyph by glyph,
allocating a fresh segment vector per line; a line evicted at the
10,000-line cap shifted every index, so nothing could be kept. And on
every frame, idle or not, seeding the scanline shading summed the wrap
rows of every line above the view.
- The model numbers its lines and the view keeps one wrap per line,
aligned by that number, so an eviction drops a prefix instead of
forcing a rebuild. New output wraps only the new lines; the layout is
then a prefix sum over the N visible lines, with no measuring and no
per-line allocation.
- The wraps are kept while the wrap width, line height, font size, font
(by ImFont::FontId) and rasterizer density are exactly unchanged. A
line-spacing change only re-sums heights; filters and fold toggles
reuse the cached wraps. A resize drag still re-wraps every visible
line per frame, as before, but reuses their storage.
- The scanline seed is read from the prefix sum: O(1) per frame.
Heights, offsets and segments are bit-identical to the old rebuild. A
font reload at an unchanged size (the colour-emoji toggle) now re-wraps
the console at once; before, it waited for the next line of output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>