[librsvg] librsvg_crate: geometry_for_element() now takes a viewport



commit 1ab33c940c940b5484713f8fbba8c1cb2ea6f6ad
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Mar 4 19:27:02 2019 -0600

    librsvg_crate: geometry_for_element() now takes a viewport
    
    SVG really wants to be rendered/measured as *scalable*, based on the
    viewport size you want it in.
    
    This is especially important for SVGs which have percent dimensions:
    
      <svg width="100%" height="100%" viewBox=...>
    
    In those, asking for the dimensions of an element doesn't make sense
    unless there's a viewport size against which the "100%" will be
    resolved.
    
    In the C API, we resolved percent sizes to "SVG has no size".

 librsvg_crate/src/lib.rs                    |  6 ++--
 librsvg_crate/tests/intrinsic-dimensions.rs | 53 +++++++++++++++++++++++++----
 rsvg_internals/src/handle.rs                | 13 +++++--
 3 files changed, 61 insertions(+), 11 deletions(-)
---
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index b3231d7b..a7741baf 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -377,7 +377,8 @@ impl<'a> CairoRenderer<'a> {
         }
     }
 
-    /// Computes the (ink_rect, logical_rect) of an SVG element.
+    /// Computes the (ink_rect, logical_rect) of an SVG element, as if
+    /// it were rendered to a specific viewport.
     ///
     /// Element IDs should look like an URL fragment identifier; for
     /// example, pass `Some("#foo")` to get the geometry of the
@@ -403,10 +404,11 @@ impl<'a> CairoRenderer<'a> {
     pub fn geometry_for_element(
         &self,
         id: Option<&str>,
+        viewport: &cairo::Rectangle,
     ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
         self.handle
             .0
-            .get_geometry_for_element(id)
+            .get_geometry_for_element(id, viewport)
             .map(|(i, l)| (i.into(), l.into()))
     }
 
diff --git a/librsvg_crate/tests/intrinsic-dimensions.rs b/librsvg_crate/tests/intrinsic-dimensions.rs
index 564ad2c5..a132eb34 100644
--- a/librsvg_crate/tests/intrinsic-dimensions.rs
+++ b/librsvg_crate/tests/intrinsic-dimensions.rs
@@ -79,7 +79,15 @@ fn root_geometry_with_percent_viewport() {
     );
 
     let renderer = CairoRenderer::new(&svg);
-    let (ink_r, logical_r) = renderer.geometry_for_element(None).unwrap();
+
+    let viewport = cairo::Rectangle {
+        x: 0.0,
+        y: 0.0,
+        width: 100.0,
+        height: 100.0,
+    };
+
+    let (ink_r, logical_r) = renderer.geometry_for_element(None, &viewport).unwrap();
 
     let rect = cairo::Rectangle {
         x: 10.0,
@@ -102,7 +110,15 @@ fn element_geometry_with_percent_viewport() {
     );
 
     let renderer = CairoRenderer::new(&svg);
-    let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo")).unwrap();
+
+    let viewport = cairo::Rectangle {
+        x: 0.0,
+        y: 0.0,
+        width: 100.0,
+        height: 100.0,
+    };
+
+    let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo"), &viewport).unwrap();
 
     let rect = cairo::Rectangle {
         x: 10.0,
@@ -126,7 +142,15 @@ fn element_geometry_viewport_viewbox() {
     );
 
     let renderer = CairoRenderer::new(&svg);
-    let (ink_r, logical_r) = renderer.geometry_for_element(Some("#two")).unwrap();
+
+    let viewport = cairo::Rectangle {
+        x: 0.0,
+        y: 0.0,
+        width: 100.0,
+        height: 400.0,
+    };
+
+    let (ink_r, logical_r) = renderer.geometry_for_element(Some("#two"), &viewport).unwrap();
 
     let rect = cairo::Rectangle {
         x: 0.0,
@@ -146,8 +170,16 @@ fn element_geometry_for_nonexistent_element() {
 "#,
     );
 
+    let viewport = cairo::Rectangle {
+        x: 0.0,
+        y: 0.0,
+        width: 100.0,
+        height: 100.0,
+    };
+
     let renderer = CairoRenderer::new(&svg);
-    match renderer.geometry_for_element(Some("#foo")) {
+
+    match renderer.geometry_for_element(Some("#foo"), &viewport) {
         Err(RenderingError::InvalidId(DefsLookupErrorKind::NotFound)) => (),
         _ => panic!(),
     }
@@ -161,18 +193,25 @@ fn element_geometry_for_invalid_id() {
 "#,
     );
 
+    let viewport = cairo::Rectangle {
+        x: 0.0,
+        y: 0.0,
+        width: 100.0,
+        height: 100.0,
+    };
+
     let renderer = CairoRenderer::new(&svg);
-    match renderer.geometry_for_element(Some("foo")) {
+    match renderer.geometry_for_element(Some("foo"), &viewport) {
         Err(RenderingError::InvalidId(DefsLookupErrorKind::CannotLookupExternalReferences)) => (),
         _ => panic!(),
     }
 
-    match renderer.geometry_for_element(Some("foo.svg#foo")) {
+    match renderer.geometry_for_element(Some("foo.svg#foo"), &viewport) {
         Err(RenderingError::InvalidId(DefsLookupErrorKind::CannotLookupExternalReferences)) => (),
         _ => panic!(),
     }
 
-    match renderer.geometry_for_element(Some("")) {
+    match renderer.geometry_for_element(Some(""), &viewport) {
         Err(RenderingError::InvalidId(DefsLookupErrorKind::HrefError(HrefError::ParseError))) => (),
         _ => panic!(),
     }
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 41bb1751..22b27a72 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -448,9 +448,17 @@ impl Handle {
             height: 1.0,
         };
 
+        self.get_node_geometry_with_viewport(node, &viewport)
+    }
+
+    fn get_node_geometry_with_viewport(
+        &self,
+        node: &RsvgNode,
+        viewport: &cairo::Rectangle,
+    ) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
         let target = ImageSurface::create(cairo::Format::Rgb24, 1, 1)?;
         let cr = cairo::Context::new(&target);
-        let mut draw_ctx = self.create_drawing_ctx_for_node(&cr, &viewport, Some(node));
+        let mut draw_ctx = self.create_drawing_ctx_for_node(&cr, viewport, Some(node));
         let root = self.get_root();
 
         draw_ctx.draw_node_from_stack(&root.get_cascaded_values(), &root, false)?;
@@ -513,9 +521,10 @@ impl Handle {
     pub fn get_geometry_for_element(
         &self,
         id: Option<&str>,
+        viewport: &cairo::Rectangle,
     ) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
         let node = self.get_node_or_root(id)?;
-        self.get_node_geometry(&node)
+        self.get_node_geometry_with_viewport(&node, viewport)
     }
 
     fn lookup_node(&self, id: &str) -> Result<RsvgNode, DefsLookupErrorKind> {


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