>From a7c9365f7956d9d7a089a2f161d2b9d06fc91d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Thu, 23 May 2019 20:48:35 +0200 Subject: [PATCH] Fix transparency handling in SVG images with Cairo We create cairo_surface_t objects with CAIRO_FORMAT_ARGB32, which is meant to be used with "premultiplied alpha" values, i.e. RGB values must be scaled down according to the alpha value. Some references: https://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t https://wiki.gnome.org/Attic/GtkCairoIntegration * src/image.c (gdk_pixbuf_to_argb32): New function to convert GdkPixbuf to Cairo ARGB. (svg_load_image): Use it. --- src/image.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/image.c b/src/image.c index 57b405f6db..7d9aea6f3e 100644 --- a/src/image.c +++ b/src/image.c @@ -1084,6 +1084,17 @@ emacs_color_to_argb32 (Emacs_Color *ec) | ((ec->green / 256) << 8) | (ec->blue / 256)); } +static uint32_t +gdk_pixbuf_to_argb32 (const guchar iconptr[4]) +{ + /* Convert to pre-multiplied alpha. */ + guchar a = iconptr[3]; + return a<<24 + | ((iconptr[0]*a / 256) << 16) + | ((iconptr[1]*a / 256) << 8) + | (iconptr[2]*a / 256); +} + static uint32_t get_spec_bg_or_alpha_as_argb (struct image *img, struct frame *f) @@ -9271,10 +9282,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, if (iconptr[3] == 0) *dataptr = bgcolor; else - *dataptr = (iconptr[0] << 16) - | (iconptr[1] << 8) - | iconptr[2] - | (iconptr[3] << 24); + *dataptr = gdk_pixbuf_to_argb32 (iconptr); iconptr += 4; ++dataptr; -- 2.21.0