[librsvg: 3/10] Defs: decouple from RsvgHandle



commit 941ffd91066342a3dde3e31c85fd318dbcbd0aa0
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Nov 22 09:23:05 2018 -0600

    Defs: decouple from RsvgHandle
    
    Defs used to keep a pointer to its parent RsvgHandle from
    initialization.  Instead, now it explicitly takes a handle into
    .lookup().
    
    This is so that we can create a Defs independently of an RsvgHandle
    and manipulate it more freely.  Or maybe we can group it with all the
    things that get produced at loading time, independently of a handle.
    
    Unfortunately this means that the single call to defs.lookup() from
    DrawingCtx now requires a handle, which DrawingCtx didn't have
    before.  For now, we'll make DrawingCtx be constructed with a handle.
    This more or less makes sense, since a DrawingCtx is really tied to a
    particular handle.

 librsvg/rsvg-handle.c             | 13 ++++++------
 librsvg/rsvg-private.h            |  7 ++++---
 rsvg_internals/src/defs.rs        | 42 ++++++++++++++++++++-------------------
 rsvg_internals/src/drawing_ctx.rs |  9 ++++++++-
 4 files changed, 41 insertions(+), 30 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 15dd8b29..b711b0f9 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -156,7 +156,7 @@ rsvg_handle_init (RsvgHandle * self)
 
     self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
     self->priv->hstate = RSVG_HANDLE_STATE_START;
-    self->priv->defs = rsvg_defs_new (self);
+    self->priv->defs = rsvg_defs_new ();
     self->priv->dpi_x = rsvg_internal_dpi_x;
     self->priv->dpi_y = rsvg_internal_dpi_y;
 
