[librsvg: 3/10] Defs: decouple from RsvgHandle
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/10] Defs: decouple from RsvgHandle
- Date: Thu, 22 Nov 2018 20:21:47 +0000 (UTC)
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]