From bc75f4744c02b60d896f445f6c2278416aa33ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 2 Oct 2020 20:56:44 +0200 Subject: [PATCH] sixel: fix sheared image when image crosses scrollback wrap-around MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- CHANGELOG.md | 3 +++ sixel.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e6440f..668b2c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,9 @@ * Background opacity when in _reverse video_ mode. * Crash when writing a sixel image that extends outside the terminal's right margin (https://codeberg.org/dnkl/foot/issues/151). +* Sixel image at non-zero column positions getting sheared at + seemingly random occasions + (https://codeberg.org/dnkl/foot/issues/151). ### Security diff --git a/sixel.c b/sixel.c index 0600a434..747e3d00 100644 --- a/sixel.c +++ b/sixel.c @@ -448,6 +448,16 @@ sixel_unhook(struct terminal *term) int pixel_rows_left = term->sixel.image.height; const int stride = term->sixel.image.width * sizeof(uint32_t); + /* + * Need to 'remember' current cursor column. + * + * If we split up the sixel (to avoid scrollback wrap-around), we + * will emit a carriage-return (after several linefeeds), which + * will reset the cursor column to 0. If we use _that_ column for + * the subsequent image parts, the image will look sheared. + */ + const int start_col = term->grid->cursor.point.col; + /* We do not allow sixels to cross the scrollback wrap-around, as * this makes intersection calculations much more complicated */ while (pixel_rows_left > 0) { @@ -478,7 +488,7 @@ sixel_unhook(struct terminal *term) .height = height, .rows = (height + term->cell_height - 1) / term->cell_height, .cols = (width + term->cell_width - 1) / term->cell_width, - .pos = (struct coord){cursor->col, cur_row}, + .pos = (struct coord){start_col, cur_row}, }; sixel_overwrite_by_rectangle(