TermBuf::Grid
Stability: internal
A rectangular array of cells.
Cells live in one flat slice, so a row is a contiguous Slice view and
scrolling is a run of memmoves. Alongside them the grid keeps a hash per
row, recomputed lazily, which is what lets the painter recognise a scrolled
band without comparing cells.
The grid is the only place that knows a cluster can occupy more than one cell, and it never lets those cells get out of step: writing to any of them blanks all of them first.
Constants
Constructors
Instance methods
Whether both grids hold the same cells. Damage is not compared: it says what has yet to be painted, not what is on the screen.
Writes one cell without regard for wide character pairing. Callers that
place characters want #place; this is for filling, scrolling, and the
internals of #place itself.
Blanks any cluster straddling the left or right edge of rect, so that filling or scrolling the rectangle cannot tear one apart.
The cells lying outside rect keep the style they had and lose only their share of the glyph. A rectangle operation has no business changing how a cell outside it looks, and giving those cells the incoming style would paint the rectangle wider than it is — on the rows where a cluster happens to straddle, and not on the others.
Replaces this grid's contents with other's, which must be the same size. Used to bring the front buffer up to date once a paint has been written to the terminal.
Blanks every cell of the cluster overlapping column x, if one covers more than that column. A cell that leads nothing is left alone.
Every cell of it takes blank, which for #place is the style being
written: a terminal erases what it displaces in whatever the current
style is, having no memory of what the cell used to be, and this follows
it. The rectangle operations want a different answer and use
#clip_wide.
The columns the cluster covering (x, y) occupies. A cell that leads nothing covers itself alone, and so does a continuation at the left edge with no lead left to walk to.
The column the cluster covering (x, y) begins at, which is x itself unless that cell is a continuation. Off the grid, x.
Places cell at (x, y), blanking every cell of any cluster it displaces. Returns the columns consumed, or zero when the cluster will not fit before the right edge and nothing was written.
Resizes the grid, keeping whatever content still fits anchored at the top left and filling the rest with blank. Every cell is left marked dirty: the terminal's own reflow is not something the buffer can predict, so the next paint has to be a full one.
FNV-1a hash of row y, recomputed only when the row has been written to since it was last asked for.
Moves the contents of rect by lines rows, positive scrolling up so that content moves toward the top and blank rows appear at the bottom.
Each row that leaves the rectangle is yielded before being overwritten. The yielded slice is a view into the grid, valid only until the block returns, so a consumer keeping the row must copy it.
Scrolls without inspecting the rows that leave.
Renders the grid as text, one line per row, for specs and debugging. Continuation cells contribute nothing, so a wide character appears once.
Starts marking damage alongside the grid's own on every write.
One Sink is one watcher: each output painting this grid needs its own
record of what it has yet to draw, because they paint at different times
and one committing must not tell another its rows are clean. There are
one or two of these, so marking them is a loop over a short array rather
than anything cleverer.