[librsvg: 8/15] StackingContext: store the link_target here for <a> elements




commit 9058a34a1fa8196dfe2502c2d7206f9f4890a4d8
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Oct 18 12:38:54 2021 -0500

    StackingContext: store the link_target here for <a> elements
    
    The <a> Link element used to draw itself by wrapping its drawing in a
    call to DrawingCtx::with_link_tag().  We remove that function, pass
    the link target as part of StackingCtx, and deal with it in
    DrawingCtx::with_discrete_layer().
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/613>

 src/drawing_ctx.rs | 27 +++++++++++----------------
 src/layout.rs      | 16 ++++++++++++++++
 src/structure.rs   | 24 +++++++++++++++++-------
 3 files changed, 44 insertions(+), 23 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 6e76c922..8121edb2 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -690,6 +690,10 @@ impl DrawingCtx {
             draw_fn(acquired_nodes, self)
         } else {
             with_saved_cr(&self.cr.clone(), || {
+                if let Some(ref link_target) = stacking_ctx.link_target {
+                    self.link_tag_begin(&link_target);
+                }
+
                 let Opacity(UnitInterval(opacity)) = stacking_ctx.opacity;
 
                 let affine_at_start = self.get_transform();
@@ -712,7 +716,7 @@ impl DrawingCtx {
                     && stacking_ctx.mix_blend_mode == MixBlendMode::Normal
                     && stacking_ctx.clip_in_object_space.is_none());
 
-                if needs_temporary_surface {
+                let res = if needs_temporary_surface {
                     // Compute our assortment of affines
 
                     let affines = CompositingAffines::new(
@@ -868,7 +872,13 @@ impl DrawingCtx {
                     res
                 } else {
                     draw_fn(acquired_nodes, self)
+                };
+
+                if stacking_ctx.link_target.is_some() {
+                    self.link_tag_end();
                 }
+
+                res
             })
         };
 
@@ -924,21 +934,6 @@ impl DrawingCtx {
         self.cr.tag_end(CAIRO_TAG_LINK);
     }
 
-    /// Wraps the draw_fn in a link to the given target
-    pub fn with_link_tag(
-        &mut self,
-        link_target: &str,
-        draw_fn: &mut dyn FnMut(&mut DrawingCtx) -> Result<BoundingBox, RenderingError>,
-    ) -> Result<BoundingBox, RenderingError> {
-        self.link_tag_begin(link_target);
-
-        let res = draw_fn(self);
-
-        self.link_tag_end();
-
-        res
-    }
-
     fn run_filters(
         &mut self,
         surface_to_filter: SharedImageSurface,
diff --git a/src/layout.rs b/src/layout.rs
index 956fec3a..15eb28a8 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -47,6 +47,9 @@ pub struct StackingContext {
     pub clip_in_object_space: Option<Node>,
     pub mask: Option<Node>,
     pub mix_blend_mode: MixBlendMode,
+
+    /// Target from an <a> element
+    pub link_target: Option<String>,
 }
 
 /// Stroke parameters in user-space coordinates.
@@ -210,8 +213,21 @@ impl StackingContext {
             clip_in_object_space,
             mask,
             mix_blend_mode,
+            link_target: None,
         }
     }
+
+    pub fn new_with_link(
+        acquired_nodes: &mut AcquiredNodes<'_>,
+        element: &Element,
+        transform: Transform,
+        values: &ComputedValues,
+        link_target: Option<String>,
+    ) -> StackingContext {
+        let mut ctx = Self::new(acquired_nodes, element, transform, values);
+        ctx.link_target = link_target;
+        ctx
+    }
 }
 
 impl Stroke {
diff --git a/src/structure.rs b/src/structure.rs
index 3cc8ac46..f3e5477d 100644
--- a/src/structure.rs
+++ b/src/structure.rs
@@ -552,7 +552,22 @@ impl Draw for Link {
         let values = cascaded.get();
 
         let elt = node.borrow_element();
-        let stacking_ctx = StackingContext::new(acquired_nodes, &elt, values.transform(), values);
+
+        let link_is_empty = self.link.as_ref().map(|l| l.is_empty()).unwrap_or(true);
+
+        let link_target = if link_is_empty {
+            None
+        } else {
+            self.link.clone()
+        };
+
+        let stacking_ctx = StackingContext::new_with_link(
+            acquired_nodes,
+            &elt,
+            values.transform(),
+            values,
+            link_target,
+        );
 
         draw_ctx.with_discrete_layer(
             &stacking_ctx,
@@ -560,12 +575,7 @@ impl Draw for Link {
             values,
             clipping,
             None,
-            &mut |an, dc| match self.link.as_ref() {
-                Some(l) if !l.is_empty() => {
-                    dc.with_link_tag(l, &mut |dc| node.draw_children(an, &cascaded, dc, clipping))
-                }
-                _ => node.draw_children(an, &cascaded, dc, clipping),
-            },
+            &mut |an, dc| node.draw_children(an, &cascaded, dc, clipping),
         )
     }
 }


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