Blob Blame History Raw
From ae7ecfa0846b40d75f5b20c4f122df9a0b78ee4f Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@gnome.org>
Date: Thu, 19 Sep 2019 15:25:03 -0500
Subject: [PATCH] (#506): Fix empty patterns which reference a fallback pattern
 with children

When we do draw_ctx.acquired_nodes().get_node_of_type() to acquire a
pattern, or its fallback, we need to set the NodePattern.node to the
corresponding node weakref.

This was being done correctly at the beginning of the implementation
of resolve(), as of commit 03cbbe96, where the sequence is this:

    DrawingCtx.set_source_paint_server()
        paint_server = acquired_nodes.get_node()
	<paint_server as NodePattern>.resolve_fallbacks_and_set_pattern()
	    self.resolve(node, ...)
	        *self.node.borrow_mut() = Some(node.downgrade());

However, this setting of self.node (where self is a NodePattern) to
the corresponding weakref was missing in the "while" loop in
NodePattern.resolve(), where it acquires the fallback pattern - the
fallback's NodePattern also needs its .node to be set to its node's
weakref.

We'll clean this up at some point.

Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/506
---
 rsvg_internals/src/pattern.rs                 |   6 +++++-
 .../bugs/506-pattern-fallback-ref.png         | Bin 0 -> 486 bytes
 .../reftests/bugs/506-pattern-fallback.svg    |  19 ++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 tests/fixtures/reftests/bugs/506-pattern-fallback-ref.png
 create mode 100644 tests/fixtures/reftests/bugs/506-pattern-fallback.svg

diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 9d943b1d..291d81d3 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -164,7 +164,11 @@ impl PaintSource for NodePattern {
                 }
 
                 let node_data = a_node.borrow();
-                result.resolve_from_fallback(&node_data.get_impl::<NodePattern>());
+
+                let fallback_pattern = node_data.get_impl::<NodePattern>();
+                *fallback_pattern.node.borrow_mut() = Some(a_node.downgrade());
+
+                result.resolve_from_fallback(fallback_pattern);
 
                 stack.push(a_node);
             } else {
diff --git a/tests/fixtures/reftests/bugs/506-pattern-fallback-ref.png b/tests/fixtures/reftests/bugs/506-pattern-fallback-ref.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9fec4e90e652595043b4dc7d6f9a2e915c3b9f8
GIT binary patch
literal 486
zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6&6<n8Xl@E-&h>|H(?C_UTL
z#WAE}&f6;+c^eD_SR7~nt2VPVd@-?XSrfP4ZZV)9T7&$XmzgUpUi<j}xbkhM{my0V
m48<%AhXyyIb(jFnf52+augz4zbVjohWSgg}pUXO@geCxCb5Z&L

literal 0
HcmV?d00001

diff --git a/tests/fixtures/reftests/bugs/506-pattern-fallback.svg b/tests/fixtures/reftests/bugs/506-pattern-fallback.svg
new file mode 100644
index 00000000..64f71050
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/506-pattern-fallback.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     version="1.1"
+     width="256"
+     height="256"
+     viewBox="0 0 256 256">
+  <defs>
+    <pattern id="pattern1" xlink:href="#pattern2"/>
+    <pattern id="pattern2" patternUnits="userSpaceOnUse" width="1" height="1">
+      <image width="1" height="1" preserveAspectRatio="none"
+             xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12Ng+M8AAAICAQCqKp4n
+AAAAAElFTkSuQmCC"
+             x="0"
+             y="0"/>
+    </pattern>
+  </defs>
+  <rect x="100" y="100" width="56" height="56" style="fill:url(#pattern1);"/>
+</svg>
-- 
2.23.0