patch 9.2.0637: sixel: anti-aliased RGBA images render with visible outline
Commit: https://github.com/vim/vim/commit/66bec4bd8a421461d75a8b04619d63e2cd0b0b40 Author: Yasuhiro Matsumoto <[email protected]> Date: Sat Jun 13 19:07:06 2026 +0000 patch 9.2.0637: sixel: anti-aliased RGBA images render with visible outline Problem: Only alpha == 0 was treated as transparent, so partly- transparent edge pixels rendered opaque and outlined the image. Solution: Treat alpha < 128 as transparent. Emit pixels with alpha < 128 as the transparent palette index. Rendering them opaque showed the anti-aliased fringe of an RGBA image as bright dots. closes: #20477 Signed-off-by: Yasuhiro Matsumoto <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/src/sixel.c b/src/sixel.c index 4d7ef53c2..5245af663 100644 --- a/src/sixel.c +++ b/src/sixel.c @@ -306,11 +306,14 @@ sixel_resize_rgb(char_u *src, int sw, int sh, int dw, int dh) * (indices 1..npal; 0 is reserved as transparent). * * Handles both RGB (3 bytes/pixel, has_alpha == FALSE) and RGBA (4 bytes/ - * pixel, has_alpha == TRUE). For RGBA, alpha == 0 pixels are mapped to - * palette index 0 -- which the sixel emitter never writes to the bitmask, - * leaving the cell's underlying terminal contents visible (transparency). - * Pixels with alpha != 0 are deduplicated by their R,G,B triple, ignoring - * the alpha value (sixel cannot represent partial transparency anyway). + * pixel, has_alpha == TRUE). Sixel cannot represent partial transparency, + * so RGBA pixels are split at half coverage: alpha < 128 pixels are mapped + * to palette index 0 -- which the sixel emitter never writes to the + * bitmask, leaving the cell's underlying terminal contents visible + * (transparency). Rendering them opaque instead would show the image's + * anti-aliased edge fringe (mostly-transparent, often light-colored + * pixels) as bright dots around the image. Pixels with alpha >= 128 are + * deduplicated by their R,G,B triple, ignoring the alpha value. * * Returns OK on success, FAIL when colors exceed max_colors (caller may * fall back to a fixed palette) or on OOM. @@ -354,7 +357,7 @@ rgb_to_paletted_fast( unsigned int h; int slot; - if (has_alpha && p[3] == 0) + if (has_alpha && p[3] < 128) { idx[i] = 0; // transparent -- terminal leaves cell as-is continue; @@ -403,9 +406,10 @@ too_many: * Always succeeds; produces 240 palette entries. * * Handles both RGB (3 bytes/pixel, has_alpha == FALSE) and RGBA (4 bytes/ - * pixel, has_alpha == TRUE). For RGBA, alpha == 0 pixels are mapped to + * pixel, has_alpha == TRUE). For RGBA, alpha < 128 pixels are mapped to * palette index 0 -- which the sixel emitter never writes to the bitmask, - * leaving the cell's underlying terminal contents visible (transparency). + * leaving the cell's underlying terminal contents visible (transparency); + * see rgb_to_paletted_fast() for why the cut is at half coverage. */ static int rgb_to_paletted_fixed( @@ -433,7 +437,7 @@ rgb_to_paletted_fixed( char_u *p = pixels + (size_t)n * bpp; int ri, gi, bi; - if (has_alpha && p[3] == 0) + if (has_alpha && p[3] < 128) { idx[n] = 0; continue; @@ -518,9 +522,9 @@ sixel_encode(image_rgb_T *img) // P2=1 means pixel positions left unspecified by any colour register // keep their previous on-screen contents instead of being painted with // colour register 0. That gives true transparency for RGBA images: - // alpha==0 pixels are emitted as palette index 0 (which we never write - // to the bitmask), so the terminal leaves the popup's underlying cell - // colour visible there -- no flatten, no colour-match drift. + // alpha < 128 pixels are emitted as palette index 0 (which we never + // write to the bitmask), so the terminal leaves the popup's underlying + // cell colour visible there -- no flatten, no colour-match drift. if (ga_concat_bytes(&ga, " P0;1;8q\"1;1;", 13) == FAIL || ga_concat_int(&ga, width) == FAIL || ga_append(&ga, ';') == FAIL diff --git a/src/version.c b/src/version.c index d2dcaafb5..619d899b2 100644 --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 637, /**/ 636, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wYTov-00DSkS-FP%40256bit.org.
