[librsvg] Move the size_callback to CHandle



commit 5474a5ecbc08b6b4d189e1d56eac6ec86129f4e4
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Apr 5 17:48:36 2019 -0600

    Move the size_callback to CHandle

 rsvg_internals/src/c_api.rs        | 92 +++++++++++++++++++++++++++++++++-----
 rsvg_internals/src/handle.rs       | 86 ++++++-----------------------------
 rsvg_internals/src/pixbuf_utils.rs |  6 +--
 3 files changed, 99 insertions(+), 85 deletions(-)
---
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index 22119e4f..9d3e3cb3 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -154,6 +154,47 @@ pub struct RsvgHandle {
     _abi_padding: [glib_sys::gpointer; 16],
 }
 
+pub struct SizeCallback {
+    size_func: RsvgSizeFunc,
+    user_data: glib_sys::gpointer,
+    destroy_notify: glib_sys::GDestroyNotify,
+}
+
+impl SizeCallback {
+    pub 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 Default for SizeCallback {
+    fn default() -> SizeCallback {
+        SizeCallback {
+            size_func: None,
+            user_data: ptr::null_mut(),
+            destroy_notify: None,
+        }
+    }
+}
+
+impl Drop for SizeCallback {
+    fn drop(&mut self) {
+        unsafe {
+            if let Some(ref f) = self.destroy_notify {
+                f(self.user_data);
+            };
+        }
+    }
+}
+
 /// Contains all the interior mutability for a RsvgHandle to be called
 /// from the C API.
 pub struct CHandle {
@@ -161,6 +202,7 @@ pub struct CHandle {
     load_flags: Cell<LoadFlags>,
     base_url: RefCell<Option<Url>>,
     base_url_cstring: RefCell<Option<CString>>, // needed because the C api returns *const char
+    size_callback: RefCell<SizeCallback>,
     handle: Handle,
 }
 
@@ -291,6 +333,7 @@ impl ObjectSubclass for CHandle {
             load_flags: Cell::new(LoadFlags::default()),
             base_url: RefCell::new(None),
             base_url_cstring: RefCell::new(None),
+            size_callback: RefCell::new(SizeCallback::default()),
             handle: Handle::new(),
         }
     }
@@ -337,6 +380,8 @@ impl ObjectImpl for CHandle {
     fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> {
         let prop = &PROPERTIES[id];
 
+        let size_callback = self.size_callback.borrow();
+
         match *prop {
             subclass::Property("flags", ..) => {
                 let flags = HandleFlags::from(self.load_flags.get());
@@ -355,23 +400,23 @@ impl ObjectImpl for CHandle {
 
             subclass::Property("width", ..) => Ok(self
                 .handle
-                .get_dimensions_no_error(self.dpi.get())
+                .get_dimensions_no_error(self.dpi.get(), &*size_callback)
                 .width
                 .to_value()),
             subclass::Property("height", ..) => Ok(self
                 .handle
-                .get_dimensions_no_error(self.dpi.get())
+                .get_dimensions_no_error(self.dpi.get(), &*size_callback)
                 .height
                 .to_value()),
 
             subclass::Property("em", ..) => Ok(self
                 .handle
-                .get_dimensions_no_error(self.dpi.get())
+                .get_dimensions_no_error(self.dpi.get(), &*size_callback)
                 .em
                 .to_value()),
             subclass::Property("ex", ..) => Ok(self
                 .handle
-                .get_dimensions_no_error(self.dpi.get())
+                .get_dimensions_no_error(self.dpi.get(), &*size_callback)
                 .ex
                 .to_value()),
 
@@ -428,6 +473,20 @@ impl CHandle {
     fn load_options(&self) -> LoadOptions {
         LoadOptions::new(self.load_flags.get(), self.base_url.borrow().clone())
     }
+
+    pub fn set_size_callback(
+        &self,
+        size_func: RsvgSizeFunc,
+        user_data: glib_sys::gpointer,
+        destroy_notify: glib_sys::GDestroyNotify,
+    ) {
+        *self.size_callback.borrow_mut() = SizeCallback {
+            size_func,
+            user_data,
+            destroy_notify,
+        };
+    }
+
 }
 
 pub fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a CHandle {
@@ -616,7 +675,6 @@ pub unsafe extern "C" fn rsvg_rust_handle_set_size_callback(
     let rhandle = get_rust_handle(raw_handle);
 
     rhandle
-        .handle
         .set_size_callback(size_func, user_data, destroy_notify);
 }
 
@@ -720,9 +778,11 @@ pub unsafe extern "C" fn rsvg_rust_handle_render_cairo_sub(
     let cr = from_glib_none(cr);
     let id: Option<String> = from_glib_none(id);
 
+    let size_callback = rhandle.size_callback.borrow();
+
     match rhandle
         .handle
-        .render_cairo_sub(&cr, id.as_ref().map(String::as_str), rhandle.dpi.get())
+        .render_cairo_sub(&cr, id.as_ref().map(String::as_str), rhandle.dpi.get(), &*size_callback)
     {
         Ok(()) => true.to_glib(),
 
@@ -741,9 +801,11 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_pixbuf_sub(
     let rhandle = get_rust_handle(handle);
     let id: Option<String> = from_glib_none(id);
 
+    let size_callback = rhandle.size_callback.borrow();
+
     match rhandle
         .handle
-        .get_pixbuf_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
+        .get_pixbuf_sub(id.as_ref().map(String::as_str), rhandle.dpi.get(), &*size_callback)
     {
         Ok(pixbuf) => pixbuf.to_glib_full(),
         Err(_) => ptr::null_mut(),
@@ -757,7 +819,9 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_dimensions(
 ) {
     let rhandle = get_rust_handle(handle);
 
-    *dimension_data = rhandle.handle.get_dimensions_no_error(rhandle.dpi.get());
+    let size_callback = rhandle.size_callback.borrow();
+
+    *dimension_data = rhandle.handle.get_dimensions_no_error(rhandle.dpi.get(), &*size_callback);
 }
 
 #[no_mangle]
@@ -770,9 +834,15 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_dimensions_sub(
 
     let id: Option<String> = from_glib_none(id);
 
+    let size_callback = rhandle.size_callback.borrow();
+
     match rhandle
         .handle
-        .get_dimensions_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
+        .get_dimensions_sub(
+            id.as_ref().map(String::as_str),
+            rhandle.dpi.get(),
+            &*size_callback,
+        )
     {
         Ok(dimensions) => {
             *dimension_data = dimensions;
@@ -803,9 +873,11 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_position_sub(
 
     let id: Option<String> = from_glib_none(id);
 
+    let size_callback = rhandle.size_callback.borrow();
+
     match rhandle
         .handle
-        .get_position_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
+        .get_position_sub(id.as_ref().map(String::as_str), rhandle.dpi.get(), &*size_callback)
     {
         Ok(position) => {
             *position_data = position;
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index c1adc6ca..01285f33 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -1,17 +1,15 @@
 use std::cell::{Cell, RefCell};
-use std::ptr;
 use std::rc::Rc;
 
 use cairo::{self, ImageSurface, Status};
 use gdk_pixbuf::Pixbuf;
 use gio;
 use glib::{self, Bytes, Cast};
-use glib_sys;
 use libc;
 use locale_config::{LanguageRange, Locale};
 
 use crate::allowed_url::{AllowedUrl, Href};
-use crate::c_api::{RsvgDimensionData, RsvgPositionData, RsvgSizeFunc};
+use crate::c_api::{RsvgDimensionData, RsvgPositionData, SizeCallback};
 use crate::dpi::Dpi;
 use crate::drawing_ctx::{DrawingCtx, RsvgRectangle};
 use crate::error::{DefsLookupErrorKind, LoadingError, RenderingError};
@@ -73,52 +71,10 @@ pub enum LoadState {
     ClosedError,
 }
 
-struct SizeCallback {
-    size_func: RsvgSizeFunc,
-    user_data: glib_sys::gpointer,
-    destroy_notify: glib_sys::GDestroyNotify,
-}
-
-impl SizeCallback {
-    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 Default for SizeCallback {
-    fn default() -> SizeCallback {
-        SizeCallback {
-            size_func: None,
-            user_data: ptr::null_mut(),
-            destroy_notify: None,
-        }
-    }
-}
-
-impl Drop for SizeCallback {
-    fn drop(&mut self) {
-        unsafe {
-            if let Some(ref f) = self.destroy_notify {
-                f(self.user_data);
-            };
-        }
-    }
-}
-
 pub struct Handle {
     svg: RefCell<Option<Rc<Svg>>>,
     load_state: Cell<LoadState>,
     buffer: RefCell<Vec<u8>>, // used by the legacy write() api
-    size_callback: RefCell<SizeCallback>,
     in_loop: Cell<bool>,
     is_testing: Cell<bool>,
 }
@@ -129,25 +85,11 @@ impl Handle {
             svg: RefCell::new(None),
             load_state: Cell::new(LoadState::Start),
             buffer: RefCell::new(Vec::new()),
-            size_callback: RefCell::new(SizeCallback::default()),
             in_loop: Cell::new(false),
             is_testing: Cell::new(false),
         }
     }
 
-    pub fn set_size_callback(
-        &self,
-        size_func: RsvgSizeFunc,
-        user_data: glib_sys::gpointer,
-        destroy_notify: glib_sys::GDestroyNotify,
-    ) {
-        *self.size_callback.borrow_mut() = SizeCallback {
-            size_func,
-            user_data,
-            destroy_notify,
-        };
-    }
-
     fn get_svg(&self) -> Rc<Svg> {
         // This assumes that the Svg is already loaded, or unwrap() will panic
         self.svg.borrow().as_ref().unwrap().clone()
@@ -250,7 +192,7 @@ impl Handle {
         }
     }
 
-    pub fn get_dimensions(&self, dpi: Dpi) -> Result<RsvgDimensionData, RenderingError> {
+    pub fn get_dimensions(&self, dpi: Dpi, size_callback: &SizeCallback) -> Result<RsvgDimensionData, 
RenderingError> {
         self.check_is_loaded()?;
 
         // This function is probably called from the cairo_render functions,
@@ -268,15 +210,15 @@ impl Handle {
 
         self.in_loop.set(true);
 
-        let res = self.get_dimensions_sub(None, dpi);
+        let res = self.get_dimensions_sub(None, dpi, size_callback);
 
         self.in_loop.set(false);
 
         res
     }
 
-    pub fn get_dimensions_no_error(&self, dpi: Dpi) -> RsvgDimensionData {
-        match self.get_dimensions(dpi) {
+    pub fn get_dimensions_no_error(&self, dpi: Dpi, size_callback: &SizeCallback) -> RsvgDimensionData {
+        match self.get_dimensions(dpi, size_callback) {
             Ok(dimensions) => dimensions,
 
             Err(_) => {
@@ -296,15 +238,13 @@ impl Handle {
         &self,
         id: Option<&str>,
         dpi: Dpi,
+        size_callback: &SizeCallback,
     ) -> Result<RsvgDimensionData, RenderingError> {
         self.check_is_loaded()?;
 
         let (ink_r, _) = self.get_geometry_sub(id, dpi)?;
 
-        let (w, h) = self
-            .size_callback
-            .borrow()
-            .call(ink_r.width as libc::c_int, ink_r.height as libc::c_int);
+        let (w, h) = size_callback.call(ink_r.width as libc::c_int, ink_r.height as libc::c_int);
 
         Ok(RsvgDimensionData {
             width: w,
@@ -318,6 +258,7 @@ impl Handle {
         &self,
         id: Option<&str>,
         dpi: Dpi,
+        size_callback: &SizeCallback,
     ) -> Result<RsvgPositionData, RenderingError> {
         self.check_is_loaded()?;
 
@@ -330,7 +271,7 @@ impl Handle {
         let width = ink_r.width as libc::c_int;
         let height = ink_r.height as libc::c_int;
 
-        self.size_callback.borrow().call(width, height);
+        size_callback.call(width, height);
 
         Ok(RsvgPositionData {
             x: ink_r.x as libc::c_int,
@@ -477,11 +418,12 @@ impl Handle {
         cr: &cairo::Context,
         id: Option<&str>,
         dpi: Dpi,
+        size_callback: &SizeCallback,
     ) -> Result<(), RenderingError> {
         check_cairo_context(cr)?;
         self.check_is_loaded()?;
 
-        let dimensions = self.get_dimensions(dpi)?;
+        let dimensions = self.get_dimensions(dpi, size_callback)?;
         if dimensions.width == 0 || dimensions.height == 0 {
             // nothing to render
             return Ok(());
@@ -530,10 +472,10 @@ impl Handle {
         res
     }
 
-    pub fn get_pixbuf_sub(&self, id: Option<&str>, dpi: Dpi) -> Result<Pixbuf, RenderingError> {
+    pub fn get_pixbuf_sub(&self, id: Option<&str>, dpi: Dpi, size_callback: &SizeCallback) -> Result<Pixbuf, 
RenderingError> {
         self.check_is_loaded()?;
 
-        let dimensions = self.get_dimensions(dpi)?;
+        let dimensions = self.get_dimensions(dpi, size_callback)?;
 
         if dimensions.width == 0 || dimensions.height == 0 {
             return empty_pixbuf();
@@ -544,7 +486,7 @@ impl Handle {
 
         {
             let cr = cairo::Context::new(&surface);
-            self.render_cairo_sub(&cr, id, dpi)?;
+            self.render_cairo_sub(&cr, id, dpi, size_callback)?;
         }
 
         let surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
diff --git a/rsvg_internals/src/pixbuf_utils.rs b/rsvg_internals/src/pixbuf_utils.rs
index e4ab045b..3b16c203 100644
--- a/rsvg_internals/src/pixbuf_utils.rs
+++ b/rsvg_internals/src/pixbuf_utils.rs
@@ -12,7 +12,7 @@ use glib_sys;
 use libc;
 use url::Url;
 
-use crate::c_api::RsvgDimensionData;
+use crate::c_api::{RsvgDimensionData, SizeCallback};
 use crate::dpi::Dpi;
 use crate::error::{set_gerror, LoadingError, RenderingError};
 use crate::handle::{Handle, LoadFlags, LoadOptions};
@@ -178,7 +178,7 @@ fn render_to_pixbuf_at_size(
             f64::from(width) / f64::from(dimensions.width),
             f64::from(height) / f64::from(dimensions.height),
         );
-        handle.render_cairo_sub(&cr, None, dpi)?;
+        handle.render_cairo_sub(&cr, None, dpi, &SizeCallback::default())?;
     }
 
     let shared_surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
@@ -243,7 +243,7 @@ fn pixbuf_from_file_with_size_mode(
         }
 
         handle
-            .get_dimensions(dpi)
+            .get_dimensions(dpi, &SizeCallback::default())
             .and_then(|dimensions| {
                 let (width, height) = get_final_size(&dimensions, size_mode);
 


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