[librsvg: 10/13] StackingContext: store the mask




commit ef828645386f13a58fcb215f98efbaee72a3dbf3
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue May 11 17:35:40 2021 -0500

    StackingContext: store the mask

 src/drawing_ctx.rs | 89 +++++++++++++++++++++---------------------------------
 src/layout.rs      | 32 ++++++++++++++++++++
 src/marker.rs      |  2 +-
 src/structure.rs   |  8 ++---
 src/text.rs        |  2 +-
 5 files changed, 72 insertions(+), 61 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index a772b179..e943ea50 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -15,7 +15,6 @@ use crate::coord_units::CoordUnits;
 use crate::dasharray::Dasharray;
 use crate::document::{AcquiredNodes, NodeId};
 use crate::dpi::Dpi;
-use crate::element::Element;
 use crate::error::{AcquireError, ImplementationLimit, RenderingError};
 use crate::filters::{self, FilterSpec};
 use crate::float_eq_cairo::ApproxEqCairo;
@@ -34,7 +33,6 @@ use crate::property_defs::{
 };
 use crate::rect::Rect;
 use crate::shapes::{Markers, Shape};
-use crate::structure::Mask;
 use crate::surface_utils::{
     shared_surface::ExclusiveImageSurface, shared_surface::SharedImageSurface,
     shared_surface::SurfaceType,
@@ -506,7 +504,6 @@ impl DrawingCtx {
 
     fn generate_cairo_mask(
         &mut self,
-        mask: &Mask,
         mask_node: &Node,
         transform: Transform,
         bbox: &BoundingBox,
@@ -518,6 +515,8 @@ impl DrawingCtx {
             return Ok(None);
         }
 
+        let mask = borrow_element_as!(mask_node, Mask);
+
         let bbox_rect = bbox.rect.as_ref().unwrap();
 
         let cascaded = CascadedValues::new_from_node(mask_node);
@@ -572,7 +571,8 @@ impl DrawingCtx {
 
             let mut mask_draw_ctx = self.nested(mask_cr);
 
-            let stacking_ctx = StackingContext::new(&mask_element, Transform::identity(), values);
+            let stacking_ctx =
+                StackingContext::new(acquired_nodes, &mask_element, Transform::identity(), values);
 
             let res = mask_draw_ctx.with_discrete_layer(
                 &stacking_ctx,
@@ -619,10 +619,8 @@ impl DrawingCtx {
             let saved_cr = SavedCr::new(self);
 
             let clip_path_value = values.clip_path();
-            let mask_value = values.mask();
 
             let clip_uri = clip_path_value.0.get();
-            let mask = mask_value.0.get();
 
             let Opacity(UnitInterval(opacity)) = stacking_ctx.opacity;
 
@@ -645,7 +643,7 @@ impl DrawingCtx {
             let is_opaque = approx_eq!(f64, opacity, 1.0);
             let needs_temporary_surface = !(is_opaque
                 && stacking_ctx.filter == Filter::None
-                && mask.is_none()
+                && stacking_ctx.mask.is_none()
                 && values.mix_blend_mode() == MixBlendMode::Normal
                 && clip_in_object_space.is_none());
 
@@ -727,49 +725,24 @@ impl DrawingCtx {
 
                 // Mask
 
-                if let Some(mask_id) = mask {
-                    if let Ok(acquired) = acquired_nodes.acquire(mask_id) {
-                        let mask_node = acquired.get();
-
-                        match *mask_node.borrow_element() {
-                            Element::Mask(ref m) => {
-                                res = res.and_then(|bbox| {
-                                    saved_cr
-                                        .draw_ctx
-                                        .generate_cairo_mask(
-                                            &m,
-                                            &mask_node,
-                                            affines.for_temporary_surface,
-                                            &bbox,
-                                            acquired_nodes,
-                                        )
-                                        .map(|mask_surf| {
-                                            if let Some(surf) = mask_surf {
-                                                saved_cr
-                                                    .draw_ctx
-                                                    .cr
-                                                    .set_matrix(affines.compositing.into());
-                                                saved_cr.draw_ctx.cr.mask_surface(&surf, 0.0, 0.0);
-                                            }
-                                        })
-                                        .map(|_: ()| bbox)
-                                });
-                            }
-                            _ => {
-                                rsvg_log!(
-                                    "element {} references \"{}\" which is not a mask",
-                                    node_name,
-                                    mask_id
-                                );
-                            }
-                        }
-                    } else {
-                        rsvg_log!(
-                            "element {} references nonexistent mask \"{}\"",
-                            node_name,
-                            mask_id
-                        );
-                    }
+                if let Some(ref mask_node) = stacking_ctx.mask {
+                    res = res.and_then(|bbox| {
+                        saved_cr
+                            .draw_ctx
+                            .generate_cairo_mask(
+                                mask_node,
+                                affines.for_temporary_surface,
+                                &bbox,
+                                acquired_nodes,
+                            )
+                            .map(|mask_surf| {
+                                if let Some(surf) = mask_surf {
+                                    saved_cr.draw_ctx.cr.set_matrix(affines.compositing.into());
+                                    saved_cr.draw_ctx.cr.mask_surface(&surf, 0.0, 0.0);
+                                }
+                            })
+                            .map(|_: ()| bbox)
+                    });
                 } else {
                     // No mask, so composite the temporary surface
 
@@ -1004,8 +977,12 @@ impl DrawingCtx {
 
                     let elt = pattern.node_with_children.borrow_element();
 
-                    let stacking_ctx =
-                        StackingContext::new(&elt, Transform::identity(), pattern_values);
+                    let stacking_ctx = StackingContext::new(
+                        acquired_nodes,
+                        &elt,
+                        Transform::identity(),
+                        pattern_values,
+                    );
 
                     dc.with_discrete_layer(
                         &stacking_ctx,
@@ -1188,7 +1165,7 @@ impl DrawingCtx {
         }
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         self.with_discrete_layer(
             &stacking_ctx,
@@ -1301,7 +1278,7 @@ impl DrawingCtx {
 
         let elt = node.borrow_element();
 
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         self.with_discrete_layer(
             &stacking_ctx,
@@ -1616,7 +1593,8 @@ impl DrawingCtx {
                 None
             };
 
-            let stacking_ctx = StackingContext::new(&use_element, Transform::identity(), values);
+            let stacking_ctx =
+                StackingContext::new(acquired_nodes, &use_element, Transform::identity(), values);
 
             self.with_discrete_layer(
                 &stacking_ctx,
@@ -1645,6 +1623,7 @@ impl DrawingCtx {
             // otherwise the referenced node is not a <symbol>; process it generically
 
             let stacking_ctx = StackingContext::new(
+                acquired_nodes,
                 &use_element,
                 Transform::new_translate(use_rect.x0, use_rect.y0),
                 values,
diff --git a/src/layout.rs b/src/layout.rs
index bc3b4495..ee520b4f 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -2,7 +2,9 @@
 //!
 //! The idea is to take the DOM tree and produce a layout tree with SVG concepts.
 
+use crate::document::AcquiredNodes;
 use crate::element::Element;
+use crate::node::*;
 use crate::properties::ComputedValues;
 use crate::property_defs::{Filter, Opacity};
 use crate::transform::Transform;
@@ -25,10 +27,12 @@ pub struct StackingContext {
     pub transform: Transform,
     pub opacity: Opacity,
     pub filter: Filter,
+    pub mask: Option<Node>,
 }
 
 impl StackingContext {
     pub fn new(
+        acquired_nodes: &mut AcquiredNodes<'_>,
         element: &Element,
         transform: Transform,
         values: &ComputedValues,
@@ -50,10 +54,38 @@ impl StackingContext {
             }
         }
 
+        let mask = values.mask().0.get().and_then(|mask_id| {
+            if let Ok(acquired) = acquired_nodes.acquire(mask_id) {
+                let node = acquired.get();
+                match *node.borrow_element() {
+                    Element::Mask(_) => Some(node.clone()),
+
+                    _ => {
+                        rsvg_log!(
+                            "element {} references \"{}\" which is not a mask",
+                            element,
+                            mask_id
+                        );
+
+                        None
+                    }
+                }
+            } else {
+                rsvg_log!(
+                    "element {} references nonexistent mask \"{}\"",
+                    element,
+                    mask_id
+                );
+
+                None
+            }
+        });
+
         StackingContext {
             transform,
             opacity,
             filter,
+            mask,
         }
     }
 }
diff --git a/src/marker.rs b/src/marker.rs
index 22a191b4..b3b5eb75 100644
--- a/src/marker.rs
+++ b/src/marker.rs
@@ -161,7 +161,7 @@ impl Marker {
         };
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, transform, values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, transform, values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
diff --git a/src/structure.rs b/src/structure.rs
index f62032f6..2f390cc4 100644
--- a/src/structure.rs
+++ b/src/structure.rs
@@ -35,7 +35,7 @@ impl Draw for Group {
         let values = cascaded.get();
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -77,7 +77,7 @@ impl Draw for Switch {
         let values = cascaded.get();
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -255,7 +255,7 @@ impl Draw for Svg {
         let values = cascaded.get();
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -507,7 +507,7 @@ impl Draw for Link {
         let values = cascaded.get();
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, elt.get_transform(), values);
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
diff --git a/src/text.rs b/src/text.rs
index 3e3478a6..d72a54fe 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -494,7 +494,7 @@ impl Draw for Text {
 
         let elt = node.borrow_element();
 
-        let stacking_ctx = StackingContext::new(&elt, elt.get_transform(), values);
+        let stacking_ctx = StackingContext::new(acquired_nodes, &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]