[librsvg: 7/14] handle: move the size_func in the rust handle
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 7/14] handle: move the size_func in the rust handle
- Date: Sun, 6 Jan 2019 03:25:24 +0000 (UTC)
commit 845b41c4d212079d8db1ec7bca4cba06cc36ab38
Author: Paolo Borelli <pborelli gnome org>
Date: Sat Jan 5 14:36:57 2019 +0100
handle: move the size_func in the rust handle
This requires creating and intermediate closure struct
librsvg/rsvg-handle.c | 74 +++++++++++++++++++++++++++++++-------------
rsvg_internals/src/handle.rs | 56 +++++++++++++++++++++++++++++++++
rsvg_internals/src/lib.rs | 2 ++
3 files changed, 111 insertions(+), 21 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index ba962389..4710c462 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -171,11 +171,53 @@ extern gboolean rsvg_handle_rust_render_cairo_sub (RsvgHandle *handle,
const char *id);
extern GdkPixbuf *rsvg_handle_rust_get_pixbuf_sub (RsvgHandle *handle, const char *id);
-struct RsvgHandlePrivate {
- RsvgSizeFunc size_func;
- gpointer user_data;
- GDestroyNotify user_data_destroy;
+typedef struct {
+ RsvgSizeFunc func;
+ gpointer data;
+ GDestroyNotify data_destroy;
+} RsvgSizeClosure;
+
+static RsvgSizeClosure *
+rsvg_size_closure_new (RsvgSizeFunc func, gpointer data, GDestroyNotify data_destroy)
+{
+ RsvgSizeClosure *closure;
+
+ closure = g_new0(RsvgSizeClosure, 1);
+ closure->func = func;
+ closure->data = data;
+ closure->data_destroy = data_destroy;
+
+ return closure;
+}
+
+G_GNUC_INTERNAL
+void rsvg_size_closure_free (RsvgSizeClosure *closure);
+
+void
+rsvg_size_closure_free (RsvgSizeClosure *closure)
+{
+ if (closure && closure->data && closure->data_destroy) {
+ (*closure->data_destroy) (closure->data);
+ }
+
+ g_free (closure);
+}
+G_GNUC_INTERNAL
+void rsvg_size_closure_call (RsvgSizeClosure *closure, int *width, int *height);
+
+void
+rsvg_size_closure_call (RsvgSizeClosure *closure, int *width, int *height)
+{
+ if (closure && closure->func) {
+ (*closure->func) (width, height, closure->data);
+ }
+}
+
+extern void rsvg_handle_rust_set_size_closure (RsvgHandleRust *raw_handle, RsvgSizeClosure *closure);
+extern void rsvg_handle_rust_call_size_closure (RsvgHandleRust *raw_handle, int *width, int *height);
+
+struct RsvgHandlePrivate {
gchar *base_uri; // Keep this here; since rsvg_handle_get_base_uri() returns a const char *
gboolean in_loop; /* see get_dimension() */
@@ -217,11 +259,6 @@ rsvg_handle_dispose (GObject *instance)
{
RsvgHandle *self = (RsvgHandle *) instance;
- if (self->priv->user_data_destroy) {
- (*self->priv->user_data_destroy) (self->priv->user_data);
- self->priv->user_data_destroy = NULL;
- }
-
g_clear_pointer (&self->priv->base_uri, g_free);
g_clear_pointer (&self->priv->rust_handle, rsvg_handle_rust_free);
@@ -1048,9 +1085,8 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
dimension_data->em = dimension_data->width;
dimension_data->ex = dimension_data->height;
- if (handle->priv->size_func)
- (*handle->priv->size_func) (&dimension_data->width, &dimension_data->height,
- handle->priv->user_data);
+ rsvg_handle_rust_call_size_closure (handle->priv->rust_handle, &dimension_data->width,
&dimension_data->height);
+
return TRUE;
}
@@ -1123,8 +1159,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
width = ink_r.width;
height = ink_r.height;
- if (handle->priv->size_func)
- (*handle->priv->size_func) (&width, &height, handle->priv->user_data);
+ rsvg_handle_rust_call_size_closure (handle->priv->rust_handle, &width, &height);
return TRUE;
}
@@ -1286,16 +1321,13 @@ rsvg_handle_set_dpi_x_y (RsvgHandle * handle, double dpi_x, double dpi_y)
void
rsvg_handle_set_size_callback (RsvgHandle * handle,
RsvgSizeFunc size_func,
- gpointer user_data, GDestroyNotify user_data_destroy)
+ gpointer user_data,
+ GDestroyNotify user_data_destroy)
{
g_return_if_fail (RSVG_IS_HANDLE (handle));
- if (handle->priv->user_data_destroy)
- (*handle->priv->user_data_destroy) (handle->priv->user_data);
-
- handle->priv->size_func = size_func;
- handle->priv->user_data = user_data;
- handle->priv->user_data_destroy = user_data_destroy;
+ rsvg_handle_rust_set_size_closure (handle->priv->rust_handle,
+ rsvg_size_closure_new (size_func, user_data, user_data_destroy));
}
/**
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f247dc2c..fe5f2e4e 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -42,6 +42,23 @@ pub struct RsvgHandle {
_private: [u8; 0],
}
+// A *const RsvgSizeClosure is just an opaque pointer we get from C
+#[repr(C)]
+pub struct RsvgSizeClosure {
+ _private: [u8; 0],
+}
+
+#[allow(improper_ctypes)]
+extern "C" {
+ fn rsvg_size_closure_free(closure: *mut RsvgSizeClosure);
+
+ fn rsvg_size_closure_call(
+ closure: *const RsvgSizeClosure,
+ width: *mut libc::c_int,
+ height: *mut libc::c_int,
+ );
+}
+
// Keep in sync with rsvg.h:RsvgDimensionData
#[repr(C)]
pub struct RsvgDimensionData {
@@ -79,6 +96,7 @@ pub struct Handle {
load_options: Cell<LoadOptions>,
load_state: Cell<LoadState>,
load: RefCell<Option<LoadContext>>,
+ size_closure: *mut RsvgSizeClosure,
is_testing: Cell<bool>,
}
@@ -91,6 +109,7 @@ impl Handle {
load_options: Cell::new(LoadOptions::default()),
load_state: Cell::new(LoadState::Start),
load: RefCell::new(None),
+ size_closure: ptr::null_mut(),
is_testing: Cell::new(false),
}
}
@@ -462,6 +481,16 @@ impl Handle {
}
}
+impl Drop for Handle {
+ fn drop(&mut self) {
+ if !self.size_closure.is_null() {
+ unsafe {
+ rsvg_size_closure_free(self.size_closure);
+ }
+ }
+ }
+}
+
// Keep these in sync with rsvg.h:RsvgHandleFlags
const RSVG_HANDLE_FLAG_UNLIMITED: u32 = 1 << 0;
const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: u32 = 1 << 1;
@@ -796,6 +825,33 @@ pub unsafe extern "C" fn rsvg_handle_rust_set_flags(raw_handle: *const Handle, f
rhandle.load_options.set(LoadOptions::from_flags(flags));
}
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_set_size_closure(
+ raw_handle: *mut Handle,
+ closure: *mut RsvgSizeClosure,
+) {
+ let rhandle = &mut *raw_handle;
+
+ if !rhandle.size_closure.is_null() {
+ rsvg_size_closure_free(rhandle.size_closure);
+ }
+
+ rhandle.size_closure = closure;
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_rust_call_size_closure(
+ raw_handle: *const Handle,
+ width: *mut libc::c_int,
+ height: *mut libc::c_int,
+) {
+ let rhandle = &*raw_handle;
+
+ if !rhandle.size_closure.is_null() {
+ rsvg_size_closure_call(rhandle.size_closure, width, height);
+ }
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_rust_set_testing(
raw_handle: *const Handle,
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 60303056..ea5d3db8 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -37,6 +37,7 @@ extern crate lazy_static;
pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};
pub use handle::{
+ rsvg_handle_rust_call_size_closure,
rsvg_handle_rust_close,
rsvg_handle_rust_free,
rsvg_handle_rust_get_base_gfile,
@@ -55,6 +56,7 @@ pub use handle::{
rsvg_handle_rust_set_dpi_x,
rsvg_handle_rust_set_dpi_y,
rsvg_handle_rust_set_flags,
+ rsvg_handle_rust_set_size_closure,
rsvg_handle_rust_set_testing,
rsvg_handle_rust_write,
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]