[librsvg] rsvg_handle_rust_get_geometry_sub(): Port to Rust.



commit c596fcfbe39c08561c75b71b835c0abeb7de853e
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Dec 19 12:38:28 2018 -0600

    rsvg_handle_rust_get_geometry_sub(): Port to Rust.

 librsvg/rsvg-handle.c           |  70 ++--------------------------
 rsvg_internals/src/handle.rs    | 101 ++++++++++++++++++++++++----------------
 rsvg_internals/src/lib.rs       |   6 +--
 rsvg_internals/src/structure.rs |  55 +++++++---------------
 4 files changed, 83 insertions(+), 149 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 92f08530..9dc3aacc 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -158,10 +158,8 @@ extern double rsvg_handle_rust_get_dpi_y (RsvgHandleRust *raw_handle);
 extern void rsvg_handle_rust_set_dpi_x (RsvgHandleRust *raw_handle, double dpi_x);
 extern void rsvg_handle_rust_set_dpi_y (RsvgHandleRust *raw_handle, double dpi_y);
 extern void rsvg_handle_rust_set_base_url (RsvgHandleRust *raw_handle, const char *uri);
-extern RsvgNode *rsvg_handle_rust_get_root (RsvgHandleRust *raw_handle);
 extern GFile *rsvg_handle_rust_get_base_gfile (RsvgHandleRust *raw_handle);
 extern RsvgNode *rsvg_handle_defs_lookup (RsvgHandle *handle, const char *name);
-extern gboolean rsvg_handle_rust_node_is_root(RsvgHandleRust *raw_handle, RsvgNode *node);
 extern guint rsvg_handle_rust_get_flags (RsvgHandleRust *raw_handle);
 extern void rsvg_handle_rust_set_flags (RsvgHandleRust *raw_handle, guint flags);
 extern RsvgHandleState rsvg_handle_rust_get_load_state (RsvgHandleRust *raw_handle);
@@ -176,20 +174,15 @@ extern RsvgDrawingCtx *rsvg_handle_create_drawing_ctx_for_node(RsvgHandle *handl
                                                                RsvgDimensionData *dimensions,
                                                                RsvgNode *node,
                                                                gboolean is_testing);
-extern gboolean rsvg_handle_get_node_geometry(RsvgHandle *handle,
-                                              RsvgNode *node,
-                                              RsvgRectangle *ink_rect,
-                                              RsvgRectangle *logical_rect);
-
+extern gboolean rsvg_handle_rust_get_geometry_sub (RsvgHandle *handle,
+                                                   RsvgRectangle *out_ink_rect,
+                                                   RsvgRectangle *out_logical_rect,
+                                                   const char *id);
 
 /* Implemented in rust/src/node.rs */
 /* Call this as node = rsvg_node_unref (node);  Then node will be NULL and you don't own it anymore! */
 extern RsvgNode *rsvg_node_unref (RsvgNode *node);
 
-/* Implemented in rsvg_internals/src/structure.rs */
-G_GNUC_INTERNAL
-gboolean rsvg_node_svg_get_size (RsvgNode *node, double dpi_x, double dpi_y, int *out_width, int 
*out_height);
-
 /* Defined in rsvg_internals/src/drawing_ctx.rs */
 extern void rsvg_drawing_ctx_free (RsvgDrawingCtx *draw_ctx);
 extern gboolean rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx) G_GNUC_WARN_UNUSED_RESULT;
@@ -1190,66 +1183,13 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
 gboolean
 rsvg_handle_get_geometry_sub (RsvgHandle * handle, RsvgRectangle * ink_rect, RsvgRectangle * logical_rect, 
const char *id)
 {
-    RsvgNode *node = NULL;
-    gboolean res = FALSE;
-    RsvgRectangle ink_r, logical_r;
-
     g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE);
 
-    memset (&ink_r, 0, sizeof (RsvgRectangle));
-    memset (&logical_r, 0, sizeof (RsvgRectangle));
-
     if (!is_loaded (handle)) {
         return FALSE;
     }
 
