[librsvg] Port all handling of the size_func to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Port all handling of the size_func to Rust
- Date: Tue, 8 Jan 2019 23:05:52 +0000 (UTC)
commit 06c6c7395d40e0f8e333d9c0ef0838d9d0ac1d82
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Jan 8 17:04:05 2019 -0600
Port all handling of the size_func to Rust
librsvg/rsvg-handle.c | 55 +++-----------------
rsvg_internals/src/handle.rs | 121 +++++++++++++++++++++++++------------------
rsvg_internals/src/lib.rs | 2 +-
3 files changed, 79 insertions(+), 99 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 0b09cb44..adb85776 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -179,51 +179,10 @@ extern gboolean rsvg_handle_rust_get_dimensions_sub (RsvgHandle *handle,
extern gboolean rsvg_handle_rust_get_position_sub (RsvgHandle *handle,
RsvgPositionData *dimension_data,
const char *id);
-
-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_set_size_callback (RsvgHandleRust *raw_handle,
+ RsvgSizeFunc size_func,
+ gpointer user_data,
+ GDestroyNotify destroy_notify);
struct RsvgHandlePrivate {
RsvgHandleRust *rust_handle;
@@ -1233,8 +1192,10 @@ rsvg_handle_set_size_callback (RsvgHandle * handle,
{
g_return_if_fail (RSVG_IS_HANDLE (handle));
- rsvg_handle_rust_set_size_closure (handle->priv->rust_handle,
- rsvg_size_closure_new (size_func, user_data, user_data_destroy));
+ rsvg_handle_rust_set_size_callback (handle->priv->rust_handle,
+ size_func,
+ user_data,
+ user_data_destroy);
}
/**
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 17a79ce5..c835cf8b 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -41,23 +41,6 @@ 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 {
@@ -107,6 +90,54 @@ pub enum LoadState {
ClosedError,
}
+// Keep in sync with rsvg.h:RsvgSizeFunc
+type RsvgSizeFunc = Option<
+ unsafe extern "C" fn(
+ inout_width: *mut libc::c_int,
+ inout_height: *mut libc::c_int,
+ user_data: glib_sys::gpointer,
+ ),
+>;
+
+struct SizeCallback {
+ size_func: RsvgSizeFunc,
+ user_data: glib_sys::gpointer,
+ destroy_notify: glib_sys::GDestroyNotify,
+}
+
+impl SizeCallback {
+ fn new() -> SizeCallback {
+ SizeCallback {
+ size_func: None,
+ user_data: ptr::null_mut(),
+ destroy_notify: None,
+ }
+ }
+
+ fn call(&self, width: libc::c_int, height: libc::c_int) -> (libc::c_int, libc::c_int) {
+ unsafe {
+ let mut w = width;
+ let mut h = height;
+
+ if let Some(ref f) = self.size_func {
+ f(&mut w, &mut h, self.user_data);
+ };
+
+ (w, h)
+ }
+ }
+}
+
+impl Drop for SizeCallback {
+ fn drop(&mut self) {
+ unsafe {
+ if let Some(ref f) = self.destroy_notify {
+ f(self.user_data);
+ };
+ }
+ }
+}
+
pub struct Handle {
dpi: Dpi,
base_url: RefCell<Option<Url>>,
@@ -115,7 +146,7 @@ pub struct Handle {
load_flags: Cell<LoadFlags>,
load_state: Cell<LoadState>,
load: RefCell<Option<LoadContext>>,
- size_closure: *mut RsvgSizeClosure,
+ size_callback: RefCell<SizeCallback>,
in_loop: Cell<bool>,
is_testing: Cell<bool>,
}
@@ -130,7 +161,7 @@ impl Handle {
load_flags: Cell::new(LoadFlags::default()),
load_state: Cell::new(LoadState::Start),
load: RefCell::new(None),
- size_closure: ptr::null_mut(),
+ size_callback: RefCell::new(SizeCallback::new()),
in_loop: Cell::new(false),
is_testing: Cell::new(false),
}
@@ -493,16 +524,6 @@ 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;
@@ -783,17 +804,19 @@ pub unsafe extern "C" fn rsvg_handle_rust_set_flags(raw_handle: *const Handle, f
}
#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_set_size_closure(
+pub unsafe extern "C" fn rsvg_handle_rust_set_size_callback(
raw_handle: *mut Handle,
- closure: *mut RsvgSizeClosure,
+ size_func: RsvgSizeFunc,
+ user_data: glib_sys::gpointer,
+ destroy_notify: glib_sys::GDestroyNotify,
) {
let rhandle = &mut *raw_handle;
- if !rhandle.size_closure.is_null() {
- rsvg_size_closure_free(rhandle.size_closure);
- }
-
- rhandle.size_closure = closure;
+ *rhandle.size_callback.borrow_mut() = SizeCallback {
+ size_func,
+ user_data,
+ destroy_notify,
+ };
}
#[no_mangle]
@@ -1048,18 +1071,15 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_dimensions_sub(
let res = rsvg_handle_rust_get_geometry_sub(handle, &mut ink_r, ptr::null_mut(), id);
if from_glib(res) {
- (*dimension_data).width = ink_r.width as libc::c_int;
- (*dimension_data).height = ink_r.height as libc::c_int;
+ let (w, h) = rhandle
+ .size_callback
+ .borrow()
+ .call(ink_r.width as libc::c_int, ink_r.height as libc::c_int);
+
+ (*dimension_data).width = w;
+ (*dimension_data).height = h;
(*dimension_data).em = ink_r.width;
(*dimension_data).ex = ink_r.height;
-
- if !rhandle.size_closure.is_null() {
- rsvg_size_closure_call(
- rhandle.size_closure,
- &mut (*dimension_data).width,
- &mut (*dimension_data).height,
- );
- }
} else {
(*dimension_data).width = 0;
(*dimension_data).height = 0;
@@ -1101,11 +1121,10 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_position_sub(
(*position).x = ink_r.x as libc::c_int;
(*position).y = ink_r.y as libc::c_int;
- let mut width = ink_r.width as libc::c_int;
- let mut height = ink_r.height as libc::c_int;
- if !rhandle.size_closure.is_null() {
- rsvg_size_closure_call(rhandle.size_closure, &mut width, &mut height);
- }
+ let width = ink_r.width as libc::c_int;
+ let height = ink_r.height as libc::c_int;
+
+ rhandle.size_callback.borrow().call(width, height);
} else {
(*position).x = 0;
(*position).y = 0;
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 30464822..66637c0a 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -59,7 +59,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_size_callback,
rsvg_handle_rust_set_testing,
rsvg_handle_rust_write,
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]