[librsvg/rustification] RsvgDefs: Keep track only of nodes that have an id, or are externals
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] RsvgDefs: Keep track only of nodes that have an id, or are externals
- Date: Wed, 9 Nov 2016 23:43:53 +0000 (UTC)
commit f22b3cb210427283bf29866f87193f150fc5aebc
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Nov 9 14:12:11 2016 -0600
RsvgDefs: Keep track only of nodes that have an id, or are externals
RsvgDefs also stored all the RsvgNode objects inside an RsvgHandle so
that they could be freed at destruction time.
Now RsvgDefs only has references to nodes that have an XML id="foo"
attribute, and references to external objects.
The list of all nodes is kept in RsvgHandlePrivate now.
rsvg-base.c | 15 ++++++++++++---
rsvg-defs.c | 17 ++---------------
rsvg-gobject.c | 23 +++++++++++++++++++++++
rsvg-private.h | 4 ++--
4 files changed, 39 insertions(+), 20 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index bc4d22f..a91b12a 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -189,6 +189,15 @@ rsvg_start_style (RsvgHandle * ctx, RsvgPropertyBag *atts)
}
static void
+add_node_to_handle (RsvgHandle *ctx, RsvgNode *node)
+{
+ g_assert (ctx != NULL);
+ g_assert (node != NULL);
+
+ g_ptr_array_add (ctx->priv->all_nodes, node);
+}
+
+static void
register_node_in_defs (RsvgHandle *ctx, RsvgNode *node, RsvgPropertyBag *atts)
{
const char *id;
@@ -197,8 +206,6 @@ register_node_in_defs (RsvgHandle *ctx, RsvgNode *node, RsvgPropertyBag *atts)
if (id) {
rsvg_defs_register_node_by_id (ctx->priv->defs, id, node);
}
-
- rsvg_defs_register_memory (ctx->priv->defs, node);
}
@@ -327,6 +334,7 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
newnode->name = (char *) name; /* libxml will keep this while parsing */
newnode->parent = ctx->priv->currentnode;
+ add_node_to_handle (ctx, newnode);
register_node_in_defs (ctx, newnode, atts);
rsvg_node_set_atts (newnode, ctx, atts);
@@ -823,7 +831,8 @@ rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
self = rsvg_new_node_chars ((char *) ch, len);
- rsvg_defs_register_memory (ctx->priv->defs, (RsvgNode *) self);
+ add_node_to_handle (ctx, (RsvgNode *) self);
+
if (ctx->priv->currentnode)
rsvg_node_group_pack (ctx->priv->currentnode, (RsvgNode *) self);
}
diff --git a/rsvg-defs.c b/rsvg-defs.c
index f127002..4a842fe 100644
--- a/rsvg-defs.c
+++ b/rsvg-defs.c
@@ -33,7 +33,6 @@
struct _RsvgDefs {
GHashTable *hash;
- GPtrArray *unnamed;
GHashTable *externs;
RsvgHandle *ctx;
};
@@ -46,7 +45,6 @@ rsvg_defs_new (RsvgHandle *handle)
result->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
result->externs =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
- result->unnamed = g_ptr_array_new ();
result->ctx = handle; /* no need to take a ref here */
return result;
@@ -136,24 +134,13 @@ rsvg_defs_register_node_by_id (RsvgDefs *defs, const char *id, RsvgNode *node)
}
void
-rsvg_defs_register_memory (RsvgDefs * defs, RsvgNode * val)
-{
- g_ptr_array_add (defs->unnamed, val);
-}
-
-void
rsvg_defs_free (RsvgDefs * defs)
{
- guint i;
-
g_hash_table_destroy (defs->hash);
-
- for (i = 0; i < defs->unnamed->len; i++)
- ((RsvgNode *) g_ptr_array_index (defs->unnamed, i))->
- free (g_ptr_array_index (defs->unnamed, i));
- g_ptr_array_free (defs->unnamed, TRUE);
+ defs->hash = NULL;
g_hash_table_destroy (defs->externs);
+ defs->externs = NULL;
g_free (defs);
}
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 4e61a44..c338724 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -69,6 +69,7 @@ rsvg_handle_init (RsvgHandle * self)
self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
self->priv->load_policy = RSVG_LOAD_POLICY_DEFAULT;
+ self->priv->all_nodes = g_ptr_array_new ();
self->priv->defs = rsvg_defs_new (self);
self->priv->handler_nest = 0;
self->priv->entities = g_hash_table_new_full (g_str_hash,
@@ -97,6 +98,23 @@ rsvg_handle_init (RsvgHandle * self)
}
static void
+free_nodes (RsvgHandle *self)
+{
+ int i;
+
+ for (i = 0; i < self->priv->all_nodes->len; i++) {
+ RsvgNode *node;
+
+ node = g_ptr_array_index (self->priv->all_nodes, i);
+ g_assert (node->free != NULL);
+ node->free (node);
+ }
+
+ g_ptr_array_free (self->priv->all_nodes, TRUE);
+ self->priv->all_nodes = NULL;
+}
+
+static void
rsvg_handle_dispose (GObject *instance)
{
RsvgHandle *self = (RsvgHandle *) instance;
@@ -107,7 +125,12 @@ rsvg_handle_dispose (GObject *instance)
self->priv->is_disposed = TRUE;
g_hash_table_destroy (self->priv->entities);
+
+ free_nodes (self);
+
rsvg_defs_free (self->priv->defs);
+ self->priv->defs = NULL;
+
g_hash_table_destroy (self->priv->css_props);
if (self->priv->user_data_destroy)
diff --git a/rsvg-private.h b/rsvg-private.h
index 95e2f2f..1c9f2f5 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -141,9 +141,9 @@ struct RsvgHandlePrivate {
gpointer user_data;
GDestroyNotify user_data_destroy;
- /* stack; there is a state for each element */
+ GPtrArray *all_nodes;
- RsvgDefs *defs;
+ RsvgDefs *defs; /* lookup table for nodes that have an id="foo" attribute */
RsvgNode *currentnode;
/* this is the root level of the displayable tree, essentially what the
file is converted into at the end */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]