[librsvg] CHandle: move the dpi value from Handle to here



commit 0b5ddbab092ef8cc6da81dc4eddc918b3e2fb093
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Apr 5 11:33:15 2019 -0600

    CHandle: move the dpi value from Handle to here

 rsvg_internals/src/c_api.rs        | 77 ++++++++++++++++++++++----------------
 rsvg_internals/src/handle.rs       | 47 +++++++++++------------
 rsvg_internals/src/pixbuf_utils.rs | 20 ++++++++--
 3 files changed, 82 insertions(+), 62 deletions(-)
---
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index a2f07853..c9e51f70 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -1,3 +1,4 @@
+use std::cell::Cell;
 use std::ffi::CStr;
 use std::ops;
 use std::path::PathBuf;
@@ -156,6 +157,7 @@ pub struct RsvgHandle {
 /// Contains all the interior mutability for a RsvgHandle to be called
 /// from the C API.
 pub struct CHandle {
+    dpi: Cell<Dpi>,
     handle: Handle,
 }
 
@@ -282,6 +284,7 @@ impl ObjectSubclass for CHandle {
 
     fn new() -> Self {
         CHandle {
+            dpi: Cell::new(Dpi::default()),
             handle: Handle::new(LoadFlags::default()),
         }
     }
@@ -300,13 +303,13 @@ impl ObjectImpl for CHandle {
             }
 
             subclass::Property("dpi-x", ..) => {
-                self.handle
-                    .set_dpi_x(value.get().expect("dpi-x value has incorrect type"));
+                let dpi_x: f64 = value.get().expect("dpi-x value has incorrect type");
+                self.dpi.set(Dpi::new(dpi_x, self.dpi.get().y()));
             }
 
             subclass::Property("dpi-y", ..) => {
-                self.handle
-                    .set_dpi_y(value.get().expect("dpi-y value has incorrect type"));
+                let dpi_y: f64 = value.get().expect("dpi-y value has incorrect type");
+                self.dpi.set(Dpi::new(self.dpi.get().x(), dpi_y));
             }
 
             subclass::Property("base-uri", ..) => {
@@ -334,8 +337,8 @@ impl ObjectImpl for CHandle {
                 Ok(flags.to_value())
             }
 
-            subclass::Property("dpi-x", ..) => Ok(self.handle.dpi.get().x().to_value()),
-            subclass::Property("dpi-y", ..) => Ok(self.handle.dpi.get().y().to_value()),
+            subclass::Property("dpi-x", ..) => Ok(self.dpi.get().x().to_value()),
+            subclass::Property("dpi-y", ..) => Ok(self.dpi.get().y().to_value()),
 
             subclass::Property("base-uri", ..) => Ok(self
                 .handle
@@ -345,15 +348,27 @@ impl ObjectImpl for CHandle {
                 .map(|url| url.as_str())
                 .to_value()),
 
-            subclass::Property("width", ..) => {
-                Ok(self.handle.get_dimensions_no_error().width.to_value())
-            }
-            subclass::Property("height", ..) => {
-                Ok(self.handle.get_dimensions_no_error().height.to_value())
-            }
+            subclass::Property("width", ..) => Ok(self
+                .handle
+                .get_dimensions_no_error(self.dpi.get())
+                .width
+                .to_value()),
+            subclass::Property("height", ..) => Ok(self
+                .handle
+                .get_dimensions_no_error(self.dpi.get())
+                .height
+                .to_value()),
 
-            subclass::Property("em", ..) => Ok(self.handle.get_dimensions_no_error().em.to_value()),
-            subclass::Property("ex", ..) => Ok(self.handle.get_dimensions_no_error().ex.to_value()),
+            subclass::Property("em", ..) => Ok(self
+                .handle
+                .get_dimensions_no_error(self.dpi.get())
+                .em
+                .to_value()),
+            subclass::Property("ex", ..) => Ok(self
+                .handle
+                .get_dimensions_no_error(self.dpi.get())
+                .ex
+                .to_value()),
 
             // the following three are deprecated
             subclass::Property("title", ..) => Ok((None as Option<String>).to_value()),
@@ -497,34 +512,28 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_base_url(
 pub unsafe extern "C" fn rsvg_rust_handle_set_dpi_x(raw_handle: *const RsvgHandle, dpi_x: f64) {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle
-        .handle
-        .dpi
-        .set(Dpi::new(dpi_x, rhandle.handle.dpi.get().y()));
+    rhandle.dpi.set(Dpi::new(dpi_x, rhandle.dpi.get().y()));
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_handle_get_dpi_x(raw_handle: *const RsvgHandle) -> f64 {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle.handle.dpi.get().x()
+    rhandle.dpi.get().x()
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_handle_set_dpi_y(raw_handle: *const RsvgHandle, dpi_y: f64) {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle
-        .handle
-        .dpi
-        .set(Dpi::new(rhandle.handle.dpi.get().x(), dpi_y));
+    rhandle.dpi.set(Dpi::new(rhandle.dpi.get().x(), dpi_y));
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_handle_get_dpi_y(raw_handle: *const RsvgHandle) -> f64 {
     let rhandle = get_rust_handle(raw_handle);
 
-    rhandle.handle.dpi.get().y()
+    rhandle.dpi.get().y()
 }
 
 #[no_mangle]
@@ -663,7 +672,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_render_cairo_sub(
 
     match rhandle
         .handle
-        .render_cairo_sub(&cr, id.as_ref().map(String::as_str))
+        .render_cairo_sub(&cr, id.as_ref().map(String::as_str), rhandle.dpi.get())
     {
         Ok(()) => true.to_glib(),
 
@@ -684,7 +693,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_pixbuf_sub(
 
     match rhandle
         .handle
-        .get_pixbuf_sub(id.as_ref().map(String::as_str))
+        .get_pixbuf_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
     {
         Ok(pixbuf) => pixbuf.to_glib_full(),
         Err(_) => ptr::null_mut(),
@@ -698,7 +707,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_dimensions(
 ) {
     let rhandle = get_rust_handle(handle);
 
-    *dimension_data = rhandle.handle.get_dimensions_no_error();
+    *dimension_data = rhandle.handle.get_dimensions_no_error(rhandle.dpi.get());
 }
 
 #[no_mangle]
@@ -713,7 +722,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_dimensions_sub(
 
     match rhandle
         .handle
-        .get_dimensions_sub(id.as_ref().map(String::as_str))
+        .get_dimensions_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
     {
         Ok(dimensions) => {
             *dimension_data = dimensions;
@@ -746,7 +755,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_position_sub(
 
     match rhandle
         .handle
-        .get_position_sub(id.as_ref().map(String::as_str))
+        .get_position_sub(id.as_ref().map(String::as_str), rhandle.dpi.get())
     {
         Ok(position) => {
             *position_data = position;
@@ -812,9 +821,11 @@ pub unsafe extern "C" fn rsvg_rust_handle_new_from_gfile_sync(
         .read(cancellable.as_ref())
         .map_err(|e| LoadingError::from(e))
         .and_then(|stream| {
-            rhandle
-                .handle
-                .construct_read_stream_sync(&stream.upcast(), Some(&file), cancellable.as_ref())
+            rhandle.handle.construct_read_stream_sync(
+                &stream.upcast(),
+                Some(&file),
+                cancellable.as_ref(),
+            )
         });
 
     match res {
@@ -959,7 +970,7 @@ pub unsafe extern "C" fn rsvg_rust_handle_get_geometry_for_element(
     match rhandle.handle.get_geometry_for_element(
         id.as_ref().map(String::as_str),
         &viewport.into(),
-        rhandle.handle.dpi.get(),
+        rhandle.dpi.get(),
     ) {
         Ok((ink_rect, logical_rect)) => {
             if !out_ink_rect.is_null() {
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 83edf4c5..e7acc658 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -112,7 +112,6 @@ impl Drop for SizeCallback {
 }
 
 pub struct Handle {
-    pub dpi: Cell<Dpi>,
     pub base_url: RefCell<Option<Url>>,
     base_url_cstring: RefCell<Option<CString>>, // needed because the C api returns *const char
     svg: RefCell<Option<Rc<Svg>>>,
@@ -127,7 +126,6 @@ pub struct Handle {
 impl Handle {
     pub fn new(load_flags: LoadFlags) -> Handle {
         Handle {
-            dpi: Cell::new(Dpi::default()),
             base_url: RefCell::new(None),
             base_url_cstring: RefCell::new(None),
             svg: RefCell::new(None),
@@ -311,7 +309,7 @@ impl Handle {
         }
     }
 
-    pub fn get_dimensions(&self) -> Result<RsvgDimensionData, RenderingError> {
+    pub fn get_dimensions(&self, dpi: Dpi) -> Result<RsvgDimensionData, RenderingError> {
         self.check_is_loaded()?;
 
         // This function is probably called from the cairo_render functions,
@@ -329,15 +327,15 @@ impl Handle {
 
         self.in_loop.set(true);
 
-        let res = self.get_dimensions_sub(None);
+        let res = self.get_dimensions_sub(None, dpi);
 
         self.in_loop.set(false);
 
         res
     }
 
-    pub fn get_dimensions_no_error(&self) -> RsvgDimensionData {
-        match self.get_dimensions() {
+    pub fn get_dimensions_no_error(&self, dpi: Dpi) -> RsvgDimensionData {
+        match self.get_dimensions(dpi) {
             Ok(dimensions) => dimensions,
 
             Err(_) => {
@@ -356,10 +354,11 @@ impl Handle {
     pub fn get_dimensions_sub(
         &self,
         id: Option<&str>,
+        dpi: Dpi,
     ) -> Result<RsvgDimensionData, RenderingError> {
         self.check_is_loaded()?;
 
-        let (ink_r, _) = self.get_geometry_sub(id)?;
+        let (ink_r, _) = self.get_geometry_sub(id, dpi)?;
 
         let (w, h) = self
             .size_callback
@@ -374,14 +373,18 @@ impl Handle {
         })
     }
 
-    pub fn get_position_sub(&self, id: Option<&str>) -> Result<RsvgPositionData, RenderingError> {
+    pub fn get_position_sub(
+        &self,
+        id: Option<&str>,
+        dpi: Dpi,
+    ) -> Result<RsvgPositionData, RenderingError> {
         self.check_is_loaded()?;
 
         if let None = id {
             return Ok(RsvgPositionData { x: 0, y: 0 });
         }
 
-        let (ink_r, _) = self.get_geometry_sub(id)?;
+        let (ink_r, _) = self.get_geometry_sub(id, dpi)?;
 
         let width = ink_r.width as libc::c_int;
         let height = ink_r.height as libc::c_int;
@@ -454,6 +457,7 @@ impl Handle {
     fn get_geometry_sub(
         &self,
         id: Option<&str>,
+        dpi: Dpi,
     ) -> Result<(RsvgRectangle, RsvgRectangle), RenderingError> {
         let node = self.get_node_or_root(id)?;
 
@@ -465,7 +469,7 @@ impl Handle {
             let values = cascaded.get();
 
             if let Some((root_width, root_height)) =
-                node.with_impl(|svg: &NodeSvg| svg.get_size(&values, self.dpi.get()))
+                node.with_impl(|svg: &NodeSvg| svg.get_size(&values, dpi))
             {
                 let ink_r = RsvgRectangle {
                     x: 0.0,
@@ -480,7 +484,7 @@ impl Handle {
             }
         }
 
-        self.get_node_geometry(&node, self.dpi.get())
+        self.get_node_geometry(&node, dpi)
     }
 
     fn get_node_or_root(&self, id: Option<&str>) -> Result<RsvgNode, RenderingError> {
@@ -539,11 +543,12 @@ impl Handle {
         &self,
         cr: &cairo::Context,
         id: Option<&str>,
+        dpi: Dpi,
     ) -> Result<(), RenderingError> {
         check_cairo_context(cr)?;
         self.check_is_loaded()?;
 
-        let dimensions = self.get_dimensions()?;
+        let dimensions = self.get_dimensions(dpi)?;
         if dimensions.width == 0 || dimensions.height == 0 {
             // nothing to render
             return Ok(());
@@ -556,7 +561,7 @@ impl Handle {
             height: f64::from(dimensions.height),
         };
 
-        self.render_element_to_viewport(cr, id, &viewport, self.dpi.get())
+        self.render_element_to_viewport(cr, id, &viewport, dpi)
     }
 
     pub fn render_element_to_viewport(
@@ -592,10 +597,10 @@ impl Handle {
         res
     }
 
-    pub fn get_pixbuf_sub(&self, id: Option<&str>) -> Result<Pixbuf, RenderingError> {
+    pub fn get_pixbuf_sub(&self, id: Option<&str>, dpi: Dpi) -> Result<Pixbuf, RenderingError> {
         self.check_is_loaded()?;
 
-        let dimensions = self.get_dimensions()?;
+        let dimensions = self.get_dimensions(dpi)?;
 
         if dimensions.width == 0 || dimensions.height == 0 {
             return empty_pixbuf();
@@ -606,7 +611,7 @@ impl Handle {
 
         {
             let cr = cairo::Context::new(&surface);
-            self.render_cairo_sub(&cr, id)?;
+            self.render_cairo_sub(&cr, id, dpi)?;
         }
 
         let surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
@@ -631,16 +636,6 @@ impl Handle {
         self.get_svg().get_intrinsic_dimensions()
     }
 
-    // from the public API
-    pub fn set_dpi_x(&self, dpi_x: f64) {
-        self.dpi.set(Dpi::new(dpi_x, self.dpi.get().y()));
-    }
-
-    // from the public API
-    pub fn set_dpi_y(&self, dpi_y: f64) {
-        self.dpi.set(Dpi::new(self.dpi.get().x(), dpi_y));
-    }
-
     pub fn set_testing(&self, testing: bool) {
         self.is_testing.set(testing);
     }
diff --git a/rsvg_internals/src/pixbuf_utils.rs b/rsvg_internals/src/pixbuf_utils.rs
index e13e1214..63b8d60d 100644
--- a/rsvg_internals/src/pixbuf_utils.rs
+++ b/rsvg_internals/src/pixbuf_utils.rs
@@ -12,6 +12,7 @@ use glib_sys;
 use libc;
 
 use crate::c_api::RsvgDimensionData;
+use crate::dpi::Dpi;
 use crate::error::{set_gerror, LoadingError, RenderingError};
 use crate::handle::{Handle, LoadFlags};
 use crate::rect::IRect;
@@ -162,6 +163,7 @@ fn render_to_pixbuf_at_size(
     dimensions: &RsvgDimensionData,
     width: i32,
     height: i32,
+    dpi: Dpi,
 ) -> Result<Pixbuf, RenderingError> {
     if width == 0 || height == 0 {
         return empty_pixbuf();
@@ -175,7 +177,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)?;
+        handle.render_cairo_sub(&cr, None, dpi)?;
     }
 
     let shared_surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
@@ -183,11 +185,23 @@ fn render_to_pixbuf_at_size(
     pixbuf_from_surface(&shared_surface)
 }
 
+fn get_default_dpi() -> Dpi {
+    // This is ugly, but it preserves the C API semantics of
+    //
+    //   rsvg_set_default_dpi(...);
+    //   pixbuf = rsvg_pixbuf_from_file(...);
+    //
+    // Passing negative numbers here means that the global default DPI will be used.
+    Dpi::new(-1.0, -1.0)
+}
+
 fn pixbuf_from_file_with_size_mode(
     filename: *const libc::c_char,
     size_mode: &SizeMode,
     error: *mut *mut glib_sys::GError,
 ) -> *mut gdk_pixbuf_sys::GdkPixbuf {
+    let dpi = get_default_dpi();
+
     unsafe {
         let path = PathBuf::from_glib_none(filename);
         let file = gio::File::new_for_path(path);
@@ -206,11 +220,11 @@ fn pixbuf_from_file_with_size_mode(
         }
 
         handle
-            .get_dimensions()
+            .get_dimensions(dpi)
             .and_then(|dimensions| {
                 let (width, height) = get_final_size(&dimensions, size_mode);
 
-                render_to_pixbuf_at_size(&handle, &dimensions, width, height)
+                render_to_pixbuf_at_size(&handle, &dimensions, width, height, dpi)
             })
             .and_then(|pixbuf| Ok(pixbuf.to_glib_full()))
             .unwrap_or_else(|e| {


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