[librsvg] Move the size_callback to CHandle
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Move the size_callback to CHandle
- Date: Tue, 9 Apr 2019 16:45:25 +0000 (UTC)
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]