[librsvg: 3/4] (#818): Allow having a mask and opacity in the same element




commit 7b12391c2d0f15c88a2cbc92b4b6854701abb524
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Nov 11 18:50:26 2021 -0600

    (#818): Allow having a mask and opacity in the same element
    
    The code structure made it so that an element with a `mask` attribute,
    together with `opacity` and/or `mix-blend-mode`, would only apply the
    mask.  Now they can all be used together.
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/818
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/631>

 src/drawing_ctx.rs                                           | 12 +++++++++---
 .../fixtures/reftests/svg2-reftests/mask-and-opacity-ref.svg |  3 +++
 tests/fixtures/reftests/svg2-reftests/mask-and-opacity.svg   |  7 +++++++
 tests/src/reference.rs                                       |  6 ++++++
 4 files changed, 25 insertions(+), 3 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 8988ffe03..87cb9c56b 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -865,16 +865,22 @@ impl DrawingCtx {
                             )
                             .and_then(|mask_surf| {
                                 if let Some(surf) = mask_surf {
+                                    self.cr.push_group();
+
                                     self.cr.set_matrix(affines.compositing.into());
-                                    Ok(self.cr.mask_surface(&surf, 0.0, 0.0)?)
+                                    self.cr.mask_surface(&surf, 0.0, 0.0)?;
+
+                                    Ok(self.cr.pop_group_to_source()?)
                                 } else {
                                     Ok(())
                                 }
                             })
                             .map(|_: ()| bbox)
                         });
-                    } else {
-                        // No mask, so composite the temporary surface
+                    }
+
+                    {
+                        // Composite the temporary surface
 
                         self.cr.set_matrix(affines.compositing.into());
                         self.cr.set_operator(stacking_ctx.mix_blend_mode.into());
diff --git a/tests/fixtures/reftests/svg2-reftests/mask-and-opacity-ref.svg 
b/tests/fixtures/reftests/svg2-reftests/mask-and-opacity-ref.svg
new file mode 100644
index 000000000..f4867380f
--- /dev/null
+++ b/tests/fixtures/reftests/svg2-reftests/mask-and-opacity-ref.svg
@@ -0,0 +1,3 @@
+<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg";>
+  <circle cx="200" cy="200" r="200" fill="lime" opacity="0.5"/>
+</svg>
diff --git a/tests/fixtures/reftests/svg2-reftests/mask-and-opacity.svg 
b/tests/fixtures/reftests/svg2-reftests/mask-and-opacity.svg
new file mode 100644
index 000000000..ec70764bb
--- /dev/null
+++ b/tests/fixtures/reftests/svg2-reftests/mask-and-opacity.svg
@@ -0,0 +1,7 @@
+<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg";>
+  <mask id="mask">
+    <circle cx="200" cy="200" r="200" fill="white"/>
+  </mask>
+
+  <rect width="400" height="400" fill="lime" opacity="0.5" mask="url(#mask)"/>
+</svg>
diff --git a/tests/src/reference.rs b/tests/src/reference.rs
index 03ce6b30f..5b0d309c9 100644
--- a/tests/src/reference.rs
+++ b/tests/src/reference.rs
@@ -400,3 +400,9 @@ test_svg_reference!(
     "tests/fixtures/reftests/svg2-reftests/isolation.svg",
     "tests/fixtures/reftests/svg2-reftests/isolation-ref.svg"
 );
+
+test_svg_reference!(
+    mask_and_opacity,
+    "tests/fixtures/reftests/svg2-reftests/mask-and-opacity.svg",
+    "tests/fixtures/reftests/svg2-reftests/mask-and-opacity-ref.svg"
+);


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