[librsvg] rsvg_handle_get_node_geometry(): Port to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg_handle_get_node_geometry(): Port to Rust
- Date: Wed, 19 Dec 2018 01:00:17 +0000 (UTC)
commit ef31c69cf593ecdf83ca6b8bfc22372e8de5bebd
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Dec 18 18:57:47 2018 -0600
rsvg_handle_get_node_geometry(): Port to Rust
Also added `impl From<cairo::Rectangle> for RsvgRectangle`.
librsvg/rsvg-handle.c | 52 +++++++---------------
rsvg_internals/src/drawing_ctx.rs | 51 ++++-----------------
rsvg_internals/src/handle.rs | 94 ++++++++++++++++++++++++++++++++++++++-
rsvg_internals/src/lib.rs | 7 +--
4 files changed, 118 insertions(+), 86 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index d9fd3f16..a252f396 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -176,6 +176,11 @@ 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);
+
/* 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! */
@@ -188,9 +193,6 @@ gboolean rsvg_node_svg_get_size (RsvgNode *node, double dpi_x, double dpi_y, int
/* 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;
-extern void rsvg_drawing_ctx_get_geometry (RsvgDrawingCtx *ctx,
- RsvgRectangle *ink_rect,
- RsvgRectangle *logical_rect);
struct RsvgHandlePrivate {
RsvgSizeFunc size_func;
@@ -1126,39 +1128,6 @@ rsvg_handle_get_dimensions (RsvgHandle * handle, RsvgDimensionData * dimension_d
}
}
-static gboolean
-get_node_geometry(RsvgHandle *handle, RsvgNode *node, RsvgRectangle *ink_rect, RsvgRectangle *logical_rect)
-{
- RsvgDimensionData dimensions;
- cairo_surface_t *target;
- cairo_t *cr;
- RsvgDrawingCtx *draw;
- gboolean res = FALSE;
-
- g_assert (node != NULL);
-
- rsvg_handle_get_dimensions (handle, &dimensions);
- if (dimensions.width == 0 || dimensions.height == 0)
- return res;
-
- target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
- cr = cairo_create (target);
-
- draw = rsvg_handle_create_drawing_ctx_for_node (handle, cr, &dimensions, node, handle->priv->is_testing);
-
- /* FIXME: expose this as a RenderingError in the public API */
- res = rsvg_drawing_ctx_draw_node_from_stack (draw);
- if (res) {
- rsvg_drawing_ctx_get_geometry (draw, ink_rect, logical_rect);
- }
-
- rsvg_drawing_ctx_free (draw);
- cairo_destroy (cr);
- cairo_surface_destroy (target);
-
- return res;
-}
-
/**
* rsvg_handle_get_dimensions_sub:
* @handle: A #RsvgHandle
@@ -1256,7 +1225,7 @@ rsvg_handle_get_geometry_sub (RsvgHandle * handle, RsvgRectangle * ink_rect, Rsv
&root_width, &root_height);
if (id || !has_size) {
- res = get_node_geometry (handle, node ? node : root, &ink_r, &logical_r);
+ res = rsvg_handle_get_node_geometry (handle, node ? node : root, &ink_r, &logical_r);
if (!res) {
goto out;
}
@@ -1607,6 +1576,15 @@ rsvg_handle_internal_set_testing (RsvgHandle *handle, gboolean testing)
rsvg_handle_update_font_map_for_testing (handle);
}
+G_GNUC_INTERNAL
+gboolean rsvg_handle_get_is_testing (RsvgHandle *handle);
+
+gboolean
+rsvg_handle_get_is_testing (RsvgHandle *handle)
+{
+ return handle->priv->is_testing;
+}
+
/* This one is defined in the C code, because the prototype has varargs
* and we can't handle those from Rust :(
*/
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 2229c58a..b8a436af 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1073,7 +1073,7 @@ pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
}
}
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Default, Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct RsvgRectangle {
pub x: f64,
@@ -1082,48 +1082,13 @@ pub struct RsvgRectangle {
pub height: f64,
}
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_drawing_ctx_get_geometry(
- raw_draw_ctx: *const DrawingCtx,
- ink_rect: *mut RsvgRectangle,
- logical_rect: *mut RsvgRectangle,
-) {
- assert!(!raw_draw_ctx.is_null());
- let draw_ctx = &*raw_draw_ctx;
-
- assert!(!ink_rect.is_null());
- assert!(!logical_rect.is_null());
-
- let ink_rect: &mut RsvgRectangle = &mut *ink_rect;
- let logical_rect: &mut RsvgRectangle = &mut *logical_rect;
-
- match draw_ctx.get_bbox().ink_rect {
- Some(r) => {
- ink_rect.x = r.x;
- ink_rect.y = r.y;
- ink_rect.width = r.width;
- ink_rect.height = r.height;
- }
- None => {
- ink_rect.x = 0.0;
- ink_rect.y = 0.0;
- ink_rect.width = 0.0;
- ink_rect.height = 0.0;
- }
- }
-
- match draw_ctx.get_bbox().rect {
- Some(r) => {
- logical_rect.x = r.x;
- logical_rect.y = r.y;
- logical_rect.width = r.width;
- logical_rect.height = r.height;
- }
- None => {
- logical_rect.x = 0.0;
- logical_rect.y = 0.0;
- logical_rect.width = 0.0;
- logical_rect.height = 0.0;
+impl From<cairo::Rectangle> for RsvgRectangle {
+ fn from(r: cairo::Rectangle) -> RsvgRectangle {
+ RsvgRectangle {
+ x: r.x,
+ y: r.y,
+ width: r.width,
+ height: r.height,
}
}
}
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f5200190..8b769ced 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,4 +1,5 @@
use std::cell::{Cell, Ref, RefCell};
+use std::mem;
use std::ptr;
use std::rc::Rc;
use std::slice;
@@ -17,7 +18,7 @@ use allowed_url::AllowedUrl;
use css::{self, CssStyles};
use defs::{Fragment, Href};
use dpi::Dpi;
-use drawing_ctx::DrawingCtx;
+use drawing_ctx::{DrawingCtx, RsvgRectangle};
use error::{set_gerror, LoadingError};
use io;
use load::LoadContext;
@@ -225,6 +226,56 @@ impl Handle {
draw_ctx
}
+
+ fn get_node_geometry(
+ &mut self,
+ handle: *mut RsvgHandle,
+ node: &RsvgNode,
+ ) -> Result<(RsvgRectangle, RsvgRectangle), ()> {
+ let mut dimensions = unsafe { mem::zeroed() };
+
+ unsafe {
+ rsvg_handle_get_dimensions(handle, &mut dimensions);
+ }
+
+ if dimensions.width == 0 || dimensions.height == 0 {
+ return Err(());
+ }
+
+ let target = ImageSurface::create(cairo::Format::Rgb24, 1, 1).map_err(|_| ())?;
+
+ let cr = cairo::Context::new(&target);
+
+ let mut draw_ctx = self.create_drawing_ctx_for_node(
+ handle,
+ &cr,
+ &dimensions,
+ Some(node),
+ is_testing(handle),
+ );
+
+ let svg_ref = self.svg.borrow();
+ let svg = svg_ref.as_ref().unwrap();
+
+ let root = svg.tree.root();
+
+ draw_ctx
+ .draw_node_from_stack(&root.get_cascaded_values(), &root, false)
+ .map_err(|_| ())?;
+
+ let bbox = draw_ctx.get_bbox();
+
+ let ink_rect = bbox
+ .ink_rect
+ .map(|r| RsvgRectangle::from(r))
+ .unwrap_or_else(|| RsvgRectangle::default());
+ let logical_rect = bbox
+ .rect
+ .map(|r| RsvgRectangle::from(r))
+ .unwrap_or_else(|| RsvgRectangle::default());
+
+ Ok((ink_rect, logical_rect))
+ }
}
// Keep these in sync with rsvg.h:RsvgHandleFlags
@@ -269,6 +320,14 @@ extern "C" {
) -> *mut RsvgHandle;
fn rsvg_handle_get_rust(handle: *const RsvgHandle) -> *mut Handle;
+
+ fn rsvg_handle_get_is_testing(handle: *const RsvgHandle) -> glib_sys::gboolean;
+
+ fn rsvg_handle_get_dimensions(handle: *mut RsvgHandle, dimensions: *mut RsvgDimensionData);
+}
+
+fn is_testing(handle: *const RsvgHandle) -> bool {
+ unsafe { from_glib(rsvg_handle_get_is_testing(handle)) }
}
pub fn lookup_node(handle: *const RsvgHandle, fragment: &Fragment) -> Option<Rc<Node>> {
@@ -731,3 +790,36 @@ pub unsafe extern "C" fn rsvg_handle_create_drawing_ctx_for_node(
Box::into_raw(Box::new(draw_ctx))
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_get_node_geometry(
+ handle: *mut RsvgHandle,
+ node: *const RsvgNode,
+ out_ink_rect: *mut RsvgRectangle,
+ out_logical_rect: *mut RsvgRectangle,
+) -> glib_sys::gboolean {
+ let rhandle = get_rust_handle(handle);
+
+ assert!(!node.is_null());
+ let node = &*node;
+
+ assert!(!out_ink_rect.is_null());
+ assert!(!out_logical_rect.is_null());
+
+ let out_ink_rect = &mut *out_ink_rect;
+ let out_logical_rect = &mut *out_logical_rect;
+
+ 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();
+ false.to_glib()
+ }
+ }
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index ad809e8a..21d6277c 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -35,15 +35,12 @@ extern crate lazy_static;
pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};
-pub use drawing_ctx::{
- rsvg_drawing_ctx_draw_node_from_stack,
- rsvg_drawing_ctx_free,
- rsvg_drawing_ctx_get_geometry,
-};
+pub use drawing_ctx::{rsvg_drawing_ctx_draw_node_from_stack, rsvg_drawing_ctx_free};
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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]