[librsvg] cnode.rs: New function rsvg_rust_cnode_get_impl() to fetch the C-side implementation
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] cnode.rs: New function rsvg_rust_cnode_get_impl() to fetch the C-side implementation
- Date: Fri, 17 Feb 2017 16:38:18 +0000 (UTC)
commit 5d524850efaa21ca84706977da2c2fa0f8d74e55
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Feb 9 21:00:22 2017 -0600
cnode.rs: New function rsvg_rust_cnode_get_impl() to fetch the C-side implementation
We need this for a couple of special cases that are *not*
implementations of node methods and yet want to use the impl structures.
For example, rsvg_handle_get_dimensions_sub() wants to peek at the
toplevel svg->vbox.
We add a Node.get_c_impl() method, and a NodeTrait.get_c_impl(). The
CNode actually implements this last one by returning its stored
c_node_impl. Nodes implemented fully in Rust will return just a null
pointer.
We can hopefully remove that method once everything is implemented in Rust.
* Move rsvg-structure.[ch] over to rsvg_rust_cnode_new()
The new rsvg_foo_node_new() functions use rsvg_rust_cnode_new()
internally instead of the old _rsvg_node_init(). Also, the RsvgFooNode
structs don't have a "super" field anymore, since RsvgNode is now an
opaque struct from the Rust code.
We re-do the virtual methods for all of rsvg-structure.c. Other files
will follow.
* Move rsvg-shapes.[ch] over to rsvg_rust_cnode_new().
rsvg-base.c | 25 ++-
rsvg-private.h | 26 +++-
rsvg-shapes.c | 271 ++++++++++++++++-------------
rsvg-shapes.h | 14 +-
rsvg-structure.c | 483 ++++++++++++++++++++++++----------------------------
rsvg-structure.h | 27 +--
rust/src/cnode.rs | 17 ++-
rust/src/lib.rs | 1 +
rust/src/node.rs | 24 +++-
rust/src/shapes.rs | 6 +
10 files changed, 466 insertions(+), 428 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 7a2f108..3c30018 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -239,7 +239,7 @@ free_element_name_stack (RsvgHandle *ctx)
ctx->priv->element_name_stack = NULL;
}
-typedef RsvgNode *(* CreateNodeFn) (const char *element_name);
+typedef RsvgNode *(* CreateNodeFn) (const char *element_name, RsvgNode *parent);
typedef struct {
const char *element_name;
@@ -410,7 +410,7 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
creator = get_node_creator_for_element_name (name);
g_assert (creator != NULL && creator->create_fn != NULL);
- newnode = creator->create_fn (name);
+ newnode = creator->create_fn (name, ctx->priv->currentnode);
if (newnode) {
g_assert (rsvg_node_get_type (newnode) != RSVG_NODE_TYPE_INVALID);
@@ -835,8 +835,14 @@ rsvg_end_element (void *data, const xmlChar * xmlname)
}
/* FIXMEchpe: shouldn't this check that currentnode == treebase or sth like that? */
- if (ctx->priv->treebase && !strcmp (name, "svg"))
- _rsvg_node_svg_apply_atts ((RsvgNodeSvg *)ctx->priv->treebase, ctx);
+ if (ctx->priv->treebase && !strcmp (name, "svg")) {
+ RsvgNodeSvg *svg;
+
+ g_assert (rsvg_node_get_type (ctx->priv->treebase) == RSVG_NODE_TYPE_SVG);
+ svg = rsvg_rust_cnode_get_impl (ctx->priv->treebase);
+
+ _rsvg_node_svg_apply_atts (ctx->priv->treebase, svg, ctx);
+ }
}
}
@@ -1512,11 +1518,12 @@ rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimensi
if (!sself && id)
return FALSE;
- root = (RsvgNodeSvg *) handle->priv->treebase;
-
- if (!root)
+ if (!handle->priv->treebase)
return FALSE;
+ g_assert (rsvg_node_get_type (handle->priv->treebase) == RSVG_NODE_TYPE_SVG);
+ root = rsvg_rust_cnode_get_impl (handle->priv->treebase);
+
bbox.rect.x = bbox.rect.y = 0;
bbox.rect.width = bbox.rect.height = 1;
@@ -1592,7 +1599,6 @@ gboolean
rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_data, const char *id)
{
RsvgDrawingCtx *draw;
- RsvgNodeSvg *root;
RsvgNode *node;
RsvgBbox bbox;
RsvgDimensionData dimension_data;
@@ -1623,8 +1629,7 @@ rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_d
return TRUE;
}
- root = (RsvgNodeSvg *) handle->priv->treebase;
- if (!root)
+ if (!handle->priv->treebase)
return FALSE;
target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
diff --git a/rsvg-private.h b/rsvg-private.h
index d52aede..e16f79f 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -334,11 +334,23 @@ typedef enum {
RSVG_NODE_TYPE_FILTER_PRIMITIVE_LAST /* just a marker; not a valid type */
} RsvgNodeType;
-typedef struct {
- void (*free) (RsvgNode * self);
- void (*draw) (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
- void (*set_atts) (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *atts);
-} RsvgNodeVtable;
+typedef void (* CNodeSetAtts) (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *pbag);
+typedef void (* CNodeDraw) (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate);
+typedef void (* CNodeFree) (gpointer impl);
+
+/* Implemented in rust/src/node.rs */
+G_GNUC_INTERNAL
+RsvgNode *rsvg_rust_cnode_new (RsvgNodeType node_type,
+ RsvgNode *parent,
+ RsvgState *state,
+ gpointer impl,
+ CNodeSetAtts set_atts_fn,
+ CNodeDraw draw_fn,
+ CNodeFree free_fn);
+
+/* Implemented in rust/src/node.rs */
+G_GNUC_INTERNAL
+gpointer rsvg_rust_cnode_get_impl (RsvgNode *node);
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
@@ -362,6 +374,10 @@ RsvgNode *rsvg_node_get_parent (RsvgNode *node);
/* Implemented in rust/src/node.rs */
G_GNUC_INTERNAL
+void rsvg_node_add_child (RsvgNode *node, RsvgNode *child);
+
+/* 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 */
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 9d6ad50..2e0906f 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -44,38 +44,38 @@
typedef struct _RsvgNodePath RsvgNodePath;
struct _RsvgNodePath {
- RsvgNode super;
RsvgPathBuilder *builder;
};
static void
-rsvg_node_path_free (RsvgNode * self)
+rsvg_node_path_free (gpointer impl)
{
- RsvgNodePath *path = (RsvgNodePath *) self;
+ RsvgNodePath *path = impl;
+
if (path->builder)
rsvg_path_builder_destroy (path->builder);
- _rsvg_node_free (self);
+ g_free (path);
}
static void
-rsvg_node_path_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_path_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- RsvgNodePath *path = (RsvgNodePath *) self;
+ RsvgNodePath *path = impl;
if (!path->builder)
return;
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, path->builder);
rsvg_render_markers (ctx, path->builder);
}
static void
-rsvg_node_path_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_path_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag * atts)
{
- RsvgNodePath *path = (RsvgNodePath *) self;
+ RsvgNodePath *path = impl;
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "d"))) {
@@ -86,38 +86,36 @@ rsvg_node_path_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * at
}
RsvgNode *
-rsvg_new_path (const char *element_name)
+rsvg_new_path (const char *element_name, RsvgNode *parent)
{
RsvgNodePath *path;
- RsvgNodeVtable vtable = {
- rsvg_node_path_free,
- rsvg_node_path_draw,
- rsvg_node_path_set_atts
- };
-
- path = g_new (RsvgNodePath, 1);
- _rsvg_node_init (&path->super, RSVG_NODE_TYPE_PATH, &vtable);
+ path = g_new0 (RsvgNodePath, 1);
path->builder = NULL;
- return &path->super;
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_PATH,
+ parent,
+ rsvg_state_new (),
+ path,
+ rsvg_node_path_set_atts,
+ rsvg_node_path_draw,
+ rsvg_node_path_free);
}
+typedef struct _RsvgNodePoly RsvgNodePoly;
+
struct _RsvgNodePoly {
- RsvgNode super;
RsvgPathBuilder *builder;
};
-typedef struct _RsvgNodePoly RsvgNodePoly;
-
static RsvgPathBuilder *
-_rsvg_node_poly_create_builder (const char *value,
- gboolean close_path);
+rsvg_node_poly_create_builder (const char *value,
+ gboolean close_path);
static void
-_rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_poly_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodePoly *poly = (RsvgNodePoly *) self;
+ RsvgNodePoly *poly = impl;
const char *value;
/* support for svg < 1.0 which used verts */
@@ -125,14 +123,14 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
|| (value = rsvg_property_bag_lookup (atts, "points"))) {
if (poly->builder)
rsvg_path_builder_destroy (poly->builder);
- poly->builder = _rsvg_node_poly_create_builder (value,
- rsvg_node_get_type (self) == RSVG_NODE_TYPE_POLYGON);
+ poly->builder = rsvg_node_poly_create_builder (value,
+ rsvg_node_get_type (node) == RSVG_NODE_TYPE_POLYGON);
}
}
static RsvgPathBuilder *
-_rsvg_node_poly_create_builder (const char *value,
- gboolean close_path)
+rsvg_node_poly_create_builder (const char *value,
+ gboolean close_path)
{
double *pointlist;
guint pointlist_len, i;
@@ -177,70 +175,70 @@ _rsvg_node_poly_create_builder (const char *value,
}
static void
-_rsvg_node_poly_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_poly_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- RsvgNodePoly *poly = (RsvgNodePoly *) self;
+ RsvgNodePoly *poly = impl;
if (poly->builder == NULL)
return;
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, poly->builder);
rsvg_render_markers (ctx, poly->builder);
}
static void
-_rsvg_node_poly_free (RsvgNode * self)
+rsvg_node_poly_free (gpointer impl)
{
- RsvgNodePoly *poly = (RsvgNodePoly *) self;
+ RsvgNodePoly *poly = impl;
+
if (poly->builder)
rsvg_path_builder_destroy (poly->builder);
- _rsvg_node_free (self);
+ g_free (poly);
}
static RsvgNode *
-rsvg_new_any_poly (RsvgNodeType type)
+rsvg_new_any_poly (RsvgNodeType type, RsvgNode *parent)
{
RsvgNodePoly *poly;
- RsvgNodeVtable vtable = {
- _rsvg_node_poly_free,
- _rsvg_node_poly_draw,
- _rsvg_node_poly_set_atts
- };
-
- poly = g_new (RsvgNodePoly, 1);
- _rsvg_node_init (&poly->super, type, &vtable);
+ poly = g_new0 (RsvgNodePoly, 1);
poly->builder = NULL;
- return &poly->super;
+
+ return rsvg_rust_cnode_new (type,
+ parent,
+ rsvg_state_new (),
+ poly,
+ rsvg_node_poly_set_atts,
+ rsvg_node_poly_draw,
+ rsvg_node_poly_free);
}
RsvgNode *
-rsvg_new_polygon (const char *element_name)
+rsvg_new_polygon (const char *element_name, RsvgNode *parent)
{
- return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYGON);
+ return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYGON, parent);
}
RsvgNode *
-rsvg_new_polyline (const char *element_name)
+rsvg_new_polyline (const char *element_name, RsvgNode *parent)
{
- return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYLINE);
+ return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYLINE, parent);
}
+typedef struct _RsvgNodeLine RsvgNodeLine;
+
struct _RsvgNodeLine {
- RsvgNode super;
RsvgLength x1, x2, y1, y2;
};
-typedef struct _RsvgNodeLine RsvgNodeLine;
-
static void
-_rsvg_node_line_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_line_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeLine *line = (RsvgNodeLine *) self;
+ RsvgNodeLine *line = impl;
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "x1")))
@@ -254,10 +252,10 @@ _rsvg_node_line_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
}
static void
-_rsvg_node_line_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_line_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
+ RsvgNodeLine *line = impl;
RsvgPathBuilder *builder;
- RsvgNodeLine *line = (RsvgNodeLine *) self;
double x1, y1, x2, y2;
builder = rsvg_path_builder_new ();
@@ -270,7 +268,7 @@ _rsvg_node_line_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_move_to (builder, x1, y1);
rsvg_path_builder_line_to (builder, x2, y2);
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, builder);
rsvg_render_markers (ctx, builder);
@@ -278,35 +276,42 @@ _rsvg_node_line_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_destroy (builder);
}
+static void
+rsvg_node_line_free (gpointer impl)
+{
+ RsvgNodeLine *line = impl;
+
+ g_free (line);
+}
+
RsvgNode *
-rsvg_new_line (const char *element_name)
+rsvg_new_line (const char *element_name, RsvgNode *parent)
{
RsvgNodeLine *line;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_line_draw,
- _rsvg_node_line_set_atts
- };
-
- line = g_new (RsvgNodeLine, 1);
- _rsvg_node_init (&line->super, RSVG_NODE_TYPE_LINE, &vtable);
+ line = g_new0 (RsvgNodeLine, 1);
line->x1 = line->x2 = line->y1 = line->y2 = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
- return &line->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_LINE,
+ parent,
+ rsvg_state_new (),
+ line,
+ rsvg_node_line_set_atts,
+ rsvg_node_line_draw,
+ rsvg_node_line_free);
}
+typedef struct _RsvgNodeRect RsvgNodeRect;
+
struct _RsvgNodeRect {
- RsvgNode super;
RsvgLength x, y, w, h, rx, ry;
gboolean got_rx, got_ry;
};
-typedef struct _RsvgNodeRect RsvgNodeRect;
-
static void
-_rsvg_node_rect_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_rect_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeRect *rect = (RsvgNodeRect *) self;
+ RsvgNodeRect *rect = impl;
const char *value;
/* FIXME: negative w/h/rx/ry is an error, per http://www.w3.org/TR/SVG11/shapes.html#RectElement */
@@ -329,12 +334,12 @@ _rsvg_node_rect_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
}
static void
-_rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_rect_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
+ RsvgNodeRect *rect = impl;
double x, y, w, h, rx, ry;
double half_w, half_h;
RsvgPathBuilder *builder;
- RsvgNodeRect *rect = (RsvgNodeRect *) self;
x = rsvg_length_normalize (&rect->x, ctx);
y = rsvg_length_normalize (&rect->y, ctx);
@@ -455,42 +460,49 @@ _rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
}
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, builder);
rsvg_path_builder_destroy (builder);
}
+static void
+rsvg_node_rect_free (gpointer impl)
+{
+ RsvgNodeRect *rect = impl;
+
+ g_free (rect);
+}
+
RsvgNode *
-rsvg_new_rect (const char *element_name)
+rsvg_new_rect (const char *element_name, RsvgNode *parent)
{
RsvgNodeRect *rect;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_rect_draw,
- _rsvg_node_rect_set_atts
- };
-
- rect = g_new (RsvgNodeRect, 1);
- _rsvg_node_init (&rect->super, RSVG_NODE_TYPE_RECT, &vtable);
+ rect = g_new0 (RsvgNodeRect, 1);
rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
rect->got_rx = rect->got_ry = FALSE;
- return &rect->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_RECT,
+ parent,
+ rsvg_state_new (),
+ rect,
+ rsvg_node_rect_set_atts,
+ rsvg_node_rect_draw,
+ rsvg_node_rect_free);
}
+typedef struct _RsvgNodeCircle RsvgNodeCircle;
+
struct _RsvgNodeCircle {
- RsvgNode super;
RsvgLength cx, cy, r;
};
-typedef struct _RsvgNodeCircle RsvgNodeCircle;
-
static void
-_rsvg_node_circle_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_circle_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeCircle *circle = (RsvgNodeCircle *) self;
+ RsvgNodeCircle *circle = impl;
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "cx")))
@@ -502,9 +514,9 @@ _rsvg_node_circle_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
}
static void
-_rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_circle_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- RsvgNodeCircle *circle = (RsvgNodeCircle *) self;
+ RsvgNodeCircle *circle = impl;
double cx, cy, r;
RsvgPathBuilder *builder;
@@ -543,41 +555,48 @@ _rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, builder);
rsvg_path_builder_destroy (builder);
}
+static void
+rsvg_node_circle_free (gpointer impl)
+{
+ RsvgNodeCircle *circle = impl;
+
+ g_free (circle);
+}
+
RsvgNode *
-rsvg_new_circle (const char *element_name)
+rsvg_new_circle (const char *element_name, RsvgNode *parent)
{
RsvgNodeCircle *circle;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_circle_draw,
- _rsvg_node_circle_set_atts
- };
-
- circle = g_new (RsvgNodeCircle, 1);
- _rsvg_node_init (&circle->super, RSVG_NODE_TYPE_CIRCLE, &vtable);
+ circle = g_new0 (RsvgNodeCircle, 1);
circle->cx = circle->cy = circle->r = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
- return &circle->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_CIRCLE,
+ parent,
+ rsvg_state_new (),
+ circle,
+ rsvg_node_circle_set_atts,
+ rsvg_node_circle_draw,
+ rsvg_node_circle_free);
}
+typedef struct _RsvgNodeEllipse RsvgNodeEllipse;
+
struct _RsvgNodeEllipse {
- RsvgNode super;
RsvgLength cx, cy, rx, ry;
};
-typedef struct _RsvgNodeEllipse RsvgNodeEllipse;
-
static void
-_rsvg_node_ellipse_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_ellipse_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeEllipse *ellipse = (RsvgNodeEllipse *) self;
+ RsvgNodeEllipse *ellipse = impl;
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "cx")))
@@ -591,9 +610,9 @@ _rsvg_node_ellipse_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag
}
static void
-_rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_ellipse_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- RsvgNodeEllipse *ellipse = (RsvgNodeEllipse *) self;
+ RsvgNodeEllipse *ellipse = impl;
double cx, cy, rx, ry;
RsvgPathBuilder *builder;
@@ -633,26 +652,34 @@ _rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_render_path_builder (ctx, builder);
rsvg_path_builder_destroy (builder);
}
+static void
+rsvg_node_ellipse_free (gpointer impl)
+{
+ RsvgNodeRect *ellipse = impl;
+
+ g_free (ellipse);
+}
+
RsvgNode *
-rsvg_new_ellipse (const char *element_name)
+rsvg_new_ellipse (const char *element_name, RsvgNode *parent)
{
RsvgNodeEllipse *ellipse;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_ellipse_draw,
- _rsvg_node_ellipse_set_atts
- };
-
- ellipse = g_new (RsvgNodeEllipse, 1);
- _rsvg_node_init (&ellipse->super, RSVG_NODE_TYPE_ELLIPSE, &vtable);
+ ellipse = g_new0 (RsvgNodeEllipse, 1);
ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
- return &ellipse->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_ELLIPSE,
+ parent,
+ rsvg_state_new (),
+ ellipse,
+ rsvg_node_ellipse_set_atts,
+ rsvg_node_ellipse_draw,
+ rsvg_node_ellipse_free);
}
diff --git a/rsvg-shapes.h b/rsvg-shapes.h
index 5b0029f..686badf 100644
--- a/rsvg-shapes.h
+++ b/rsvg-shapes.h
@@ -37,19 +37,19 @@
G_BEGIN_DECLS
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_path (const char *element_name);
+RsvgNode *rsvg_new_path (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_polygon (const char *element_name);
+RsvgNode *rsvg_new_polygon (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_polyline (const char *element_name);
+RsvgNode *rsvg_new_polyline (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_line (const char *element_name);
+RsvgNode *rsvg_new_line (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_rect (const char *element_name);
+RsvgNode *rsvg_new_rect (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_circle (const char *element_name);
+RsvgNode *rsvg_new_circle (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_ellipse (const char *element_name);
+RsvgNode *rsvg_new_ellipse (const char *element_name, RsvgNode *parent);
G_END_DECLS
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 5ff0b6c..bea8cd7 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -39,41 +39,39 @@ typedef struct _RsvgNodeUse RsvgNodeUse;
typedef struct _RsvgNodeSymbol RsvgNodeSymbol;
struct _RsvgNodeGroup {
- RsvgNode super;
+ int dummy; /* just to avoid having an empty struct */
};
struct _RsvgNodeSymbol {
- RsvgNode super;
guint32 preserve_aspect_ratio;
RsvgViewBox vbox;
};
struct _RsvgNodeUse {
- RsvgNode super;
char *link;
RsvgLength x, y, w, h;
};
void
-rsvg_node_draw_from_stack (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_draw_from_stack (RsvgNode *node, RsvgDrawingCtx * ctx, int dominate)
{
RsvgState *state;
GSList *stacksave;
stacksave = ctx->drawsub_stack;
if (stacksave) {
- if (stacksave->data != self)
+ if (stacksave->data != node)
return;
ctx->drawsub_stack = stacksave->next;
}
- state = rsvg_node_get_state (self);
+ state = rsvg_node_get_state (node);
if (state->visible) {
rsvg_state_push (ctx);
- rsvg_node_draw (self, ctx, dominate);
+ rsvg_node_draw (node, ctx, dominate);
rsvg_state_pop (ctx);
}
@@ -95,230 +93,90 @@ draw_child (RsvgNode *node, gpointer data)
/* generic function for drawing all of the children of a particular node */
void
-_rsvg_node_draw_children (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+_rsvg_node_draw_children (RsvgNode *node, RsvgDrawingCtx *ctx, int dominate)
{
if (dominate != -1) {
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_push_discrete_layer (ctx);
}
- rsvg_node_foreach_child (self, draw_child, ctx);
+ rsvg_node_foreach_child (node, draw_child, ctx);
if (dominate != -1)
rsvg_pop_discrete_layer (ctx);
}
-/* generic function that doesn't draw anything at all */
static void
-_rsvg_node_draw_nothing (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_group_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
+ /* nothing */
}
static void
-_rsvg_node_dont_set_atts (RsvgNode * node, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_group_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
+ _rsvg_node_draw_children (node, ctx, dominate);
}
-void
-_rsvg_node_init (RsvgNode * self,
- RsvgNodeType type,
- RsvgNodeVtable *vtable)
+static void
+rsvg_group_free (gpointer impl)
{
- self->type = type;
- self->parent = NULL;
- self->children = g_ptr_array_new ();
- self->state = rsvg_state_new ();
- self->vtable = g_new (RsvgNodeVtable, 1);
-
- if (vtable->free) {
- self->vtable->free = vtable->free;
- } else {
- self->vtable->free = _rsvg_node_free;
- }
-
- if (vtable->draw) {
- self->vtable->draw = vtable->draw;
- } else {
- self->vtable->draw = _rsvg_node_draw_nothing;
- }
+ RsvgNodeGroup *group = impl;
- if (vtable->set_atts) {
- self->vtable->set_atts = vtable->set_atts;
- } else {
- self->vtable->set_atts = _rsvg_node_dont_set_atts;
- }
-}
-
-void
-_rsvg_node_free (RsvgNode * self)
-{
- if (self->state != NULL) {
- rsvg_state_free (self->state);
- self->state = NULL;
- }
- if (self->children != NULL) {
- g_ptr_array_free (self->children, TRUE);
- self->children = NULL;
- }
-
- self->parent = NULL;
- self->type = RSVG_NODE_TYPE_INVALID;
-
- g_free (self->vtable);
- self->vtable = NULL;
-
- g_free (self);
+ g_free (group);
}
RsvgNode *
-rsvg_new_group (const char *element_name)
+rsvg_new_group (const char *element_name, RsvgNode *parent)
{
RsvgNodeGroup *group;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_draw_children,
- NULL
- };
-
- group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_GROUP, &vtable);
-
- return &group->super;
-}
-
-void
-rsvg_node_add_child (RsvgNode * self, RsvgNode * child)
-{
- g_ptr_array_add (self->children, child);
- child->parent = self;
-}
-
-static gboolean
-rsvg_node_is_ancestor (RsvgNode * potential_ancestor, RsvgNode * potential_descendant)
-{
- /* work our way up the family tree */
- while (TRUE) {
- if (potential_ancestor == potential_descendant)
- return TRUE;
- else if (rsvg_node_get_parent (potential_descendant) == NULL)
- return FALSE;
- else
- potential_descendant = rsvg_node_get_parent (potential_descendant);
- }
-
- g_assert_not_reached ();
- return FALSE;
-}
-
-static void
-rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
-{
- RsvgNodeUse *use = (RsvgNodeUse *) self;
- RsvgNode *child;
- RsvgState *state;
- cairo_matrix_t affine;
- double x, y, w, h;
- x = rsvg_length_normalize (&use->x, ctx);
- y = rsvg_length_normalize (&use->y, ctx);
- w = rsvg_length_normalize (&use->w, ctx);
- h = rsvg_length_normalize (&use->h, ctx);
-
- rsvg_state_reinherit_top (ctx, self->state, dominate);
- if (use->link == NULL)
- return;
- child = rsvg_drawing_ctx_acquire_node (ctx, use->link);
- if (!child)
- return;
- else if (rsvg_node_is_ancestor (child, self)) { /* or, if we're <use>'ing ourself */
- rsvg_drawing_ctx_release_node (ctx, child);
- return;
- }
-
- state = rsvg_current_state (ctx);
- 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);
-
- rsvg_push_discrete_layer (ctx);
- rsvg_node_draw_from_stack (child, ctx, 1);
- rsvg_pop_discrete_layer (ctx);
- } else {
- RsvgNodeSymbol *symbol = (RsvgNodeSymbol *) child;
-
- if (symbol->vbox.active) {
- rsvg_aspect_ratio_compute (symbol->preserve_aspect_ratio,
- symbol->vbox.rect.width,
- symbol->vbox.rect.height,
- &x, &y, &w, &h);
-
- cairo_matrix_init_translate (&affine, x, y);
- cairo_matrix_multiply (&state->affine, &affine, &state->affine);
+ group = g_new0 (RsvgNodeGroup, 1);
- cairo_matrix_init_scale (&affine, w / symbol->vbox.rect.width, h / symbol->vbox.rect.height);
- cairo_matrix_multiply (&state->affine, &affine, &state->affine);
-
- cairo_matrix_init_translate (&affine, -symbol->vbox.rect.x, -symbol->vbox.rect.y);
- cairo_matrix_multiply (&state->affine, &affine, &state->affine);
-
- rsvg_drawing_ctx_push_view_box (ctx, symbol->vbox.rect.width, symbol->vbox.rect.height);
- rsvg_push_discrete_layer (ctx);
- if (!state->overflow || (!state->has_overflow && rsvg_node_get_state (child)->overflow))
- rsvg_add_clipping_rect (ctx, symbol->vbox.rect.x, symbol->vbox.rect.y,
- symbol->vbox.rect.width, symbol->vbox.rect.height);
- } else {
- cairo_matrix_init_translate (&affine, x, y);
- cairo_matrix_multiply (&state->affine, &affine, &state->affine);
- rsvg_push_discrete_layer (ctx);
- }
-
- rsvg_state_push (ctx);
- _rsvg_node_draw_children (child, ctx, 1);
- rsvg_state_pop (ctx);
- rsvg_pop_discrete_layer (ctx);
- if (symbol->vbox.active)
- rsvg_drawing_ctx_pop_view_box (ctx);
- }
-
- rsvg_drawing_ctx_release_node (ctx, child);
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_GROUP,
+ parent,
+ rsvg_state_new (),
+ group,
+ rsvg_group_set_atts,
+ rsvg_group_draw,
+ rsvg_group_free);
}
static void
-rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_svg_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- RsvgNodeSvg *sself;
+ RsvgNodeSvg *svg = impl;
RsvgState *state;
cairo_matrix_t affine, affine_old, affine_new;
double nx, ny, nw, nh;
- sself = (RsvgNodeSvg *) self;
- nx = rsvg_length_normalize (&sself->x, ctx);
- ny = rsvg_length_normalize (&sself->y, ctx);
- nw = rsvg_length_normalize (&sself->w, ctx);
- nh = rsvg_length_normalize (&sself->h, ctx);
+ nx = rsvg_length_normalize (&svg->x, ctx);
+ ny = rsvg_length_normalize (&svg->y, ctx);
+ nw = rsvg_length_normalize (&svg->w, ctx);
+ nh = rsvg_length_normalize (&svg->h, ctx);
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
state = rsvg_current_state (ctx);
affine_old = state->affine;
- if (sself->vbox.active) {
+ if (svg->vbox.active) {
double x = nx, y = ny, w = nw, h = nh;
- rsvg_aspect_ratio_compute (sself->preserve_aspect_ratio,
- sself->vbox.rect.width,
- sself->vbox.rect.height,
+ rsvg_aspect_ratio_compute (svg->preserve_aspect_ratio,
+ svg->vbox.rect.width,
+ svg->vbox.rect.height,
&x, &y, &w, &h);
cairo_matrix_init (&affine,
- w / sself->vbox.rect.width,
+ w / svg->vbox.rect.width,
0,
0,
- h / sself->vbox.rect.height,
- x - sself->vbox.rect.x * w / sself->vbox.rect.width,
- y - sself->vbox.rect.y * h / sself->vbox.rect.height);
+ h / svg->vbox.rect.height,
+ x - svg->vbox.rect.x * w / svg->vbox.rect.width,
+ y - svg->vbox.rect.y * h / svg->vbox.rect.height);
cairo_matrix_multiply (&state->affine, &affine, &state->affine);
- rsvg_drawing_ctx_push_view_box (ctx, sself->vbox.rect.width, sself->vbox.rect.height);
+ rsvg_drawing_ctx_push_view_box (ctx, svg->vbox.rect.width, svg->vbox.rect.height);
} else {
cairo_matrix_init_translate (&affine, nx, ny);
cairo_matrix_multiply (&state->affine, &affine, &state->affine);
@@ -331,23 +189,23 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
/* Bounding box addition must be AFTER the discrete layer push,
which must be AFTER the transformation happens. */
- if (!state->overflow && rsvg_node_get_parent (self)) {
+ if (!state->overflow && rsvg_node_get_parent (node)) {
state->affine = affine_old;
rsvg_add_clipping_rect (ctx, nx, ny, nw, nh);
state->affine = affine_new;
}
- rsvg_node_foreach_child (self, draw_child, ctx);
+ rsvg_node_foreach_child (node, draw_child, ctx);
rsvg_pop_discrete_layer (ctx);
rsvg_drawing_ctx_pop_view_box (ctx);
}
static void
-rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_svg_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
const char *value;
- RsvgNodeSvg *svg = (RsvgNodeSvg *) self;
+ RsvgNodeSvg *svg = impl;
if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
svg->vbox = rsvg_css_parse_vbox (value);
@@ -362,7 +220,7 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
* x & y attributes have no effect on outermost svg
* http://www.w3.org/TR/SVG/struct.html#SVGElement
*/
- if (rsvg_node_get_parent (self)) {
+ if (rsvg_node_get_parent (node)) {
if ((value = rsvg_property_bag_lookup (atts, "x")))
svg->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
@@ -374,48 +232,41 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
* style element is not loaded yet here, so we need to store those attribues
* to be applied later.
*/
- svg->atts = rsvg_property_bag_dup(atts);
+ svg->atts = rsvg_property_bag_dup (atts);
}
void
-_rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx)
+_rsvg_node_svg_apply_atts (RsvgNode *node, RsvgNodeSvg *svg, RsvgHandle *ctx)
{
const char *id = NULL, *klazz = NULL, *value;
- if (self->atts && rsvg_property_bag_size (self->atts)) {
- if ((value = rsvg_property_bag_lookup (self->atts, "class")))
+ if (svg->atts && rsvg_property_bag_size (svg->atts)) {
+ if ((value = rsvg_property_bag_lookup (svg->atts, "class")))
klazz = value;
- if ((value = rsvg_property_bag_lookup (self->atts, "id")))
+ if ((value = rsvg_property_bag_lookup (svg->atts, "id")))
id = value;
- rsvg_parse_style_attrs (ctx, rsvg_node_get_state ((RsvgNode *) self), "svg", klazz, id, self->atts);
+ rsvg_parse_style_attrs (ctx, rsvg_node_get_state (node), "svg", klazz, id, svg->atts);
}
}
static void
-rsvg_node_svg_free (RsvgNode * self)
+rsvg_node_svg_free (gpointer impl)
{
- RsvgNodeSvg *svg = (RsvgNodeSvg *) self;
+ RsvgNodeSvg *svg = impl;
if (svg->atts) {
rsvg_property_bag_free (svg->atts);
svg->atts = NULL;
}
- _rsvg_node_free (self);
+ g_free (svg);
}
RsvgNode *
-rsvg_new_svg (const char *element_name)
+rsvg_new_svg (const char *element_name, RsvgNode *parent)
{
RsvgNodeSvg *svg;
- RsvgNodeVtable vtable = {
- rsvg_node_svg_free,
- rsvg_node_svg_draw,
- rsvg_node_svg_set_atts
- };
-
- svg = g_new (RsvgNodeSvg, 1);
- _rsvg_node_init (&svg->super, RSVG_NODE_TYPE_SVG, &vtable);
+ svg = g_new0 (RsvgNodeSvg, 1);
svg->vbox.active = FALSE;
svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
svg->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
@@ -423,25 +274,122 @@ rsvg_new_svg (const char *element_name)
svg->w = rsvg_length_parse ("100%", LENGTH_DIR_HORIZONTAL);
svg->h = rsvg_length_parse ("100%", LENGTH_DIR_VERTICAL);
svg->atts = NULL;
- return &svg->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_SVG,
+ parent,
+ rsvg_state_new (),
+ svg,
+ rsvg_node_svg_set_atts,
+ rsvg_node_svg_draw,
+ rsvg_node_svg_free);
+}
+
+static gboolean
+rsvg_node_is_ancestor (RsvgNode * potential_ancestor, RsvgNode * potential_descendant)
+{
+ /* work our way up the family tree */
+ while (TRUE) {
+ if (potential_ancestor == potential_descendant)
+ return TRUE;
+ else if (rsvg_node_get_parent (potential_descendant) == NULL)
+ return FALSE;
+ else
+ potential_descendant = rsvg_node_get_parent (potential_descendant);
+ }
+
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+static void
+rsvg_node_use_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
+{
+ RsvgNodeUse *use = impl;
+ RsvgNode *child;
+ RsvgState *state;
+ cairo_matrix_t affine;
+ double x, y, w, h;
+
+ x = rsvg_length_normalize (&use->x, ctx);
+ y = rsvg_length_normalize (&use->y, ctx);
+ w = rsvg_length_normalize (&use->w, ctx);
+ h = rsvg_length_normalize (&use->h, ctx);
+
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
+
+ if (use->link == NULL)
+ return;
+ child = rsvg_drawing_ctx_acquire_node (ctx, use->link);
+ if (!child)
+ return;
+ else if (rsvg_node_is_ancestor (child, node)) { /* or, if we're <use>'ing ourself */
+ rsvg_drawing_ctx_release_node (ctx, child);
+ return;
+ }
+
+ state = rsvg_current_state (ctx);
+ 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);
+
+ rsvg_push_discrete_layer (ctx);
+ rsvg_node_draw_from_stack (child, ctx, 1);
+ rsvg_pop_discrete_layer (ctx);
+ } else {
+ RsvgNodeSymbol *symbol = rsvg_rust_cnode_get_impl (child);
+
+ if (symbol->vbox.active) {
+ rsvg_aspect_ratio_compute (symbol->preserve_aspect_ratio,
+ symbol->vbox.rect.width,
+ symbol->vbox.rect.height,
+ &x, &y, &w, &h);
+
+ cairo_matrix_init_translate (&affine, x, y);
+ cairo_matrix_multiply (&state->affine, &affine, &state->affine);
+
+ cairo_matrix_init_scale (&affine, w / symbol->vbox.rect.width, h / symbol->vbox.rect.height);
+ cairo_matrix_multiply (&state->affine, &affine, &state->affine);
+
+ cairo_matrix_init_translate (&affine, -symbol->vbox.rect.x, -symbol->vbox.rect.y);
+ cairo_matrix_multiply (&state->affine, &affine, &state->affine);
+
+ rsvg_drawing_ctx_push_view_box (ctx, symbol->vbox.rect.width, symbol->vbox.rect.height);
+ rsvg_push_discrete_layer (ctx);
+ if (!state->overflow || (!state->has_overflow && rsvg_node_get_state (child)->overflow))
+ rsvg_add_clipping_rect (ctx, symbol->vbox.rect.x, symbol->vbox.rect.y,
+ symbol->vbox.rect.width, symbol->vbox.rect.height);
+ } else {
+ cairo_matrix_init_translate (&affine, x, y);
+ cairo_matrix_multiply (&state->affine, &affine, &state->affine);
+ rsvg_push_discrete_layer (ctx);
+ }
+
+ rsvg_state_push (ctx);
+ _rsvg_node_draw_children (child, ctx, 1);
+ rsvg_state_pop (ctx);
+ rsvg_pop_discrete_layer (ctx);
+ if (symbol->vbox.active)
+ rsvg_drawing_ctx_pop_view_box (ctx);
+ }
+
+ rsvg_drawing_ctx_release_node (ctx, child);
}
static void
-rsvg_node_use_free (RsvgNode * node)
+rsvg_node_use_free (gpointer impl)
{
- RsvgNodeUse *use = (RsvgNodeUse *) node;
+ RsvgNodeUse *use = impl;
+
g_free (use->link);
- _rsvg_node_free (node);
+ g_free (use);
}
static void
-rsvg_node_use_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_use_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeUse *use;
+ RsvgNodeUse *use = impl;
const char *value;
- use = (RsvgNodeUse *) self;
-
if ((value = rsvg_property_bag_lookup (atts, "x")))
use->x = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
if ((value = rsvg_property_bag_lookup (atts, "y")))
@@ -458,30 +406,30 @@ rsvg_node_use_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
}
RsvgNode *
-rsvg_new_use (const char *element_name)
+rsvg_new_use (const char *element_name, RsvgNode *parent)
{
RsvgNodeUse *use;
- RsvgNodeVtable vtable = {
- rsvg_node_use_free,
- rsvg_node_use_draw,
- rsvg_node_use_set_atts
- };
-
- use = g_new (RsvgNodeUse, 1);
- _rsvg_node_init (&use->super, RSVG_NODE_TYPE_USE, &vtable);
+ use = g_new0 (RsvgNodeUse, 1);
use->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
use->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
use->w = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
use->h = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
use->link = NULL;
- return (RsvgNode *) use;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_USE,
+ parent,
+ rsvg_state_new (),
+ use,
+ rsvg_node_use_set_atts,
+ rsvg_node_use_draw,
+ rsvg_node_use_free);
}
static void
-rsvg_node_symbol_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
+rsvg_node_symbol_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
- RsvgNodeSymbol *symbol = (RsvgNodeSymbol *) self;
+ RsvgNodeSymbol *symbol = impl;
const char *value;
if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
@@ -490,39 +438,59 @@ rsvg_node_symbol_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
symbol->preserve_aspect_ratio = rsvg_aspect_ratio_parse (value);
}
+static void
+rsvg_node_symbol_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
+{
+ /* nothing; this gets drawn specially in rsvg_node_use_draw() */
+}
+
+static void
+rsvg_node_symbol_free (gpointer impl)
+{
+ RsvgNodeSymbol *symbol = impl;
+
+ g_free (symbol);
+}
+
RsvgNode *
-rsvg_new_symbol (const char *element_name)
+rsvg_new_symbol (const char *element_name, RsvgNode *parent)
{
RsvgNodeSymbol *symbol;
- RsvgNodeVtable vtable = {
- NULL,
- NULL,
- rsvg_node_symbol_set_atts
- };
-
- symbol = g_new (RsvgNodeSymbol, 1);
- _rsvg_node_init (&symbol->super, RSVG_NODE_TYPE_SYMBOL, &vtable);
+ symbol = g_new0 (RsvgNodeSymbol, 1);
symbol->vbox.active = FALSE;
symbol->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- return &symbol->super;
+
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_SYMBOL,
+ parent,
+ rsvg_state_new (),
+ symbol,
+ rsvg_node_symbol_set_atts,
+ rsvg_node_symbol_draw,
+ rsvg_node_symbol_free);
+}
+
+static void
+rsvg_defs_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
+{
+ /* nothing */
}
RsvgNode *
-rsvg_new_defs (const char *element_name)
+rsvg_new_defs (const char *element_name, RsvgNode *parent)
{
RsvgNodeGroup *group;
- RsvgNodeVtable vtable = {
- NULL,
- NULL,
- NULL,
- };
- group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_DEFS, &vtable);
+ group = g_new0 (RsvgNodeGroup, 1);
- return &group->super;
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_DEFS,
+ parent,
+ rsvg_state_new (),
+ group,
+ rsvg_group_set_atts,
+ rsvg_defs_draw,
+ rsvg_group_free);
}
static gboolean
@@ -542,29 +510,28 @@ draw_child_if_cond_true_and_stop (RsvgNode *node, gpointer data)
}
static void
-_rsvg_node_switch_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+rsvg_node_switch_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
- rsvg_state_reinherit_top (ctx, rsvg_node_get_state (self), dominate);
+ rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
rsvg_push_discrete_layer (ctx);
- rsvg_node_foreach_child (self, draw_child_if_cond_true_and_stop, ctx);
+ rsvg_node_foreach_child (node, draw_child_if_cond_true_and_stop, ctx);
rsvg_pop_discrete_layer (ctx);
}
RsvgNode *
-rsvg_new_switch (const char *element_name)
+rsvg_new_switch (const char *element_name, RsvgNode *parent)
{
RsvgNodeGroup *group;
- RsvgNodeVtable vtable = {
- NULL,
- _rsvg_node_switch_draw,
- NULL
- };
-
- group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_SWITCH, &vtable);
- return &group->super;
+ group = g_new0 (RsvgNodeGroup, 1);
+ return rsvg_rust_cnode_new (RSVG_NODE_TYPE_SWITCH,
+ parent,
+ rsvg_state_new (),
+ group,
+ rsvg_group_set_atts,
+ rsvg_node_switch_draw,
+ rsvg_group_free);
}
diff --git a/rsvg-structure.h b/rsvg-structure.h
index cfd0af4..50d012b 100644
--- a/rsvg-structure.h
+++ b/rsvg-structure.h
@@ -37,17 +37,17 @@
G_BEGIN_DECLS
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_use (const char *element_name);
+RsvgNode *rsvg_new_use (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_symbol (const char *element_name);
+RsvgNode *rsvg_new_symbol (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_svg (const char *element_name);
+RsvgNode *rsvg_new_svg (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_defs (const char *element_name);
+RsvgNode *rsvg_new_defs (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_group (const char *element_name);
+RsvgNode *rsvg_new_group (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_switch (const char *element_name);
+RsvgNode *rsvg_new_switch (const char *element_name, RsvgNode *parent);
typedef struct _RsvgNodeSvg RsvgNodeSvg;
@@ -60,21 +60,12 @@ struct _RsvgNodeSvg {
};
G_GNUC_INTERNAL
-void rsvg_node_add_child (RsvgNode * self, RsvgNode * child);
+void rsvg_node_draw_from_stack (RsvgNode *node, RsvgDrawingCtx * ctx, int dominate);
G_GNUC_INTERNAL
-void rsvg_node_draw_from_stack (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
-G_GNUC_INTERNAL
-void _rsvg_node_draw_children (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
-G_GNUC_INTERNAL
-void _rsvg_node_free (RsvgNode * self);
-
-G_GNUC_INTERNAL
-void _rsvg_node_init (RsvgNode * self,
- RsvgNodeType type,
- RsvgNodeVtable *vtable);
+void _rsvg_node_draw_children (RsvgNode *node, RsvgDrawingCtx * ctx, int dominate);
G_GNUC_INTERNAL
-void _rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx);
+void _rsvg_node_svg_apply_atts (RsvgNode *node, RsvgNodeSvg *svg, RsvgHandle * ctx);
G_END_DECLS
diff --git a/rust/src/cnode.rs b/rust/src/cnode.rs
index 7dd6bfd..2ad4a69 100644
--- a/rust/src/cnode.rs
+++ b/rust/src/cnode.rs
@@ -6,11 +6,6 @@ use state::RsvgState;
use std::rc::*;
-/* A *const RsvgCNodeImpl is just an opaque pointer to the C code's
- * struct for a particular node type.
- */
-pub enum RsvgCNodeImpl {}
-
type CNodeSetAtts = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, handle:
*const RsvgHandle, pbag: *const RsvgPropertyBag);
type CNodeDraw = unsafe extern "C" fn (node: *const RsvgNode, node_impl: *const RsvgCNodeImpl, draw_ctx:
*const RsvgDrawingCtx, dominate: i32);
type CNodeFree = unsafe extern "C" fn (node_impl: *const RsvgCNodeImpl);
@@ -31,6 +26,10 @@ impl NodeTrait for CNode {
fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
unsafe { (self.draw_fn) (node as *const RsvgNode, self.c_node_impl, draw_ctx, dominate); }
}
+
+ fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+ self.c_node_impl
+ }
}
impl Drop for CNode {
@@ -70,3 +69,11 @@ pub extern fn rsvg_rust_cnode_new (node_type: NodeType,
state,
Box::new (cnode)))))
}
+
+#[no_mangle]
+pub extern fn rsvg_rust_cnode_get_impl (raw_node: *const RsvgNode) -> *const RsvgCNodeImpl {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ node.get_c_impl ()
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 62c7f75..7ea6920 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -67,6 +67,7 @@ pub use node::{
pub use cnode::{
rsvg_rust_cnode_new,
+ rsvg_rust_cnode_get_impl
};
pub use viewbox::{
diff --git a/rust/src/node.rs b/rust/src/node.rs
index 64b8f1a..8946ef0 100644
--- a/rust/src/node.rs
+++ b/rust/src/node.rs
@@ -19,9 +19,15 @@ use state::RsvgState;
*/
pub type RsvgNode = Rc<Node>;
+/* A *const RsvgCNodeImpl is just an opaque pointer to the C code's
+ * struct for a particular node type.
+ */
+pub enum RsvgCNodeImpl {}
+
pub trait NodeTrait {
fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag);
fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32);
+ fn get_c_impl (&self) -> *const RsvgCNodeImpl;
}
pub struct Node {
@@ -114,6 +120,18 @@ impl Node {
pub fn add_child (&self, child: &Rc<Node>) {
self.children.borrow_mut ().push (child.clone ());
}
+
+ pub fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
+ self.node_impl.set_atts (node, handle, pbag);
+ }
+
+ pub fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+ self.node_impl.draw (node, draw_ctx, dominate);
+ }
+
+ pub fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+ self.node_impl.get_c_impl ()
+ }
}
extern "C" {
@@ -193,13 +211,13 @@ pub extern fn rsvg_node_draw (raw_node: *const RsvgNode, draw_ctx: *const RsvgDr
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)
+pub extern fn rsvg_node_foreach_child (raw_node: *const RsvgNode, func: 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) };
+ for child in node.children.borrow ().iter () {
+ let next = unsafe { func (child as *const RsvgNode, data) };
if !next {
break;
}
diff --git a/rust/src/shapes.rs b/rust/src/shapes.rs
index e3f0028..78b2ccd 100644
--- a/rust/src/shapes.rs
+++ b/rust/src/shapes.rs
@@ -1,4 +1,5 @@
use std::cell::RefCell;
+use std::ptr;
use drawing_ctx;
use drawing_ctx::*;
@@ -40,4 +41,9 @@ impl NodeTrait for NodePath {
drawing_ctx::state_reinherit_top (draw_ctx, self.state, dominate);
drawing_ctx::render_path_builder (draw_ctx, & *self.builder.borrow ());
}
+
+
+ fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+ ptr::null ()
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]