Skip to main content

Module index

Module index 

Source
Expand description

The height index: pixel position ↔ row, in O(log n).

This is the structure that makes variable-height rows possible. xtext could skip it because every row was fontsize × subline_count, so “what is at pixel Y” was a division (gtk_xtext_find_char, xtext.c:1339) and the scroll adjustment’s unit was fractional lines (page_size = height / fontsize, xtext.c:919). Both assumptions have to go for an image to be able to be 240 pixels tall.

Why chunked prefix sums and not a Fenwick tree. A Fenwick tree is the textbook answer for prefix sums with point updates, and it is the wrong shape here: it is indexed from a fixed origin, and this buffer grows at both ends (chat-history backfill prepends) and shrinks at the front (scrollback trim). Every prepend would renumber the whole tree.

Instead: rows live in fixed-target-size chunks in a VecDeque, each chunk caching its own summed height, with a lazily-repaired running prefix over the chunks. Front insert pushes a chunk; trim pops one; neither touches the rest. A lookup binary-searches the chunk prefixes and then scans within one chunk, which is bounded by [CHUNK_TARGET].

Estimated heights. A row that has never been laid out reports an estimate rather than forcing a measure, so a resize costs O(visible) instead of xtext’s O(entire scrollback) (gtk_xtext_calc_lines, xtext.c:4395, walks every entry on every width change). The honest cost is that the scrollbar’s extent is approximate until the estimates are replaced. That is survivable precisely because scroll position is anchored to a row rather than to a pixel value — see crate::anchor.

Structs§

HeightIndex
Chunked prefix-sum index over row heights.
Hit
Where a pixel offset lands.