Skip to content

Commit

Permalink
ChafaKittyCanvas: If alpha threshold is at max, composite on solid BG
Browse files Browse the repository at this point in the history
This allows us to show artifact-free animations with transparency using
the basic Kitty protocol.
  • Loading branch information
hpjansson committed Sep 19, 2022
1 parent 8b3426e commit 6fa53ad
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 5 deletions.
8 changes: 7 additions & 1 deletion chafa/chafa-canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,11 @@ chafa_canvas_draw_all_pixels (ChafaCanvas *canvas, ChafaPixelType src_pixel_type
}
else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY)
{
ChafaColor bg_color;

chafa_unpack_color (canvas->config.bg_color_packed_rgb, &bg_color);
bg_color.ch [3] = canvas->config.alpha_threshold < 1 ? 0x00 : 0xff;

/* Kitty mode */

canvas->fg_palette.alpha_threshold = canvas->config.alpha_threshold;
Expand All @@ -1570,7 +1575,8 @@ chafa_canvas_draw_all_pixels (ChafaCanvas *canvas, ChafaPixelType src_pixel_type
src_pixel_type,
src_pixels,
src_width, src_height,
src_rowstride);
src_rowstride,
bg_color);
}
else /* if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2) */
{
Expand Down
18 changes: 16 additions & 2 deletions chafa/internal/chafa-kitty-canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "internal/chafa-bitfield.h"
#include "internal/chafa-indexed-image.h"
#include "internal/chafa-kitty-canvas.h"
#include "internal/chafa-pixops.h"
#include "internal/chafa-string-util.h"

typedef struct
Expand All @@ -39,6 +40,8 @@ typedef struct
{
ChafaKittyCanvas *kitty_canvas;
SmolScaleCtx *scale_ctx;
ChafaColor bg_color;
gboolean flatten_alpha;
}
DrawCtx;

Expand All @@ -47,7 +50,7 @@ chafa_kitty_canvas_new (gint width, gint height)
{
ChafaKittyCanvas *kitty_canvas;

kitty_canvas = g_new (ChafaKittyCanvas, 1);
kitty_canvas = g_new0 (ChafaKittyCanvas, 1);
kitty_canvas->width = width;
kitty_canvas->height = height;
kitty_canvas->rgba_image = g_malloc (width * height * sizeof (guint32));
Expand All @@ -69,12 +72,21 @@ draw_pixels_worker (ChafaBatchInfo *batch, const DrawCtx *ctx)
((guint32 *) ctx->kitty_canvas->rgba_image) + (ctx->kitty_canvas->width * batch->first_row),
batch->first_row,
batch->n_rows);

/* FIXME: Smolscale should be able to do this */
if (ctx->flatten_alpha)
chafa_composite_rgba_on_solid_color (ctx->bg_color,
ctx->kitty_canvas->rgba_image,
ctx->kitty_canvas->width,
batch->first_row,
batch->n_rows);
}

void
chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas, ChafaPixelType src_pixel_type,
gconstpointer src_pixels,
gint src_width, gint src_height, gint src_rowstride)
gint src_width, gint src_height, gint src_rowstride,
ChafaColor bg_color)
{
DrawCtx ctx;

Expand All @@ -100,6 +112,8 @@ chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas, ChafaPixelTy
kitty_canvas->width * sizeof (guint32),
NULL,
&ctx);
ctx.bg_color = bg_color;
ctx.flatten_alpha = bg_color.ch [3] == 0;

chafa_process_batches (&ctx,
(GFunc) draw_pixels_worker,
Expand Down
6 changes: 4 additions & 2 deletions chafa/internal/chafa-kitty-canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ ChafaKittyCanvas;
ChafaKittyCanvas *chafa_kitty_canvas_new (gint width, gint height);
void chafa_kitty_canvas_destroy (ChafaKittyCanvas *kitty_canvas);

void chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas, ChafaPixelType src_pixel_type,
void chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas,
ChafaPixelType src_pixel_type,
gconstpointer src_pixels,
gint src_width, gint src_height, gint src_rowstride);
gint src_width, gint src_height, gint src_rowstride,
ChafaColor bg_color);
void chafa_kitty_canvas_build_ansi (ChafaKittyCanvas *kitty_canvas, ChafaTermInfo *term_info, GString *out_str,
gint width_cells, gint height_cells);

Expand Down
27 changes: 27 additions & 0 deletions chafa/internal/chafa-pixops.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,33 @@ composite_alpha_on_bg (ChafaColor bg_color,
}
}

/* FIXME: Could we always destroy the alpha channel and eliminate the other
* variant? */
static void
composite_alpha_on_solid (ChafaColor bg_color,
ChafaPixel *pixels, gint width, gint first_row, gint n_rows)
{
ChafaPixel *p0, *p1;

p0 = pixels + first_row * width;
p1 = p0 + n_rows * width;

for ( ; p0 < p1; p0++)
{
p0->col.ch [0] += (bg_color.ch [0] * (255 - (guint32) p0->col.ch [3])) / 255;
p0->col.ch [1] += (bg_color.ch [1] * (255 - (guint32) p0->col.ch [3])) / 255;
p0->col.ch [2] += (bg_color.ch [2] * (255 - (guint32) p0->col.ch [3])) / 255;
p0->col.ch [3] = 0xff;
}
}

void
chafa_composite_rgba_on_solid_color (ChafaColor color,
ChafaPixel *pixels, gint width, gint first_row, gint n_rows)
{
composite_alpha_on_solid (color, pixels, width, first_row, n_rows);
}

static void
prepare_pixels_2_worker (ChafaBatchInfo *batch, PrepareContext *prep_ctx)
{
Expand Down
3 changes: 3 additions & 0 deletions chafa/internal/chafa-pixops.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void chafa_sort_pixel_index_by_channel (guint8 *index,
const ChafaPixel *pixels, gint n_pixels,
gint ch);

void chafa_composite_rgba_on_solid_color (ChafaColor color,
ChafaPixel *pixels, gint width, gint first_row, gint n_rows);

G_END_DECLS

#endif /* __CHAFA_PIXOPS_H__ */

0 comments on commit 6fa53ad

Please sign in to comment.