[librsvg] Implement more generic RsvgNode methods in Rust to replace the C functions
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Implement more generic RsvgNode methods in Rust to replace the C functions
- Date: Fri, 17 Feb 2017 16:38:03 +0000 (UTC)
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]