[librsvg: 1/19] Svg::get_size - Don't convert the size to ints



commit ff9993105399e4e2f6424f646286c624a8e6bdef
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Apr 22 14:21:40 2020 -0500

    Svg::get_size - Don't convert the size to ints
    
    Try to leave it as f64 for as long as possible, and have only the
    c_api glue round to ints at the very end.

 rsvg_internals/src/handle.rs    | 42 +++++++++++++++++++++++------------------
 rsvg_internals/src/structure.rs | 19 ++++++++++---------
 2 files changed, 34 insertions(+), 27 deletions(-)
---
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index abe07805..e1ca24fb 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -14,7 +14,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::element::Element;
 use crate::error::{DefsLookupErrorKind, LoadingError, RenderingError};
 use crate::node::{CascadedValues, Node, NodeBorrow};
-use crate::rect::{IRect, Rect};
+use crate::rect::Rect;
 use crate::structure::IntrinsicDimensions;
 use url::Url;
 
@@ -243,13 +243,16 @@ impl Handle {
     ) -> Result<RsvgDimensionData, RenderingError> {
         let (ink_r, _) = self.get_geometry_sub(id, dpi, is_testing)?;
 
-        let (w, h) = size_callback.call(ink_r.width as libc::c_int, ink_r.height as libc::c_int);
+        let width = ink_r.width().round() as libc::c_int;
+        let height = ink_r.height().round() as libc::c_int;
+
+        let (w, h) = size_callback.call(width, height);
 
         Ok(RsvgDimensionData {
             width: w,
             height: h,
-            em: ink_r.width,
-            ex: ink_r.height,
+            em: ink_r.width(),
+            ex: ink_r.height(),
         })
     }
 
@@ -266,14 +269,14 @@ impl Handle {
 
         let (ink_r, _) = self.get_geometry_sub(id, dpi, is_testing)?;
 
-        let width = ink_r.width as libc::c_int;
-        let height = ink_r.height as libc::c_int;
+        let width = ink_r.width().round() as libc::c_int;
+        let height = ink_r.height().round() as libc::c_int;
 
         size_callback.call(width, height);
 
         Ok(RsvgPositionData {
-            x: ink_r.x as libc::c_int,
-            y: ink_r.y as libc::c_int,
+            x: ink_r.x0 as libc::c_int,
+            y: ink_r.y0 as libc::c_int,
         })
     }
 
@@ -284,7 +287,7 @@ impl Handle {
         viewport: Rect,
         dpi: Dpi,
         is_testing: bool,
-    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
+    ) -> Result<(Rect, Rect), RenderingError> {
         let root = self.document.root();
 
         let target = cairo::ImageSurface::create(cairo::Format::Rgb24, 1, 1)?;
@@ -301,10 +304,7 @@ impl Handle {
         let ink_rect = bbox.ink_rect.unwrap_or_default();
         let logical_rect = bbox.rect.unwrap_or_default();
 
-        Ok((
-            cairo::Rectangle::from(ink_rect),
-            cairo::Rectangle::from(logical_rect),
-        ))
+        Ok((ink_rect, logical_rect))
     }
 
     /// Returns (ink_rect, logical_rect)
@@ -313,7 +313,7 @@ impl Handle {
         id: Option<&str>,
         dpi: Dpi,
         is_testing: bool,
-    ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
+    ) -> Result<(Rect, Rect), RenderingError> {
         let node = self.get_node_or_root(id)?;
 
         let root = self.document.root();
@@ -326,9 +326,8 @@ impl Handle {
             match *node.borrow_element() {
                 Element::Svg(ref svg) => {
                     if let Some((w, h)) = svg.get_size(&values, dpi) {
-                        let rect = IRect::from_size(w, h);
-
-                        return Ok((cairo::Rectangle::from(rect), cairo::Rectangle::from(rect)));
+                        let rect = Rect::from_size(w, h);
+                        return Ok((rect, rect));
                     }
                 }
                 _ => (),
@@ -355,7 +354,14 @@ impl Handle {
     ) -> Result<(cairo::Rectangle, cairo::Rectangle), RenderingError> {
         let node = self.get_node_or_root(id)?;
         let viewport = Rect::from(*viewport);
-        self.get_node_geometry_with_viewport(&node, viewport, dpi, is_testing)
+
+        let (ink_rect, logical_rect) =
+            self.get_node_geometry_with_viewport(&node, viewport, dpi, is_testing)?;
+
+        Ok((
+            cairo::Rectangle::from(ink_rect),
+            cairo::Rectangle::from(logical_rect),
+        ))
     }
 
     fn lookup_node(&self, id: &str) -> Result<Node, DefsLookupErrorKind> {
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index d1325bbb..4b76138d 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -106,26 +106,27 @@ pub struct Svg {
 }
 
 impl Svg {
-    pub fn get_size(&self, values: &ComputedValues, dpi: Dpi) -> Option<(i32, i32)> {
+    /// Returns the SVG's size suitable for the legacy C API, or None
+    /// if it must be computed by hand.
+    ///
+    /// The legacy C API can compute an SVG document's size from the
+    /// `width`, `height`, and `viewBox` attributes of the toplevel `<svg>`
+    /// element.  If these are not available, then the size must be computed
+    /// by actually measuring the geometries of elements in the document.
+    pub fn get_size(&self, values: &ComputedValues, dpi: Dpi) -> Option<(f64, f64)> {
         let (w, h) = self.get_unnormalized_size();
 
         match (w, h, self.vbox) {
             (w, h, Some(vbox)) => {
                 let params = ViewParams::new(dpi.x(), dpi.y(), vbox.0.width(), vbox.0.height());
 
-                Some((
-                    w.normalize(values, &params).round() as i32,
-                    h.normalize(values, &params).round() as i32,
-                ))
+                Some((w.normalize(values, &params), h.normalize(values, &params)))
             }
 
             (w, h, None) if w.unit != LengthUnit::Percent && h.unit != LengthUnit::Percent => {
                 let params = ViewParams::new(dpi.x(), dpi.y(), 0.0, 0.0);
 
-                Some((
-                    w.normalize(values, &params).round() as i32,
-                    h.normalize(values, &params).round() as i32,
-                ))
+                Some((w.normalize(values, &params), h.normalize(values, &params)))
             }
             (_, _, _) => None,
         }


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