-    if (id && *id) {
-        node = rsvg_handle_defs_lookup (handle, id);
-    } else {
-        node = rsvg_handle_rust_get_root (handle->priv->rust_handle);
-    }
-
-    if (!node) {
-        goto out;
-    }
-
-    if (rsvg_handle_rust_node_is_root (handle->priv->rust_handle, node)) {
-        int root_width, root_height;
-        if (rsvg_node_svg_get_size (node,
-                                    rsvg_handle_rust_get_dpi_x (handle->priv->rust_handle),
-                                    rsvg_handle_rust_get_dpi_y (handle->priv->rust_handle),
-                                    &root_width, &root_height))
-        {
-            ink_r.width = root_width;
-            ink_r.height = root_height;
-            ink_r.x = 0;
-            ink_r.y = 0;
-
-            logical_r.width = root_width;
-            logical_r.height = root_height;
-            logical_r.x = 0;
-            logical_r.y = 0;
-
-            res = TRUE;
-            goto out;
-        }
-    }
-
-    res = rsvg_handle_get_node_geometry (handle, node, &ink_r, &logical_r);
-
-out:
-
-    if (ink_rect != NULL) {
-        *ink_rect = ink_r;
-    }
-
-    if (logical_rect != NULL) {
-        *logical_rect = logical_r;
-    }
-
-    g_clear_pointer (&node, rsvg_node_unref);
-
-    return res;
+    return rsvg_handle_rust_get_geometry_sub(handle, ink_rect, logical_rect, id);
 }
 
 /**
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index d1bb5a5f..5d388d30 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -23,6 +23,7 @@ use error::{set_gerror, LoadingError};
 use io;
 use load::LoadContext;
 use node::{box_node, Node, RsvgNode};
+use structure::NodeSvg;
 use surface_utils::shared_surface::SharedImageSurface;
 use svg::Svg;
 use util::rsvg_g_warning;
@@ -277,6 +278,46 @@ impl Handle {
         Ok((ink_rect, logical_rect))
     }
 
+    fn get_geometry_sub(
+        &mut self,
+        handle: *mut RsvgHandle,
+        id: Option<&str>,
+    ) -> Result<(RsvgRectangle, RsvgRectangle), ()> {
+        let root = {
+            let svg_ref = self.svg.borrow();
+            let svg = svg_ref.as_ref().unwrap();
+
+            svg.tree.root()
+        };
+
+        let (node, is_root) = if let Some(id) = id {
+            let n = self.defs_lookup(handle, id).map_err(|_| ())?;
+            let is_root = Rc::ptr_eq(&n, &root);
+            (n, is_root)
+        } else {
+            (root, true)
+        };
+
+        if is_root {
+            if let Some((root_width, root_height)) =
+                node.with_impl(|svg: &NodeSvg| svg.get_size(self.dpi.x(), self.dpi.y()))
+            {
+                let ink_r = RsvgRectangle {
+                    x: 0.0,
+                    y: 0.0,
+                    width: f64::from(root_width),
+                    height: f64::from(root_height),
+                };
+
+                let logical_r = ink_r;
+
+                return Ok((ink_r, logical_r));
+            }
+        }
+
+        self.get_node_geometry(handle, &node)
+    }
+
     fn defs_lookup(
         &mut self,
         handle: *const RsvgHandle,
@@ -672,32 +713,6 @@ pub unsafe extern "C" fn rsvg_handle_defs_lookup(
     }
 }
 
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_get_root(raw_handle: *const Handle) -> *const RsvgNode {
-    let rhandle = &*raw_handle;
-
-    let svg_ref = rhandle.svg.borrow();
-    let svg = svg_ref.as_ref().unwrap();
-
-    box_node(svg.tree.root())
-}
-
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_node_is_root(
-    raw_handle: *const Handle,
-    node: *mut RsvgNode,
-) -> glib_sys::gboolean {
-    let rhandle = &*raw_handle;
-
-    assert!(!node.is_null());
-    let node: &RsvgNode = &*node;
-
-    let svg_ref = rhandle.svg.borrow();
-    let svg = svg_ref.as_ref().unwrap();
-
-    Rc::ptr_eq(&svg.tree.root(), node).to_glib()
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_get_flags(raw_handle: *const Handle) -> u32 {
     let rhandle = &*raw_handle;
@@ -806,33 +821,39 @@ pub unsafe extern "C" fn rsvg_handle_create_drawing_ctx_for_node(
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_get_node_geometry(
+pub unsafe extern "C" fn rsvg_handle_rust_get_geometry_sub(
     handle: *mut RsvgHandle,
-    node: *const RsvgNode,
     out_ink_rect: *mut RsvgRectangle,
     out_logical_rect: *mut RsvgRectangle,
+    id: *const libc::c_char,
 ) -> glib_sys::gboolean {
     let rhandle = get_rust_handle(handle);
 
-    assert!(!node.is_null());
-    let node = &*node;
+    let id: Option<String> = from_glib_none(id);
 
-    assert!(!out_ink_rect.is_null());
-    assert!(!out_logical_rect.is_null());
+    match rhandle.get_geometry_sub(handle, id.as_ref().map(String::as_str)) {
+        Ok((ink_r, logical_r)) => {
+            if !out_ink_rect.is_null() {
+                *out_ink_rect = ink_r;
+            }
 
-    let out_ink_rect = &mut *out_ink_rect;
-    let out_logical_rect = &mut *out_logical_rect;
+            if !out_logical_rect.is_null() {
+                *out_logical_rect = logical_r;
+            }
 
-    match rhandle.get_node_geometry(handle, node) {
-        Ok((ink_rect, logical_rect)) => {
-            *out_ink_rect = ink_rect;
-            *out_logical_rect = logical_rect;
             true.to_glib()
         }
 
         Err(()) => {
-            *out_ink_rect = mem::zeroed();
-            *out_logical_rect = mem::zeroed();
+            if !out_ink_rect.is_null() {
+                *out_ink_rect = mem::zeroed();
+            }
+
+            if !out_logical_rect.is_null() {
+                *out_logical_rect = mem::zeroed();
+            }
+
+            // FIXME: return a proper error code to the public API
             false.to_glib()
         }
     }
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 21d6277c..78531f7d 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -40,17 +40,15 @@ pub use drawing_ctx::{rsvg_drawing_ctx_draw_node_from_stack, rsvg_drawing_ctx_fr
 pub use handle::{
     rsvg_handle_create_drawing_ctx_for_node,
     rsvg_handle_defs_lookup,
-    rsvg_handle_get_node_geometry,
     rsvg_handle_rust_close,
     rsvg_handle_rust_free,
     rsvg_handle_rust_get_base_gfile,
     rsvg_handle_rust_get_dpi_x,
     rsvg_handle_rust_get_dpi_y,
     rsvg_handle_rust_get_flags,
+    rsvg_handle_rust_get_geometry_sub,
     rsvg_handle_rust_get_load_state,
-    rsvg_handle_rust_get_root,
     rsvg_handle_rust_new,
-    rsvg_handle_rust_node_is_root,
     rsvg_handle_rust_read_stream_sync,
     rsvg_handle_rust_set_base_url,
     rsvg_handle_rust_set_dpi_x,
@@ -61,8 +59,6 @@ pub use handle::{
 
 pub use node::rsvg_node_unref;
 
-pub use structure::rsvg_node_svg_get_size;
-
 pub use xml::rsvg_xml_state_error;
 
 #[macro_use]
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index f077555b..580953a6 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -1,9 +1,6 @@
 use std::cell::Cell;
 use std::cell::RefCell;
 
-use glib::translate::*;
-use glib_sys;
-
 use aspect_ratio::*;
 use attributes::Attribute;
 use css::CssStyles;
@@ -13,7 +10,6 @@ use error::{AttributeResultExt, RenderingError};
 use float_eq_cairo::ApproxEqCairo;
 use handle::RsvgHandle;
 use length::*;
-use libc;
 use node::*;
 use parsers::{parse, parse_and_validate, Parse};
 use property_bag::{OwnedPropertyBag, PropertyBag};
@@ -124,6 +120,22 @@ impl NodeSvg {
             node.set_style(css_styles, &pbag);
         }
     }
+
+    pub fn get_size(&self, dpi_x: f64, dpi_y: f64) -> Option<(i32, i32)> {
+        match (self.w.get(), self.h.get(), self.vbox.get()) {
+            (w, h, Some(vb)) => Some((
+                w.hand_normalize(dpi_x, vb.0.width, 12.0).round() as i32,
+                h.hand_normalize(dpi_y, vb.0.height, 12.0).round() as i32,
+            )),
+            (w, h, None) if w.unit != LengthUnit::Percent && h.unit != LengthUnit::Percent => {
+                Some((
+                    w.hand_normalize(dpi_x, 0.0, 12.0).round() as i32,
+                    h.hand_normalize(dpi_y, 0.0, 12.0).round() as i32,
+                ))
+            }
+            (_, _, _) => None,
+        }
+    }
 }
 
 impl NodeTrait for NodeSvg {
@@ -435,38 +447,3 @@ impl NodeTrait for NodeSymbol {
         Ok(())
     }
 }
-
-#[no_mangle]
-pub extern "C" fn rsvg_node_svg_get_size(
-    raw_node: *const RsvgNode,
-    dpi_x: libc::c_double,
-    dpi_y: libc::c_double,
-    out_width: *mut i32,
-    out_height: *mut i32,
-) -> glib_sys::gboolean {
-    assert!(!raw_node.is_null());
-    let node: &RsvgNode = unsafe { &*raw_node };
-
-    assert!(!out_width.is_null());
-    assert!(!out_height.is_null());
-
-    node.with_impl(
-        |svg: &NodeSvg| match (svg.w.get(), svg.h.get(), svg.vbox.get()) {
-            (w, h, Some(vb)) => {
-                unsafe {
-                    *out_width = w.hand_normalize(dpi_x, vb.0.width, 12.0).round() as i32;
-                    *out_height = h.hand_normalize(dpi_y, vb.0.height, 12.0).round() as i32;
-                }
-                true.to_glib()
-            }
-            (w, h, None) if w.unit != LengthUnit::Percent && h.unit != LengthUnit::Percent => {
-                unsafe {
-                    *out_width = w.hand_normalize(dpi_x, 0.0, 12.0).round() as i32;
-                    *out_height = h.hand_normalize(dpi_y, 0.0, 12.0).round() as i32;
-                }
-                true.to_glib()
-            }
-            (_, _, _) => false.to_glib(),
-        },
-    )
-}


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