When we scribble underneath a TRANSPARENT or ANNIHILATED
sprixcell, or even an OPAQUE or MIXED one in Kitty, we
needn't invalidate the sprixel. Perform these checks for
less aggressive invalidation, eliminating the flicker we
were seeing in xray using Kitty. Closes#1522.
In Sixel, we map the alpha value to either 0 or 255, as
it has no alpha concept. Kitty can freely reproduce eight
bits of alpha, so go ahead and use them. Improves image
quality of translucent bitmaps in Kitty at the expense of
some behavioral divergence depending on bitmap backend.
Sixel: detect SPRIXCELL_TRANSPARENT cells and mark them as such.
sprixel_invalidate: fix copy-and-paste, want both TRANSPARENT and
ANNIHILATED to block progression to INVALIDATED. add gigantic
comment detailing the state machine. #1537, #1522, #1527, #1483.
When the damaged cell of a sprixel is actually entirely
transparent (or annihilated), there's no need to invalidate
it. Check for this in the TAM in sprixel_invalidate(). Good
optimization, and eliminates a lot of the flicker in `xray`
on Kitty described in #1522.
cell_release() and cell_duplicate() were deprecated in 2.2.6,
but replaced with static inlines. this breaks the abi, forcing
recompiles from client programs. restore them as exported
functions.
Some terminals (foot makes this claim explicitly) can draw
sixels more quickly when P2 is 0 than when P2 is 1. Since
we're already detecting transparency for the TAM matrix, do
the same globally, and prepare a sixel_p2_e value-result
parameter based on the results. If there are no transparent
pixels, emit P2=0 #1527.
At least mlterm unhides the cursor after emitting a
Sixel, even if it was hidden beforehand. Track this
behavior using 'sprixel_cursor_hack' in the tinfo cache.
Set this based on an "mlterm" TERM heuristic match.
When it is set, supply the 'civis' capability as
cursor_hack in blitterargs, and emit it at the end of
the sixel in sixel_blit() #1524.
Now that we explicitly set P2=1, we can safely emit a "Set Raster
Attributes" command, to tell the terminal the final size of the image
up front.
Also fix the ‘pad’ parameter (horizontal aspect ratio); XTerm rejects
sixels with pan or pad set to 0.
This indicates that empty pixels should "remain at their current
color". I.e. it makes them transparent.
This is in contrast to P2=0|2, where empty pixels are filled with the
"current background color" (which is either sixel color register #0,
or the current ANSI background color, depending on terminal and its
sixel implementation).
Note that due to what is most likely a bug, XTerm will behave as if
P2=1 if P2 is either left unset, or explicitly set to 0 or 2, as long
as we do *not* emit a "Set Raster Attributes" command.
the media code that makes up non-core libnotcurses called
into lookup_rgba(). instead, have them use the new
funtion ncvisual_blitter_geom() to access the actual blitter
being used. we can then hide lookup_blitset(), which ought
never have been exported. closes#1519.
Require a known-good TERM heuristic match to enable
quadrants (NCBLIT_2x2); they otherwise decay to halves
(NCBLIT_2x1). The only terminal that supports quadrants
but does not support sextants is the Linux console, where
we program quadrants directly into the font table,
like a beast. Closes#1517, and #1298 if we're lucky.
deprecate ncvisual_geom() in favor of new ncvisual_blitter_geom(), which allows caller to get the blitter used. replace the checks and calculations in ncvisual_render() with a call to ncvisual_blitter_geom(), unifying the two paths (and eliminating several bugs in the unloved ncvisual_geom()).
if we go into ncvisual_render() looking to render a number
of rows not evenly divisible by the scaling factor, we need
to get an extra row (duh). correct ncvisual_render_cell() to
reflect this. the blitters already know to fill this line in
with transparency wherever the image is not defined. fix up
rotation unit tests to reflect this. closes#1513.