[librsvg/librsvg-2.42] (#282) - Don't reuse the input surface for painting feComposite's output



commit d1506ab6620df62486eb03804a2c38aa13dd552c
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Jun 8 07:49:51 2018 -0500

    (#282) - Don't reuse the input surface for painting feComposite's output
    
    feComposite tried to take a shortcut if one of its inputs is an
    existing surface, by painting its output to that same surface.
    However, the overall filter may want to reuse the original surface
    unchanged.  This was causing drop shadows, done like Inkscape's, to be
    mis-painted.
    
    https://gitlab.gnome.org/GNOME/librsvg/issues/282

 librsvg/rsvg-filter.c                              |  36 ++++++++++-----------
 .../fixtures/reftests/bugs/282-drop-shadow-ref.png | Bin 0 -> 1726 bytes
 tests/fixtures/reftests/bugs/282-drop-shadow.svg   |  12 +++++++
 3 files changed, 30 insertions(+), 18 deletions(-)
---
diff --git a/librsvg/rsvg-filter.c b/librsvg/rsvg-filter.c
index 79257c63..3b52362d 100644
--- a/librsvg/rsvg-filter.c
+++ b/librsvg/rsvg-filter.c
@@ -3323,6 +3323,7 @@ rsvg_filter_primitive_composite_render (RsvgNode *node, RsvgFilterPrimitive *pri
     RsvgFilterPrimitiveComposite *composite = (RsvgFilterPrimitiveComposite *) primitive;
     RsvgIRect boundarys;
     cairo_surface_t *output, *in, *in2;
+    gint rowstride, height, width;
 
     boundarys = rsvg_filter_primitive_get_bounds (primitive, ctx);
 
@@ -3336,28 +3337,27 @@ rsvg_filter_primitive_composite_render (RsvgNode *node, RsvgFilterPrimitive *pri
         return;
     }
 
+    height = cairo_image_surface_get_height (in);
+    width = cairo_image_surface_get_width (in);
+    rowstride = cairo_image_surface_get_stride (in);
+
+    output = _rsvg_image_surface_new (width, height);
+    if (output == NULL) {
+        cairo_surface_destroy (in);
+        cairo_surface_destroy (in2);
+        return;
+    }
+
+    cairo_surface_flush (in);
+    cairo_surface_flush (in2);
+
     if (composite->mode == COMPOSITE_MODE_ARITHMETIC) {
         guchar i;
         gint x, y;
-        gint rowstride, height, width;
         guchar *in_pixels;
         guchar *in2_pixels;
         guchar *output_pixels;
 
-        height = cairo_image_surface_get_height (in);
-        width = cairo_image_surface_get_width (in);
-        rowstride = cairo_image_surface_get_stride (in);
-
-        output = _rsvg_image_surface_new (width, height);
-        if (output == NULL) {
-            cairo_surface_destroy (in);
-            cairo_surface_destroy (in2);
-            return;
-        }
-
-        cairo_surface_flush (in);
-        cairo_surface_flush (in2);
-
         in_pixels = cairo_image_surface_get_data (in);
         in2_pixels = cairo_image_surface_get_data (in2);
         output_pixels = cairo_image_surface_get_data (output);
@@ -3397,10 +3397,10 @@ rsvg_filter_primitive_composite_render (RsvgNode *node, RsvgFilterPrimitive *pri
     } else {
         cairo_t *cr;
 
-        cairo_surface_reference (in2);
-        output = in2;
-
         cr = cairo_create (output);
+        cairo_set_source_surface (cr, in2, 0, 0);
+        cairo_paint (cr);
+
         cairo_set_source_surface (cr, in, 0, 0);
         cairo_rectangle (cr,
                          boundarys.x0,
diff --git a/tests/fixtures/reftests/bugs/282-drop-shadow-ref.png 
b/tests/fixtures/reftests/bugs/282-drop-shadow-ref.png
new file mode 100644
index 00000000..1d6983c7
Binary files /dev/null and b/tests/fixtures/reftests/bugs/282-drop-shadow-ref.png differ
diff --git a/tests/fixtures/reftests/bugs/282-drop-shadow.svg 
b/tests/fixtures/reftests/bugs/282-drop-shadow.svg
new file mode 100644
index 00000000..04afae33
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/282-drop-shadow.svg
@@ -0,0 +1,12 @@
+<svg width="48" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg";>
+  <defs>
+    <filter id="filter22" color-interpolation-filters="sRGB">
+      <feFlood flood-color="rgb(0,0,0)" flood-opacity=".5" result="flood"/>
+      <feComposite in="flood" in2="SourceGraphic" operator="in" result="composite1"/>
+      <feGaussianBlur in="composite1" result="blur" stdDeviation="2"/>
+      <feOffset dx="0" dy="2" result="offset"/>
+      <feComposite in="SourceGraphic" in2="offset" result="composite2"/>
+    </filter>
+  </defs>
+  <circle cx="24" cy="24" r="20" fill="#EA4335" filter="url(#filter22)"/>
+</svg>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]