[librsvg] Unref the parent node after calling rsvg_node_get_parent()



commit f3c0ff0b523ef4f9eadf8a362b8e548058c3493b
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Feb 16 21:39:17 2017 -0600

    Unref the parent node after calling rsvg_node_get_parent()
    
    This function now returns a new strong reference to the parent, so we
    must unref() it when we are done with it.

 rsvg-base.c         |   20 +++++++++++++-------
 rsvg-cairo-render.c |    8 +++++---
 rsvg-defs.c         |    2 +-
 rsvg-gobject.c      |    2 +-
 rsvg-structure.c    |   41 +++++++++++++++++++++++++++++------------
 rsvg-styles.c       |   20 +++++++++++++++++---
 6 files changed, 66 insertions(+), 27 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index bac8424..9279e0d 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -430,7 +430,7 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
 
         node_set_atts (newnode, ctx, creator, atts);
 
-        rsvg_node_unref (newnode);
+        newnode = rsvg_node_unref (newnode);
     }
 }
 
@@ -835,7 +835,7 @@ rsvg_end_element (void *data, const xmlChar * xmlname)
             RsvgNode *parent;
 
             parent = rsvg_node_get_parent (ctx->priv->currentnode);
-            ctx->priv->currentnode = rsvg_object_unref (ctx->priv->currentnode);
+            ctx->priv->currentnode = rsvg_node_unref (ctx->priv->currentnode);
             ctx->priv->currentnode = parent;
             pop_element_name (ctx);
         }
@@ -1392,8 +1392,7 @@ rsvg_drawing_ctx_free (RsvgDrawingCtx * handle)
 
     rsvg_state_free_all (handle->state);
 
-       /* the drawsub stack's nodes are owned by the ->defs */
-       g_slist_free (handle->drawsub_stack);
+       g_slist_free_full (handle->drawsub_stack, (GDestroyNotify) rsvg_node_unref);
 
     g_warn_if_fail (handle->acquired_nodes == NULL);
     g_slist_free (handle->acquired_nodes);
@@ -1535,11 +1534,11 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
     if (id && *id) {
         sself = rsvg_defs_lookup (handle->priv->defs, id);
 
-        if (sself == handle->priv->treebase)
+        if (rsvg_node_is_same (sself, handle->priv->treebase))
             id = NULL;
-    }
-    else
+    } else {
         sself = handle->priv->treebase;
+    }
 
     if (!sself && id)
         return FALSE;
@@ -1574,6 +1573,9 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
             return FALSE;
         }
 
+        g_assert (sself != NULL);
+        sself = rsvg_node_ref (sself);
+
         while (sself != NULL) {
             draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, sself);
             sself = rsvg_node_get_parent (sself);
@@ -1664,6 +1666,10 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
     if (!draw)
         goto bail;
 
+    g_assert (node != NULL);
+
+    node = rsvg_node_ref (node);
+
     while (node != NULL) {
         draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, node);
         node = rsvg_node_get_parent (node);
diff --git a/rsvg-cairo-render.c b/rsvg-cairo-render.c
index 1c80930..c5d7363 100644
--- a/rsvg-cairo-render.c
+++ b/rsvg-cairo-render.c
@@ -226,9 +226,11 @@ rsvg_handle_render_cairo_sub (RsvgHandle * handle, cairo_t * cr, const char *id)
     if (!draw)
         return FALSE;
 
-    while (drawsub != NULL) {
-        draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, drawsub);
-        drawsub = rsvg_node_get_parent (drawsub);
+    if (drawsub) {
+        while (drawsub != NULL) {
+            draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, rsvg_node_ref (drawsub));
+            drawsub = rsvg_node_get_parent (drawsub);
+        }
     }
 
     cairo_save (cr);
diff --git a/rsvg-defs.c b/rsvg-defs.c
index 6279aba..2eaaf63 100644
--- a/rsvg-defs.c
+++ b/rsvg-defs.c
@@ -42,7 +42,7 @@ rsvg_defs_new (RsvgHandle *handle)
 {
     RsvgDefs *result = g_new (RsvgDefs, 1);
 
-    result->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, rsvg_node_unref);
+    result->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) rsvg_node_unref);
     result->externs =
         g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
     result->ctx = handle; /* no need to take a ref here */
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 25bda7c..c539854 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -108,7 +108,7 @@ free_nodes (RsvgHandle *self)
         RsvgNode *node;
 
         node = g_ptr_array_index (self->priv->all_nodes, i);
-        rsvg_node_unref (node);
+        node = rsvg_node_unref (node);
     }
 
     g_ptr_array_free (self->priv->all_nodes, TRUE);
