[librsvg: 1/2] (#373): Render gradients with userSpaceOnUse even for an empty bounding box



commit f1de149cdab1e0a90936e73122bbee02303c66e7
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 6 12:03:22 2018 -0600

    (#373): Render gradients with userSpaceOnUse even for an empty bounding box
    
    In the test, a horizontal or vertical line was not being styled with a
    gradient, because those lines have an empty bounding box.  However,
    the gradient in question had gradientUnits="userSpaceOnUse", *not*
    "objectBoundingBox".  So, we don't need the object's bounding box at
    all, and the lines can use the gradient in the current coordinate
    system.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/373

 rsvg_internals/src/gradient.rs                     |  24 ++++++++-----
 .../bugs/373-gradient-userspaceonuse-ref.png       | Bin 0 -> 631 bytes
 .../reftests/bugs/373-gradient-userspaceonuse.svg  |  39 +++++++++++++++++++++
 3 files changed, 54 insertions(+), 9 deletions(-)
---
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index 8d76c0e8..a14d9e0d 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -415,6 +415,14 @@ impl Gradient {
             }
         }
     }
+
+    fn bounds_are_valid(&self, bbox: &BoundingBox) -> bool {
+        if self.common.units == Some(GradientUnits(CoordUnits::UserSpaceOnUse)) {
+            true
+        } else {
+            bbox.rect.map_or(false, |r| !r.is_empty())
+        }
+    }
 }
 
 fn acquire_gradient<'a>(draw_ctx: &'a mut DrawingCtx<'_>, name: &str) -> Option<AcquiredNode> {
@@ -690,15 +698,13 @@ pub fn gradient_resolve_fallbacks_and_set_pattern(
     let mut did_set_gradient = false;
 
     node.with_impl(|node_gradient: &NodeGradient| {
-        if let Some(r) = bbox.rect {
-            if !r.is_empty() {
-                let gradient = node_gradient.get_gradient_with_color_stops_from_node(node);
-                let resolved = resolve_gradient(&gradient, draw_ctx);
-                let cascaded = node.get_cascaded_values();
-                let values = cascaded.get();
-
-                set_pattern_on_draw_context(&resolved, values, draw_ctx, opacity, bbox);
-            }
+        let gradient = node_gradient.get_gradient_with_color_stops_from_node(node);
+        let resolved = resolve_gradient(&gradient, draw_ctx);
+
+        if resolved.bounds_are_valid(bbox) {
+            let cascaded = node.get_cascaded_values();
+            let values = cascaded.get();
+            set_pattern_on_draw_context(&resolved, values, draw_ctx, opacity, bbox);
         }
 
         did_set_gradient = true;
diff --git a/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse-ref.png 
b/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse-ref.png
new file mode 100644
index 00000000..5d8e4c42
Binary files /dev/null and b/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse-ref.png differ
diff --git a/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse.svg 
b/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse.svg
new file mode 100644
index 00000000..218e5f79
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/373-gradient-userspaceonuse.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- 
+     We draw a horizontal and a vertical line, both with a gradient.
+     Since gradientUnits="userSpaceOnUse", it does not matter that the
+     lines have an empty bounding box, as would be the case for
+     objectBoundingBox.  Thus, the gradient *is* drawn (here, all green),
+     instead of leaving the lines unstyled.
+-->
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   version="1.1"
+   x="0px"
+   y="0px"
+   width="200"
+   height="200"
+   viewBox="0 0 200 200"
+   xml:space="preserve">
+  <rect x="0" y="0" width="200" height="200" style="fill:blue" />
+  <g>
+    <radialGradient id="SVGID_19_" cx="100" cy="100" r="100" gradientUnits="userSpaceOnUse">
+      <stop offset="0" style="stop-color:green" />
+    </radialGradient>
+    <line
+       x1="100"
+       y1="0"
+       x2="100"
+       y2="200"
+       style="fill:none;stroke:url(#SVGID_19_);stroke-width:2;stroke-miterlimit:10"
+       />
+    <line
+       x1="0"
+       y1="100"
+       x2="200"
+       y2="100"
+       style="fill:none;stroke:url(#SVGID_19_);stroke-width:2;stroke-miterlimit:10"
+       />
+  </g>
+</svg>


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