TermBuf::Painter
Stability: internal
Works out the operations that bring the terminal from what it is showing to what the application has drawn.
Two passes. The first looks for whole bands of rows that merely moved, and asks the terminal to scroll them rather than sending them again. The second walks the rows that are still different and emits the changed runs.
The painter mutates the sink's front grid as it extracts scrolls, so that
the second pass diffs against the post-scroll state. That means the bytes it
returns have to actually reach the terminal; a caller that throws them away
must call Sink#invalidate before painting again.
It holds nothing about which screen it is diffing: the front grid, the
damage and the scroll hints all come from the Sink it is handed, so one
painter is one output rather than one buffer.
Constants
A trailing run of blanks longer than this is cheaper to erase than to write spaces over.
What moving the cursor a short distance within a row costs. A gap of unchanged cells cheaper than this to reprint is not worth skipping.
Redrawing a row costs at least this much, so a scroll starts paying for itself once it saves this many rows.
Roughly what a scroll costs in bytes: margins, the scroll itself, and releasing the margins again.
What changing style costs, near enough.
Constructors
Instance methods
What the terminal can do, which decides whether a scroll or an erase is available at all.
Changes what the painter may use. The next paint should be forced, since what is on the terminal was drawn under the old mask.
Whether to write the cell after a glyph that may have painted outside its own columns, even when nothing in that cell changed.
On by default, and there is nothing yet that would turn it off: both terminals measured draw over a neighbouring cell without repainting it first, so ink left there stays there. Nothing predicts which clusters overhang — that is font coverage, and it moved between two fonts covering different scripts — so the cheap conservative rule wins: after anything that is not plain ASCII, write the next cell again. It costs one cell per such glyph per frame and nothing at all on ASCII text.
An application that knows its terminal repaints what it draws over, or that would rather have the bytes, can turn it off.
Whether to write the cell after a glyph that may have painted outside its own columns, even when nothing in that cell changed.
On by default, and there is nothing yet that would turn it off: both terminals measured draw over a neighbouring cell without repainting it first, so ink left there stays there. Nothing predicts which clusters overhang — that is font coverage, and it moved between two fonts covering different scripts — so the cheap conservative rule wins: after anything that is not plain ASCII, write the next cell again. It costs one cell per such glyph per frame and nothing at all on ASCII text.
An application that knows its terminal repaints what it draws over, or that would rather have the bytes, can turn it off.
A cluster the terminal will put in the wrong place, noticed on its way
out, or nil while none has been. Read and cleared by the driver, which
is what turns it into a warning.
Only watched for under Quirk::PerCodePointColumns, and only until the
first one: after that the application has been told, and the cost of
looking goes back to a boolean nothing reads.
Where to leave the terminal's own cursor when the frame ends, or nil to
leave it hidden.
A frame that changes no cells is still worth sending when this has moved: the cursor is what tells someone where they are typing.
Where to leave the terminal's own cursor when the frame ends, or nil to
leave it hidden.
A frame that changes no cells is still worth sending when this has moved: the cursor is what tells someone where they are typing.
The operations that bring sink's terminal up to date with buffer.
Empty when there is nothing to do. The caller writes them out and then
calls Sink#commit.
Forgets what the terminal was last told about its own cursor, so the next frame says it again. For a forced repaint, where nothing on the screen can be taken on trust.
Whether to look. False on every terminal that measures clusters the way this does, and false again once one has been found.
Whether to look. False on every terminal that measures clusters the way this does, and false again once one has been found.