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.
parent c8b08f1d
......@@ -188,6 +188,15 @@ rsvg_start_style (RsvgHandle * ctx, RsvgPropertyBag *atts)
ctx->priv->handler = &handler->super;
}
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)
{
......@@ -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);
}
......
......@@ -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;
......@@ -135,25 +133,14 @@ rsvg_defs_register_node_by_id (RsvgDefs *defs, const char *id, RsvgNode *node)
g_hash_table_insert (defs->hash, g_strdup (id), 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);
}
......
......@@ -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,
......@@ -96,6 +97,23 @@ rsvg_handle_init (RsvgHandle * self)
self->priv->in_loop = FALSE;
}
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)
{
......@@ -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)
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment