[librsvg/rustification] rsvg-base: New function rsvg_acquire_node_of_type()



commit a761759b79f1704be245e12249861a7184738f20
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Oct 28 10:18:28 2016 -0500

    rsvg-base: New function rsvg_acquire_node_of_type()
    
    In many places where we call rsvg_acquire_node(), the next thing
    done is to check that the type of the acquired node is the one
    that particular code expects.  The node is released if it doesn't match.
    
    Encapsulate that pattern in a function so we can use
    it everywhere instead of checking by hand.
    
    Also, we allow rsvg_node_acquire() to take a NULL uri, for convenience.

 rsvg-base.c    |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 rsvg-private.h |    2 ++
 2 files changed, 52 insertions(+), 4 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 21d328c..28bb8c7 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -2053,7 +2053,7 @@ rsvg_push_discrete_layer (RsvgDrawingCtx * ctx)
 /*
  * rsvg_acquire_node:
  * @ctx: The drawing context in use
- * @url: The IRI to lookup
+ * @url: The IRI to lookup, or %NULL
  *
  * Use this function when looking up urls to other nodes. This
  * function does proper recursion checking and thereby avoids
@@ -2062,14 +2062,21 @@ rsvg_push_discrete_layer (RsvgDrawingCtx * ctx)
  * Nodes acquired by this function must be released using
  * rsvg_release_node() in reverse acquiring order.
  *
- * Returns: The node referenced by @url or %NULL if the @url
- *          does not reference a node.
+ * Note that if you acquire a node, you have to release it before trying to
+ * 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.
+ *
+ * Returns: The node referenced by @url; or %NULL if the @url
+ *          is %NULL or it does not reference a node.
  */
 RsvgNode *
 rsvg_acquire_node (RsvgDrawingCtx * ctx, const char *url)
 {
   RsvgNode *node;
 
+  if (url == NULL)
+      return NULL;
+
   node = rsvg_defs_lookup (ctx->defs, url);
   if (node == NULL)
     return NULL;
@@ -2082,12 +2089,51 @@ rsvg_acquire_node (RsvgDrawingCtx * ctx, const char *url)
   return node;
 }
 
+/**
+ * rsvg_acquire_node_of_type:
+ * @ctx: The drawing context in use
+ * @url: The IRI to lookup
+ * @type: Type which the node must have
+ *
+ * Use this function when looking up urls to other nodes, and when you expect
+ * the node to be of a particular type. This function does proper recursion
+ * checking and thereby avoids infinite loops.
+ *
+ * Malformed SVGs, for example, may reference a marker by its IRI, but
+ * the object referenced by the IRI is not a marker.
+ *
+ * Nodes acquired by this function must be released using
+ * rsvg_release_node() in reverse acquiring order.
+ *
+ * Note that if you acquire a node, you have to release it before trying to
+ * 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.
+ *
+ * Returns: The node referenced by @url or %NULL if the @url
+ *          does not reference a node.  Also returns %NULL if
+ *          the node referenced by @url is not of the specified @type.
+ */
+RsvgNode *
+rsvg_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type)
+{
+    RsvgNode *node;
+
+    node = rsvg_acquire_node (ctx, url);
+    if (node == NULL || RSVG_NODE_TYPE (node) != type) {
+        rsvg_release_node (ctx, node);
+        return NULL;
+    }
+
+    return node;
+}
+
 /*
  * rsvg_release_node:
  * @ctx: The drawing context the node was acquired from
  * @node: Node to release
  *
- * Releases a node previously acquired via rsvg_acquire_node().
+ * Releases a node previously acquired via rsvg_acquire_node() or
+ * rsvg_acquire_node_of_type().
  *
  * if @node is %NULL, this function does nothing.
  */
diff --git a/rsvg-private.h b/rsvg-private.h
index 169d4bf..2e3d2cb 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -361,6 +361,8 @@ void rsvg_push_discrete_layer   (RsvgDrawingCtx * ctx);
 G_GNUC_INTERNAL
 RsvgNode *rsvg_acquire_node     (RsvgDrawingCtx * ctx, const char *url);
 G_GNUC_INTERNAL
+RsvgNode *rsvg_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type);
+G_GNUC_INTERNAL
 void rsvg_release_node          (RsvgDrawingCtx * ctx, RsvgNode *node);
 G_GNUC_INTERNAL
 void rsvg_render_path           (RsvgDrawingCtx * ctx, const cairo_path_t *path);


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