@@ -1029,7 +1029,8 @@ rsvg_handle_create_drawing_ctx(RsvgHandle *handle,
                                cairo_t *cr,
                                RsvgDimensionData *dimensions)
 {
-    return rsvg_drawing_ctx_new (cr,
+    return rsvg_drawing_ctx_new (handle,
+                                 cr,
                                  dimensions->width, dimensions->height,
                                  dimensions->em, dimensions->ex,
                                  handle->priv->dpi_x, handle->priv->dpi_y,
@@ -1077,7 +1078,7 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
     }
 
     if (id && *id)
-        drawsub = rsvg_defs_lookup (handle->priv->defs, id);
+        drawsub = rsvg_defs_lookup (handle->priv->defs, handle, id);
 
     if (drawsub == NULL && id != NULL) {
         g_warning ("element id=\"%s\" does not exist", id);
@@ -1218,7 +1219,7 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
     root = rsvg_tree_get_root (handle->priv->tree);
 
     if (id && *id) {
-        node = rsvg_defs_lookup (handle->priv->defs, id);
+        node = rsvg_defs_lookup (handle->priv->defs, handle, id);
 
         if (node && rsvg_tree_is_root (handle->priv->tree, node))
             id = NULL;
@@ -1295,7 +1296,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
     if (NULL == id || '\0' == *id)
         return TRUE;
 
-    node = rsvg_defs_lookup (handle->priv->defs, id);
+    node = rsvg_defs_lookup (handle->priv->defs, handle, id);
     if (!node)
         return FALSE;
 
@@ -1337,7 +1338,7 @@ rsvg_handle_has_sub (RsvgHandle * handle,
     if (G_UNLIKELY (!id || !id[0]))
       return FALSE;
 
-    return rsvg_defs_lookup (handle->priv->defs, id) != NULL;
+    return rsvg_defs_lookup (handle->priv->defs, handle, id) != NULL;
 }
 
 /**
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index a1a5a7b7..b2803fe7 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -201,7 +201,8 @@ GdkPixbuf *rsvg_cairo_surface_to_pixbuf (cairo_surface_t *surface);
 
 /* Defined in rsvg_internals/src/drawing_ctx.rs */
 G_GNUC_INTERNAL
-RsvgDrawingCtx *rsvg_drawing_ctx_new (cairo_t *cr,
+RsvgDrawingCtx *rsvg_drawing_ctx_new (RsvgHandle *handle,
+                                      cairo_t *cr,
                                       guint width,
                                       guint height,
                                       double vb_width,
@@ -241,7 +242,7 @@ RsvgNode *rsvg_load_destroy (RsvgLoad *load) G_GNUC_WARN_UNUSED_RESULT;
 
 /* Defined in rsvg_internals/src/defs.rs */
 G_GNUC_INTERNAL
-RsvgDefs *rsvg_defs_new (RsvgHandle *handle);
+RsvgDefs *rsvg_defs_new (void);
 
 /* Defined in rsvg_internals/src/defs.rs */
 G_GNUC_INTERNAL
@@ -249,7 +250,7 @@ void rsvg_defs_free (RsvgDefs *defs);
 
 /* Defined in rsvg_internals/src/defs.rs */
 /* for some reason this one's public... */
-RsvgNode *rsvg_defs_lookup (const RsvgDefs * defs, const char *name);
+RsvgNode *rsvg_defs_lookup (const RsvgDefs * defs, RsvgHandle *handle, const char *name);
 
 G_GNUC_INTERNAL
 RsvgDefs *rsvg_handle_get_defs (RsvgHandle *handle);
diff --git a/rsvg_internals/src/defs.rs b/rsvg_internals/src/defs.rs
index 731e2880..b5a67cb9 100644
--- a/rsvg_internals/src/defs.rs
+++ b/rsvg_internals/src/defs.rs
@@ -11,15 +11,13 @@ use util::utf8_cstr;
 pub enum RsvgDefs {}
 
 pub struct Defs {
-    handle: *const RsvgHandle,
     nodes: HashMap<String, Rc<Node>>,
     externs: HashMap<String, *const RsvgHandle>,
 }
 
 impl Defs {
-    fn new(handle: *const RsvgHandle) -> Defs {
+    fn new() -> Defs {
         Defs {
-            handle,
             nodes: Default::default(),
             externs: Default::default(),
         }
@@ -34,17 +32,17 @@ impl Defs {
     /// This may return a node within the same RSVG handle, or a node in a secondary RSVG
     /// handle that is referenced by the current one.  If the element's id is not found,
     /// returns `None`.
-    pub fn lookup(&mut self, name: &str) -> Option<&Rc<Node>> {
+    pub fn lookup(&mut self, handle: *const RsvgHandle, name: &str) -> Option<&Rc<Node>> {
         if let Ok(reference) = Reference::parse(name) {
             match reference {
                 Reference::PlainUri(_) => None,
                 Reference::FragmentId(fragment) => self.nodes.get(fragment),
                 Reference::UriWithFragmentId(uri, fragment) => {
-                    let handle = self.get_extern_handle(uri);
-                    if handle.is_null() {
+                    let extern_handle = self.get_extern_handle(handle, uri);
+                    if extern_handle.is_null() {
                         None
                     } else {
-                        handle::get_defs(handle).nodes.get(fragment)
+                        handle::get_defs(extern_handle).nodes.get(fragment)
                     }
                 }
             }
@@ -53,20 +51,23 @@ impl Defs {
         }
     }
 
-    fn get_extern_handle(&mut self, possibly_relative_uri: &str) -> *const RsvgHandle {
-        handle::resolve_uri(self.handle, possibly_relative_uri).map_or(
-            ptr::null(),
-            |uri| match self.externs.entry(uri) {
+    fn get_extern_handle(
+        &mut self,
+        handle: *const RsvgHandle,
+        possibly_relative_uri: &str,
+    ) -> *const RsvgHandle {
+        handle::resolve_uri(handle, possibly_relative_uri).map_or(ptr::null(), |uri| {
+            match self.externs.entry(uri) {
                 Entry::Occupied(e) => *(e.get()),
                 Entry::Vacant(e) => {
-                    let handle = handle::load_extern(self.handle, e.key());
-                    if !handle.is_null() {
-                        e.insert(handle);
+                    let extern_handle = handle::load_extern(handle, e.key());
+                    if !extern_handle.is_null() {
+                        e.insert(extern_handle);
                     }
-                    handle
+                    extern_handle
                 }
-            },
-        )
+            }
+        })
     }
 }
 
@@ -104,8 +105,8 @@ impl<'a> Reference<'a> {
 }
 
 #[no_mangle]
-pub extern "C" fn rsvg_defs_new(handle: *const RsvgHandle) -> *mut RsvgDefs {
-    Box::into_raw(Box::new(Defs::new(handle))) as *mut RsvgDefs
+pub extern "C" fn rsvg_defs_new() -> *mut RsvgDefs {
+    Box::into_raw(Box::new(Defs::new())) as *mut RsvgDefs
 }
 
 #[no_mangle]
@@ -121,6 +122,7 @@ pub extern "C" fn rsvg_defs_free(defs: *mut RsvgDefs) {
 #[no_mangle]
 pub extern "C" fn rsvg_defs_lookup(
     defs: *mut RsvgDefs,
+    handle: *const RsvgHandle,
     name: *const libc::c_char,
 ) -> *const RsvgNode {
     assert!(!defs.is_null());
@@ -129,7 +131,7 @@ pub extern "C" fn rsvg_defs_lookup(
     let defs = unsafe { &mut *(defs as *mut Defs) };
     let name = unsafe { utf8_cstr(name) };
 
-    match defs.lookup(name) {
+    match defs.lookup(handle, name) {
         Some(n) => n as *const RsvgNode,
         None => ptr::null(),
     }
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index f34dfbf5..4aab36db 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -18,6 +18,7 @@ use defs::{Defs, RsvgDefs};
 use error::RenderingError;
 use filters;
 use float_eq_cairo::ApproxEqCairo;
+use handle::RsvgHandle;
 use length::Dasharray;
 use mask::NodeMask;
 use node::{CascadedValues, NodeType, RsvgNode};
@@ -99,6 +100,8 @@ impl Drop for ViewParams {
 pub enum RsvgDrawingCtx {}
 
 pub struct DrawingCtx<'a> {
+    handle: *const RsvgHandle,
+
     rect: cairo::Rectangle,
     dpi_x: f64,
     dpi_y: f64,
@@ -136,6 +139,7 @@ pub struct DrawingCtx<'a> {
 
 impl<'a> DrawingCtx<'a> {
     pub fn new(
+        handle: *const RsvgHandle,
         cr: cairo::Context,
         width: f64,
         height: f64,
@@ -171,6 +175,7 @@ impl<'a> DrawingCtx<'a> {
         view_box_stack.push(ViewBox::new(0.0, 0.0, vb_width, vb_height));
 
         DrawingCtx {
+            handle,
             rect,
             dpi_x,
             dpi_y,
@@ -288,7 +293,7 @@ impl<'a> DrawingCtx<'a> {
     // acquire it again.  If you acquire a node "#foo" and don't release it before
     // trying to acquire "foo" again, you will obtain a %NULL the second time.
     pub fn get_acquired_node(&mut self, url: &str) -> Option<AcquiredNode> {
-        if let Some(node) = self.defs.borrow_mut().lookup(url) {
+        if let Some(node) = self.defs.borrow_mut().lookup(self.handle, url) {
             if !self.acquired_nodes_contains(node) {
                 self.acquired_nodes.borrow_mut().push(node.clone());
                 let acq = AcquiredNode(self.acquired_nodes.clone(), node.clone());
@@ -1169,6 +1174,7 @@ impl NodeStack {
 
 #[no_mangle]
 pub extern "C" fn rsvg_drawing_ctx_new(
+    handle: *const RsvgHandle,
     cr: *mut cairo_sys::cairo_t,
     width: u32,
     height: u32,
@@ -1183,6 +1189,7 @@ pub extern "C" fn rsvg_drawing_ctx_new(
     let defs = unsafe { &mut *(defs as *mut Defs) };
 
     Box::into_raw(Box::new(DrawingCtx::new(
+        handle,
         unsafe { from_glib_none(cr) },
         f64::from(width),
         f64::from(height),


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