diff --git a/rsvg-structure.c b/rsvg-structure.c
index bea8cd7..6dfadcf 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -60,7 +60,9 @@ rsvg_node_draw_from_stack (RsvgNode *node, RsvgDrawingCtx * ctx, int dominate)
 
     stacksave = ctx->drawsub_stack;
     if (stacksave) {
-        if (stacksave->data != node)
+        RsvgNode *stack_node = stacksave->data;
+
+        if (!rsvg_node_is_same (stack_node, node))
             return;
 
         ctx->drawsub_stack = stacksave->next;
@@ -150,6 +152,7 @@ rsvg_node_svg_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int domi
     RsvgState *state;
     cairo_matrix_t affine, affine_old, affine_new;
     double nx, ny, nw, nh;
+    RsvgNode *parent;
 
     nx = rsvg_length_normalize (&svg->x, ctx);
     ny = rsvg_length_normalize (&svg->y, ctx);
@@ -189,12 +192,16 @@ rsvg_node_svg_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int domi
 
     /* Bounding box addition must be AFTER the discrete layer push,
        which must be AFTER the transformation happens. */
-    if (!state->overflow && rsvg_node_get_parent (node)) {
+    parent = rsvg_node_get_parent (node);
+
+    if (!state->overflow && parent) {
         state->affine = affine_old;
         rsvg_add_clipping_rect (ctx, nx, ny, nw, nh);
         state->affine = affine_new;
     }
 
+    parent = rsvg_node_unref (parent);
+
     rsvg_node_foreach_child (node, draw_child, ctx);
 
     rsvg_pop_discrete_layer (ctx);
@@ -206,6 +213,7 @@ rsvg_node_svg_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgP
 {
     const char *value;
     RsvgNodeSvg *svg = impl;
+    RsvgNode *parent;
 
     if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
         svg->vbox = rsvg_css_parse_vbox (value);
@@ -220,7 +228,9 @@ rsvg_node_svg_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgP
      * x & y attributes have no effect on outermost svg
      * http://www.w3.org/TR/SVG/struct.html#SVGElement
      */
-    if (rsvg_node_get_parent (node)) {
+    parent = rsvg_node_get_parent (node);
+
+    if (parent) {
         if ((value = rsvg_property_bag_lookup (atts, "x")))
             svg->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
 
@@ -228,6 +238,8 @@ rsvg_node_svg_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgP
             svg->y = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
     }
 
+    parent = rsvg_node_unref (parent);
+
     /*
      * style element is not loaded yet here, so we need to store those attribues
      * to be applied later.
@@ -285,19 +297,24 @@ rsvg_new_svg (const char *element_name, RsvgNode *parent)
 }
 
 static gboolean
-rsvg_node_is_ancestor (RsvgNode * potential_ancestor, RsvgNode * potential_descendant)
+rsvg_node_is_ancestor (RsvgNode *potential_ancestor, RsvgNode *descendant)
 {
-    /* work our way up the family tree */
-    while (TRUE) {
-        if (potential_ancestor == potential_descendant)
+    descendant = rsvg_node_ref (descendant);
+
+    while (descendant != NULL) {
+        RsvgNode *parent;
+
+        if (rsvg_node_is_same (potential_ancestor, descendant)) {
+            descendant = rsvg_node_unref (descendant);
             return TRUE;
-        else if (rsvg_node_get_parent (potential_descendant) == NULL)
-            return FALSE;
-        else
-            potential_descendant = rsvg_node_get_parent (potential_descendant);
+        }
+
+        parent = rsvg_node_get_parent (descendant);
+
+        descendant = rsvg_node_unref (descendant);
+        descendant = parent;
     }
 
-    g_assert_not_reached ();
     return FALSE;
 }
 
diff --git a/rsvg-styles.c b/rsvg-styles.c
index e2ad559..ba6acc3 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -1758,11 +1758,25 @@ rsvg_state_reinherit_top (RsvgDrawingCtx * ctx, RsvgState * state, int dominate)
     }
 }
 
-void
-rsvg_state_reconstruct (RsvgState * state, RsvgNode * current)
+static void
+reconstruct_helper (RsvgState *state, RsvgNode *current)
 {
+    RsvgNode *currents_parent;
+
     if (current == NULL)
         return;
-    rsvg_state_reconstruct (state, rsvg_node_get_parent (current));
+
+    currents_parent = rsvg_node_get_parent (current);
+
+    reconstruct_helper (state, currents_parent);
+
+    currents_parent = rsvg_node_unref (currents_parent);
+
     rsvg_state_inherit (state, rsvg_node_get_state (current));
 }
+
+void
+rsvg_state_reconstruct (RsvgState * state, RsvgNode * current)
+{
+    reconstruct_helper (state, current);
+}


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