[librsvg: 8/13] StackingContext: store the opacity here




commit cad4d157c81c2030ce5db3814b01d9e781a69dd9
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue May 11 14:37:59 2021 -0500

    StackingContext: store the opacity here
    
    Handle a special case we didn't before, as the opacity property does
    not apply to the mask element.

 src/drawing_ctx.rs | 33 ++++++++++++++++++++++-----------
 src/layout.rs      | 24 +++++++++++++++++++++---
 src/marker.rs      |  3 ++-
 src/structure.rs   | 12 ++++++++----
 src/text.rs        |  4 +++-
 5 files changed, 56 insertions(+), 20 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index a01180e5..132ed5a1 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -531,10 +531,9 @@ impl DrawingCtx {
             mask.get_rect(&params)
         };
 
-        let mask_transform = mask_node
-            .borrow_element()
-            .get_transform()
-            .post_transform(&transform);
+        let mask_element = mask_node.borrow_element();
+
+        let mask_transform = mask_element.get_transform().post_transform(&transform);
 
         let mask_content_surface = self.create_surface_for_toplevel_viewport()?;
 
@@ -573,7 +572,7 @@ impl DrawingCtx {
 
             let mut mask_draw_ctx = self.nested(mask_cr);
 
-            let stacking_ctx = StackingContext::new(Transform::identity());
+            let stacking_ctx = StackingContext::new(&mask_element, Transform::identity(), values);
 
             let res = mask_draw_ctx.with_discrete_layer(
                 &stacking_ctx,
@@ -634,7 +633,7 @@ impl DrawingCtx {
                 values.filter()
             };
 
-            let UnitInterval(opacity) = values.opacity().0;
+            let Opacity(UnitInterval(opacity)) = stacking_ctx.opacity;
 
             let affine_at_start = saved_cr.draw_ctx.get_transform();
 
@@ -1012,7 +1011,10 @@ impl DrawingCtx {
                         CascadedValues::new_from_node(&pattern.node_with_children);
                     let pattern_values = pattern_cascaded.get();
 
-                    let stacking_ctx = StackingContext::new(Transform::identity());
+                    let elt = pattern.node_with_children.borrow_element();
+
+                    let stacking_ctx =
+                        StackingContext::new(&elt, Transform::identity(), pattern_values);
 
                     dc.with_discrete_layer(
                         &stacking_ctx,
@@ -1194,7 +1196,8 @@ impl DrawingCtx {
             return Ok(self.empty_bbox());
         }
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         self.with_discrete_layer(
             &stacking_ctx,
@@ -1305,7 +1308,9 @@ impl DrawingCtx {
             None
         };
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         self.with_discrete_layer(
             &stacking_ctx,
@@ -1602,6 +1607,8 @@ impl DrawingCtx {
         self.cr
             .transform(node.borrow_element().get_transform().into());
 
+        let use_element = node.borrow_element();
+
         let res = if is_element_of_type!(child, Symbol) {
             // if the <use> references a <symbol>, it gets handled specially
 
@@ -1618,7 +1625,7 @@ impl DrawingCtx {
                 None
             };
 
-            let stacking_ctx = StackingContext::new(Transform::identity());
+            let stacking_ctx = StackingContext::new(&use_element, Transform::identity(), values);
 
             self.with_discrete_layer(
                 &stacking_ctx,
@@ -1646,7 +1653,11 @@ impl DrawingCtx {
         } else {
             // otherwise the referenced node is not a <symbol>; process it generically
 
-            let stacking_ctx = StackingContext::new(Transform::new_translate(use_rect.x0, use_rect.y0));
+            let stacking_ctx = StackingContext::new(
+                &use_element,
+                Transform::new_translate(use_rect.x0, use_rect.y0),
+                values,
+            );
 
             self.with_discrete_layer(
                 &stacking_ctx,
diff --git a/src/layout.rs b/src/layout.rs
index a29b35af..829131fb 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -2,7 +2,11 @@
 //!
 //! The idea is to take the DOM tree and produce a layout tree with SVG concepts.
 
+use crate::element::Element;
+use crate::properties::ComputedValues;
+use crate::property_defs::Opacity;
 use crate::transform::Transform;
+use crate::unit_interval::UnitInterval;
 
 /// SVG Stacking context, an inner node in the layout tree.
 ///
@@ -19,12 +23,26 @@ use crate::transform::Transform;
 /// render an element as an isolated group.
 pub struct StackingContext {
     pub transform: Transform,
+    pub opacity: Opacity,
 }
 
 impl StackingContext {
-    pub fn new(transform: Transform) -> StackingContext {
-        StackingContext {
-            transform,
+    pub fn new(
+        element: &Element,
+        transform: Transform,
+        values: &ComputedValues,
+    ) -> StackingContext {
+        let opacity;
+
+        match *element {
+            // The opacity property does not apply to masks, so we pass 1.0 here.
+            //
+            // "The opacity, filter and display properties do not apply to the mask element"
+            // https://drafts.fxtf.org/css-masking-1/#MaskElement
+            Element::Mask(_) => opacity = Opacity(UnitInterval::clamp(1.0)),
+            _ => opacity = values.opacity(),
         }
+
+        StackingContext { transform, opacity }
     }
 }
diff --git a/src/marker.rs b/src/marker.rs
index b0c05137..22a191b4 100644
--- a/src/marker.rs
+++ b/src/marker.rs
@@ -160,7 +160,8 @@ impl Marker {
             )
         };
 
-        let stacking_ctx = StackingContext::new(transform);
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, transform, values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
diff --git a/src/structure.rs b/src/structure.rs
index e872fd49..f62032f6 100644
--- a/src/structure.rs
+++ b/src/structure.rs
@@ -34,7 +34,8 @@ impl Draw for Group {
     ) -> Result<BoundingBox, RenderingError> {
         let values = cascaded.get();
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -75,7 +76,8 @@ impl Draw for Switch {
     ) -> Result<BoundingBox, RenderingError> {
         let values = cascaded.get();
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -252,7 +254,8 @@ impl Draw for Svg {
     ) -> Result<BoundingBox, RenderingError> {
         let values = cascaded.get();
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -503,7 +506,8 @@ impl Draw for Link {
         let cascaded = CascadedValues::new(cascaded, node);
         let values = cascaded.get();
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
diff --git a/src/text.rs b/src/text.rs
index be978491..3e3478a6 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -492,7 +492,9 @@ impl Draw for Text {
         let view_params = draw_ctx.get_view_params();
         let params = NormalizeParams::new(&values, &view_params);
 
-        let stacking_ctx = StackingContext::new(node.borrow_element().get_transform());
+        let elt = node.borrow_element();
+
+        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,


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