Subject: Re: bug#36315: 27.0.50; SVG transparency handling is inaccurate

From: Pip Cet <[email-masked]>
Date: Mon, 24 Jun 2019 16:24:17 +0000

On Mon, Jun 24, 2019 at 8:17 AM YAMAMOTO Mitsuharu
<[email-masked]> wrote:
> On Mon, 24 Jun 2019 16:56:45 +0900,
> YAMAMOTO Mitsuharu wrote:
> >
> > An alternative way would be to use rsvg_handle_render_cairo, which is
> > recommended by librsvg, and let it blend with the background color.
> >
> > Patch attached.  Note that this does not require --with-cairo.
> > Raising the required version of librsvg to 2.14 is not a problem, as
> > we are already using rsvg_handle_get_dimensions that requires that
> > version.  Is Windows librsvg DLL compiled with libcairo?
>
> Sorry, wrong patch.  Please try this instead.

Thank you very much, that fixes the problem. Unfortunately, I do not
know about the situation on Windows.

I'm not sure about the additional changes in the attached relative
patch, so feel free to take or leave them as you see fit. The second
call to cairo_set_source_rgb is currently unnecessary, because rsvg
forces the foreground color to black anyway, but that might change one
day (ideally, we'd use the frame foreground color, or even the current
face's foreground color; I have patches here that do this, though they
don't fix rsvg).

@@ -9619,15 +9619,19 @@ svg_load_image (struct frame *f, struct image
*img, char *contents,

   cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                              width, height);
+  if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+    goto rsvg_error;
   cairo_t *cr = cairo_create (surface);
   cairo_set_source_rgb (cr, background.red / 65535.0,
             background.green / 65535.0,
             background.blue / 65535.0);
   cairo_paint (cr);
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
   rsvg_handle_render_cairo (rsvg_handle, cr);
   cairo_destroy (cr);
   g_object_unref (rsvg_handle);

+  cairo_surface_flush (surface);
   unsigned char *data = cairo_image_surface_get_data (surface);
   int stride = cairo_image_surface_get_stride (surface);
   for (int y = 0; y < height; ++y)
@@ -9636,9 +9640,9 @@ svg_load_image (struct frame *f, struct image
*img, char *contents,
       for (int x = 0; x < width; ++x)
     {
       guint32 rgb = *pixels++;
-      int red   = ((rgb >> 16) & 0xff) << 8;
-      int green = ((rgb >> 8) & 0xff) << 8;
-      int blue  = (rgb & 0xff) << 8;
+      int red   = ((rgb >> 16) & 0xff) * 0x101;
+      int green = ((rgb >> 8) & 0xff) * 0x101;
+      int blue  = (rgb & 0xff) * 0x101;
       PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue));
     }
       data += stride;
From 402dbd1e1ff5c33fe9061dd362d3b47a10ac5658 Mon Sep 17 00:00:00 2001
From: Pip Cet <[email-masked]>
Date: Mon, 24 Jun 2019 16:20:19 +0000
Subject: [PATCH] minor things

---
 src/image.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/image.c b/src/image.c
index 924a188b4a..ce5534b07a 100644
--- a/src/image.c
+++ b/src/image.c
@@ -9619,15 +9619,19 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
 
   cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
 							 width, height);
+  if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+    goto rsvg_error;
   cairo_t *cr = cairo_create (surface);
   cairo_set_source_rgb (cr, background.red / 65535.0,
 			background.green / 65535.0,
 			background.blue / 65535.0);
   cairo_paint (cr);
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
   rsvg_handle_render_cairo (rsvg_handle, cr);
   cairo_destroy (cr);
   g_object_unref (rsvg_handle);
 
+  cairo_surface_flush (surface);
   unsigned char *data = cairo_image_surface_get_data (surface);
   int stride = cairo_image_surface_get_stride (surface);
   for (int y = 0; y < height; ++y)
@@ -9636,9 +9640,9 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
       for (int x = 0; x < width; ++x)
 	{
 	  guint32 rgb = *pixels++;
-	  int red   = ((rgb >> 16) & 0xff) << 8;
-	  int green = ((rgb >> 8) & 0xff) << 8;
-	  int blue  = (rgb & 0xff) << 8;
+	  int red   = ((rgb >> 16) & 0xff) * 0x101;
+	  int green = ((rgb >> 8) & 0xff) * 0x101;
+	  int blue  = (rgb & 0xff) * 0x101;
 	  PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue));
 	}
       data += stride;
-- 
2.20.1