Move sixel reflow from grid_reflow() to sixel_reflow(). This lets us
use internal sixel functions to update the sixels.
Note that grid_reflow() still needs to remap the sixelss coordinates.
When a sixel image crosses the scrollback wrap-around, it is split up
into (at least) two pieces.
We use cursor->point.col for all pieces’ x-coordinate. This caused the
final image to appear sheared, since we do a carriage-return (after a
number of linefeeds) after each piece - this causes the cursor’s
position to be reset to the left margin.
The solution is simple; remember the cursor’s initial x-coordinate,
and use that to position all image pieces.
Closes#151.
This fixes a crash when the emitted sixel extends beyond the right
margin. The crash only happens when there are other sixel images
already emitted.
Fixes part of #151
When copying the image data for the left and right parts of the
splitted images, use the sixel's height, not the cell height.
This fixes a crash when the sixel didn't cover the entire cell height.
The logic that breaks out of sixel loops does not work for rows that
has already wrapped around.
Thus, we need to destroy sixels that are about to be scrolled
out *before* we actually scroll.
Since this is the *only* time we destroy sixels (instead of
overwriting it), rename the sixel functions. And, since they now do a
very specific thing, they can be greatly simplified (and thus faster).
If changing the font size causes the cell size to decrease, either
horizontally or vertically (or both), then delete all sixels since the
grid space they allocated no longer is enough to hold the images.
Since the images are sorted, we can break out of the loop as soon as
we detect an image that *ends before* the rectangle's top starts.
In order for the row comparisons to work, the row numbers must be
re-based against the current scrollback offset, or the
scrollback *end*, to be precise.
Since the images are sorted, we can break out of the loop as soon as
we detect an image that *ends before* the row we're looking for.
In order for the row comparisons to work, the row numbers must be
re-based against the current scrollback offset, or the
scrollback *end*, to be precise.
Handle these on a higher abstraction level. The low level functions
that detect sixel intersections now assume the specified rectangle (or
line region) does *not* cross the wrap-around.
This is ensured by detecting a wrap-around region before hand, and
splitting it up into two, non wrapping regions.
This reduces the burden on sixel_split_by_rectangle(), which would
otherwise consider the newly added/splitted sixels. Since we already
know they aren't covered by the specified rectangle, we can skip that.
This function splits a sixel image into up to four pieces. The four
pieces correspond to the relative complement (set difference) of the
sixel image and the specified rectangle.
Use this function when (possibly) overwriting existing sixel images
when generating a new one, i.e. in sixel_unhook().
Instead of completely erasing a sixel image when it is being
"overwritten" (text is printed somewhere within the image, or another
sixel image is emitted within the first image), split it up into up to
four pieces: 'above', 'below', 'to-the-left' and 'to-the-right'.
This is currently very un-optimized, but seems to produce correct
results.
We used to auto-resize images to always be a multiple of 6.
This is incorrect. The client may, for example, have specified a size
to align the image to a cell boundary, which may not be a multiple of
6.
Furthermore, in e.g. Jexer, which splits up an image into stripes,
that the next image would "overwrite" the previous one. Since the next
image was started on a cell row that the previous image had overflowed
into.
A client can re-use the palette between images. Resetting the palette
breaks this.
Now we initialize the palette on demand, and resets it when the
palette size is changed (by the client).