[librsvg: 4/7] drawing_ctx: add with_link_tag method



commit b6b73aa0ab494395f1c8dd9c00b98d89ee0d83e7
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Jan 2 17:19:49 2020 +0100

    drawing_ctx: add with_link_tag method
    
    And use it in the link element, so that it becomes independent
    from cairo.

 rsvg_internals/src/drawing_ctx.rs | 36 ++++++++++++++++++++++++++++++++++++
 rsvg_internals/src/link.rs        | 30 +-----------------------------
 2 files changed, 37 insertions(+), 29 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 61db8250..46beb4d8 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1,6 +1,9 @@
 //! The main context structure which drives the drawing process.
 
 use cairo;
+use once_cell::sync::Lazy;
+use regex::{Captures, Regex};
+use std::borrow::Cow;
 use std::cell::RefCell;
 use std::convert::TryFrom;
 use std::rc::{Rc, Weak};
@@ -665,6 +668,26 @@ impl DrawingCtx {
         res
     }
 
+    /// 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> {
+        const CAIRO_TAG_LINK: &str = "Link";
+
+        let attributes = format!("uri='{}'", escape_link_target(link_target));
+
+        let cr = self.get_cairo_context();
+        cr.tag_begin(CAIRO_TAG_LINK, &attributes);
+
+        let res = draw_fn(self);
+
+        cr.tag_end(CAIRO_TAG_LINK);
+
+        res
+    }
+
     fn run_filter(
         &mut self,
         filter_uri: &Fragment,
@@ -1077,6 +1100,19 @@ fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) ->
     bbox
 }
 
+/// escape quotes and backslashes with backslash
+fn escape_link_target(value: &str) -> Cow<'_, str> {
+    static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"['\\]").unwrap());
+
+    REGEX.replace_all(value, |caps: &Captures<'_>| {
+        match caps.get(0).unwrap().as_str() {
+            "'" => "\\'".to_owned(),
+            "\\" => "\\\\".to_owned(),
+            _ => unreachable!(),
+        }
+    })
+}
+
 impl From<StrokeLinejoin> for cairo::LineJoin {
     fn from(j: StrokeLinejoin) -> cairo::LineJoin {
         match j {
diff --git a/rsvg_internals/src/link.rs b/rsvg_internals/src/link.rs
index 0104dc91..e8e5d9bf 100644
--- a/rsvg_internals/src/link.rs
+++ b/rsvg_internals/src/link.rs
@@ -1,9 +1,6 @@
 //! The `link` element.
 
 use markup5ever::{expanded_name, local_name, namespace_url, ns};
-use once_cell::sync::Lazy;
-use regex::{Captures, Regex};
-use std::borrow::Cow;
 
 use crate::bbox::BoundingBox;
 use crate::drawing_ctx::DrawingCtx;
@@ -40,34 +37,9 @@ impl NodeTrait for Link {
 
         draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| match self.link.as_ref() {
             Some(l) if !l.is_empty() => {
-                const CAIRO_TAG_LINK: &str = "Link";
-
-                let attributes = format!("uri='{}'", escape_value(l));
-
-                let cr = dc.get_cairo_context();
-
-                cr.tag_begin(CAIRO_TAG_LINK, &attributes);
-
-                let res = node.draw_children(&cascaded, dc, clipping);
-
-                cr.tag_end(CAIRO_TAG_LINK);
-
-                res
+                dc.with_link_tag(l, &mut |dc| node.draw_children(&cascaded, dc, clipping))
             }
             _ => node.draw_children(&cascaded, dc, clipping),
         })
     }
 }
-
-/// escape quotes and backslashes with backslash
-fn escape_value(value: &str) -> Cow<'_, str> {
-    static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"['\\]").unwrap());
-
-    REGEX.replace_all(value, |caps: &Captures<'_>| {
-        match caps.get(0).unwrap().as_str() {
-            "'" => "\\'".to_owned(),
-            "\\" => "\\\\".to_owned(),
-            _ => unreachable!(),
-        }
-    })
-}


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