[librsvg] Implement more generic RsvgNode methods in Rust to replace the C functions



commit 0d0069d364ca8dc6f16f7710527f4f4eebf4ebbd
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Feb 9 16:56:14 2017 -0600

    Implement more generic RsvgNode methods in Rust to replace the C functions
    
    We use the new rsvg_node_get_type() throughout.

 rsvg-base.c         |   63 +++++---------------------------------------------
 rsvg-cairo-draw.c   |   12 +++++-----
 rsvg-filter.c       |    8 +++---
 rsvg-paint-server.c |    4 +-
 rsvg-private.h      |   18 +++++++++++++-
 rsvg-shapes.c       |    2 +-
 rsvg-structure.c    |    2 +-
 rsvg-text.c         |    4 +-
 rust/src/lib.rs     |    3 ++
 rust/src/node.rs    |   36 +++++++++++++++++++++++++++-
 10 files changed, 77 insertions(+), 75 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index a35ab46..7a2f108 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -375,18 +375,6 @@ get_node_creator_for_element_name (const char *name)
     return result;
 }
 
-void
-rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag *atts)
-{
-    node->vtable->set_atts (node, handle, atts);
-}
-
-void
-rsvg_node_draw (RsvgNode *node, RsvgDrawingCtx *draw, int dominate)
-{
-    node->vtable->draw (node, draw, dominate);
-}
-
 static void
 node_set_atts (RsvgNode * node, RsvgHandle * ctx, const NodeCreator *creator, RsvgPropertyBag * atts)
 {
@@ -400,7 +388,7 @@ node_set_atts (RsvgNode * node, RsvgHandle * ctx, const NodeCreator *creator, Rs
          * attributes until the end, when rsvg_end_element() calls
          * _rsvg_node_svg_apply_atts()
          */
-        if (rsvg_node_type (node) != RSVG_NODE_TYPE_SVG) {
+        if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_SVG) {
             id = rsvg_property_bag_lookup (atts, "id");
 
             if (creator->supports_class_attribute)
@@ -425,7 +413,7 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
     newnode = creator->create_fn (name);
 
     if (newnode) {
-        g_assert (rsvg_node_type (newnode) != RSVG_NODE_TYPE_INVALID);
+        g_assert (rsvg_node_get_type (newnode) != RSVG_NODE_TYPE_INVALID);
 
         push_element_name (ctx, name);
 
@@ -434,7 +422,7 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
 
         if (ctx->priv->currentnode) {
             rsvg_node_add_child (ctx->priv->currentnode, newnode);
-        } else if (rsvg_node_type (newnode) == RSVG_NODE_TYPE_SVG) {
+        } else if (rsvg_node_get_type (newnode) == RSVG_NODE_TYPE_SVG) {
             ctx->priv->treebase = newnode;
         }
 
@@ -444,43 +432,6 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
     }
 }
 
-RsvgNodeType
-rsvg_node_type (RsvgNode *node)
-{
-    return node->type;
-}
-
-RsvgState *
-rsvg_node_get_state (RsvgNode *node)
-{
-    return node->state;
-}
-
-RsvgNode *
-rsvg_node_get_parent (RsvgNode *node)
-{
-    return node->parent;
-}
-
-void
-rsvg_node_foreach_child (RsvgNode *node, RsvgNodeForeachChildFn fn, gpointer data)
-{
-    guint len;
-    guint i;
-
-    len = node->children->len;
-
-    for (i = 0; i < len; i++) {
-        RsvgNode *child;
-        gboolean next;
-
-        child = g_ptr_array_index (node->children, i);
-        next = fn (child, data);
-        if (!next)
-            break;
-    }
-}
-
 /* extra (title, desc, metadata) */
 
 static void
@@ -932,9 +883,9 @@ find_last_chars_node (RsvgNode *node, gpointer data)
 
     dest = data;
 
-    if (rsvg_node_type (node) == RSVG_NODE_TYPE_CHARS) {
+    if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_CHARS) {
         *dest = node;
-    } else if (rsvg_node_type (node) == RSVG_NODE_TYPE_TSPAN) {
+    } else if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_TSPAN) {
         *dest = NULL;
     }
 
@@ -950,7 +901,7 @@ rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
         return;
 
     if (ctx->priv->currentnode) {
-        RsvgNodeType type = rsvg_node_type (ctx->priv->currentnode);
+        RsvgNodeType type = rsvg_node_get_type (ctx->priv->currentnode);
         if (type == RSVG_NODE_TYPE_TSPAN || type == RSVG_NODE_TYPE_TEXT) {
             /* find the last CHARS node in the text or tspan node, so that we
                can coalesce the text, and thus avoid screwing up the Pango layouts */
@@ -2291,7 +2242,7 @@ rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, Rs
     RsvgNode *node;
 
     node = rsvg_drawing_ctx_acquire_node (ctx, url);
-    if (node == NULL || rsvg_node_type (node) != type) {
+    if (node == NULL || rsvg_node_get_type (node) != type) {
         rsvg_drawing_ctx_release_node (ctx, node);
         return NULL;
     }
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index a076477..62684d1 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -47,7 +47,7 @@ add_color_stop_to_gradient (RsvgNode *node, gpointer data)
     Gradient *gradient = data;
     RsvgGradientStop *stop;
 
-    if (rsvg_node_type (node) != RSVG_NODE_TYPE_STOP)
+    if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_STOP)
         return TRUE; /* just ignore this node */
 
     stop = (RsvgGradientStop *) node;
@@ -110,9 +110,9 @@ radial_gradient_to_rust (RsvgRadialGradient *radial)
 Gradient *
 rsvg_gradient_node_to_rust_gradient (RsvgNode *node)
 {
-    if (rsvg_node_type (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
+    if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
         return linear_gradient_to_rust ((RsvgLinearGradient *) node);
-    } else if (rsvg_node_type (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
+    } else if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
         return radial_gradient_to_rust ((RsvgRadialGradient *) node);
     } else {
         return NULL;
@@ -203,13 +203,13 @@ _set_source_rsvg_paint_server (RsvgDrawingCtx * ctx,
         node = rsvg_drawing_ctx_acquire_node (ctx, ps->core.iri->iri_str);
         if (node == NULL) {
             use_alternate = TRUE;
-        } else if (rsvg_node_type (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
+        } else if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
             _set_source_rsvg_linear_gradient (ctx, (RsvgLinearGradient *) node, opacity, bbox);
             had_paint_server = TRUE;
-        } else if (rsvg_node_type (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
+        } else if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
             _set_source_rsvg_radial_gradient (ctx, (RsvgRadialGradient *) node, opacity, bbox);
             had_paint_server = TRUE;
-        } else if (rsvg_node_type (node) == RSVG_NODE_TYPE_PATTERN) {
+        } else if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_PATTERN) {
             if (_set_source_rsvg_pattern (ctx, (RsvgPattern *) node, bbox)) {
                 had_paint_server = TRUE;
             } else {
diff --git a/rsvg-filter.c b/rsvg-filter.c
index fbc5120..5e6a25d 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -539,7 +539,7 @@ rsvg_filter_context_free (RsvgFilterContext * ctx)
 static gboolean
 node_is_filter_primitive (RsvgNode *node)
 {
-    RsvgNodeType type = rsvg_node_type (node);
+    RsvgNodeType type = rsvg_node_get_type (node);
 
     return type > RSVG_NODE_TYPE_FILTER_PRIMITIVE_FIRST && type < RSVG_NODE_TYPE_FILTER_PRIMITIVE_LAST;
 }
@@ -2138,7 +2138,7 @@ merge_render_child (RsvgNode *node, gpointer data)
     RsvgFilterPrimitive *fp;
     cairo_surface_t *in;
 
-    if (rsvg_node_type (node) != RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE)
+    if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE)
         return TRUE;
 
     fp = (RsvgFilterPrimitive *) node;
@@ -2623,7 +2623,7 @@ component_transfer_render_child (RsvgNode *node, gpointer data)
     struct component_transfer_closure *closure = data;
     RsvgNodeComponentTransferFunc *f;
 
-    if (rsvg_node_type (node) != RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION)
+    if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION)
         return TRUE;
 
     f = (RsvgNodeComponentTransferFunc *) node;
@@ -4496,7 +4496,7 @@ find_light_source (RsvgNode *node, gpointer data)
 {
     struct find_light_source_closure *closure = data;
 
-    if (rsvg_node_type (node) == RSVG_NODE_TYPE_LIGHT_SOURCE) {
+    if (rsvg_node_get_type (node) == RSVG_NODE_TYPE_LIGHT_SOURCE) {
         closure->source = (RsvgNodeLightSource *) node;
     }
 
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index a399cd4..822c3e8 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -543,7 +543,7 @@ rsvg_pattern_node_to_rust_pattern (RsvgNode *node)
     RsvgPattern *pnode;
     Pattern *pattern;
 
-    if (rsvg_node_type (node) != RSVG_NODE_TYPE_PATTERN)
+    if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_PATTERN)
         return NULL;
 
     pnode = (RsvgPattern *) node;
@@ -584,7 +584,7 @@ node_has_at_least_one_child (RsvgNode *node)
 gboolean
 rsvg_pattern_node_has_children (RsvgNode *node)
 {
-    if (rsvg_node_type (node) != RSVG_NODE_TYPE_PATTERN)
+    if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_PATTERN)
         return FALSE;
 
     return node_has_at_least_one_child (node);
diff --git a/rsvg-private.h b/rsvg-private.h
index 3398be0..ea5c2d0 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -348,27 +348,43 @@ struct _RsvgNode {
     RsvgNodeVtable *vtable;
 };
 
+/* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
-RsvgNodeType rsvg_node_type (RsvgNode *node);
+RsvgNodeType rsvg_node_get_type (RsvgNode *node);
 
+/* Implemented in rust/src/node.rs */
+G_GNUC_INTERNAL
+void rsvg_node_unref (RsvgNode *node);
+
+/* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
 RsvgState *rsvg_node_get_state (RsvgNode *node);
 
+/* Implemented in rust/src/node.rs
+ *
+ * Returns a strong reference to the parent (or NULL); use rsvg_node_unref()
+ * when you are done.
+ */
 G_GNUC_INTERNAL
 RsvgNode *rsvg_node_get_parent (RsvgNode *node);
 
+/* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
 void rsvg_node_set_atts (RsvgNode *node, RsvgHandle *handle, RsvgPropertyBag *atts);
 
+/* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
 void rsvg_node_draw (RsvgNode *node, RsvgDrawingCtx *draw, int dominate);
 
 /* Used to iterate among a node's children with rsvg_node_foreach_child().
  * If this caller-supplied function returns FALSE, iteration will stop.
  * Otherwise, iteration will continue to the next child node.
+ *
+ * Keep this in sync with rust/src/node.rs:NodeForeachChild
  */
 typedef gboolean (* RsvgNodeForeachChildFn) (RsvgNode *node, gpointer data);
 
+/* Implemented in rust/src/node.rs */
 G_GNUC_INTERNAL
 void rsvg_node_foreach_child (RsvgNode *node, RsvgNodeForeachChildFn fn, gpointer data);
 
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 1cddb1a..9d6ad50 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -126,7 +126,7 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
         if (poly->builder)
             rsvg_path_builder_destroy (poly->builder);
         poly->builder = _rsvg_node_poly_create_builder (value,
-                                                        rsvg_node_type (self) == RSVG_NODE_TYPE_POLYGON);
+                                                        rsvg_node_get_type (self) == RSVG_NODE_TYPE_POLYGON);
     }
 }
 
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 6c6bb7e..4e4679f 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -217,7 +217,7 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
     }
 
     state = rsvg_current_state (ctx);
-    if (rsvg_node_type (child) != RSVG_NODE_TYPE_SYMBOL) {
+    if (rsvg_node_get_type (child) != RSVG_NODE_TYPE_SYMBOL) {
         cairo_matrix_init_translate (&affine, x, y);
         cairo_matrix_multiply (&state->affine, &affine, &state->affine);
 
diff --git a/rsvg-text.c b/rsvg-text.c
index 0090386..f874284 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -183,7 +183,7 @@ static gboolean
 draw_text_child (RsvgNode *node, gpointer data)
 {
     DrawTextClosure *closure;
-    RsvgNodeType type = rsvg_node_type (node);
+    RsvgNodeType type = rsvg_node_get_type (node);
 
     closure = data;
 
@@ -276,7 +276,7 @@ static gboolean
 compute_child_length (RsvgNode *node, gpointer data)
 {
     ChildrenLengthClosure *closure;
-    RsvgNodeType type = rsvg_node_type (node);
+    RsvgNodeType type = rsvg_node_get_type (node);
     gboolean done;
 
     closure = data;
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 031b34a..62c7f75 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -60,6 +60,9 @@ pub use node::{
     rsvg_node_unref,
     rsvg_node_get_state,
     rsvg_node_add_child,
+    rsvg_node_set_atts,
+    rsvg_node_draw,
+    rsvg_node_foreach_child,
 };
 
 pub use cnode::{
diff --git a/rust/src/node.rs b/rust/src/node.rs
index 664cfee..257ad5f 100644
--- a/rust/src/node.rs
+++ b/rust/src/node.rs
@@ -26,7 +26,7 @@ pub trait NodeTrait {
 
 pub struct Node {
     node_type: NodeType,
-    parent:    Option<Weak<Node>>,      // optional; weak ref to parent
+    parent:    Option<Weak<Node>>,       // optional; weak ref to parent
     children:  RefCell<Vec<Rc<Node>>>,   // strong references to children
     state:     *mut RsvgState,
     node_impl: Box<NodeTrait>
@@ -159,7 +159,39 @@ pub extern fn rsvg_node_add_child (raw_node: *mut RsvgNode, raw_child: *const Rs
     assert! (!raw_node.is_null ());
     assert! (!raw_child.is_null ());
     let node: &mut RsvgNode = unsafe { &mut *raw_node };
-    let child: &RsvgNode = unsafe { & *raw_node };
+    let child: &RsvgNode = unsafe { & *raw_child };
 
     node.add_child (child);
 }
+
+#[no_mangle]
+pub extern fn rsvg_node_set_atts (raw_node: *mut RsvgNode, handle: *const RsvgHandle, pbag: *const 
RsvgPropertyBag) {
+    assert! (!raw_node.is_null ());
+    let node: &RsvgNode = unsafe { & *raw_node };
+
+    node.set_atts (node, handle, pbag);
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_draw (raw_node: *const RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+    assert! (!raw_node.is_null ());
+    let node: &RsvgNode = unsafe { & *raw_node };
+
+    node.draw (node, draw_ctx, dominate);
+}
+
+type NodeForeachChild = unsafe extern "C" fn (node: *const RsvgNode, data: *const libc::c_void) -> bool;
+
+#[no_mangle]
+pub extern fn rsvg_node_foreach_child (raw_node: *const RsvgNode, fn: NodeForeachChild, data: *const 
libc::c_void)
+{
+    assert! (!raw_node.is_null ());
+    let node: &RsvgNode = unsafe { & *raw_node };
+
+    for child in node.children.borrow () {
+        let next = unsafe = { (*fn) (child as *const RsvgNode, data) };
+        if !next {
+            break;
+        }
+    }
+}


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