[librsvg/rustification] RsvgDefs: Keep track only of nodes that have an id, or are externals



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]