[librsvg/rustification] Initialize the RsvgNode vtables in _rsvg_node_init()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] Initialize the RsvgNode vtables in _rsvg_node_init()
- Date: Fri, 2 Dec 2016 22:20:14 +0000 (UTC)
commit 126455c4ccb537b65e7aea8041efee2a9e977b76
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Dec 2 16:19:04 2016 -0600
Initialize the RsvgNode vtables in _rsvg_node_init()
Previously each node implementation would set its own vtable;
instead, we'll pass the vtable down to _rsvg_node_init(). This
will help in moving RsvgNode to Rust.
rsvg-base.c | 10 ++-
rsvg-filter.c | 273 +++++++++++++++++++++++++++++++++++----------------
rsvg-gobject.c | 4 +-
rsvg-image.c | 12 ++-
rsvg-marker.c | 10 ++-
rsvg-mask.c | 19 +++-
rsvg-paint-server.c | 43 ++++++--
rsvg-private.h | 10 ++-
rsvg-shapes.c | 68 +++++++++----
rsvg-structure.c | 97 ++++++++++++++-----
rsvg-structure.h | 6 +-
rsvg-text.c | 32 +++++--
12 files changed, 415 insertions(+), 169 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index b1500e5..61e0474 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -382,7 +382,7 @@ node_set_atts (RsvgNode * node, RsvgHandle * ctx, const NodeCreator *creator, Rs
const char *id;
const char *klazz;
- node->set_atts (node, ctx, atts);
+ node->vtable->set_atts (node, ctx, atts);
/* The "svg" node is special; it will load its id/class
* attributes until the end, when rsvg_end_element() calls
@@ -890,9 +890,14 @@ rsvg_new_node_chars (const char *text,
int len)
{
RsvgNodeChars *self;
+ RsvgNodeVtable vtable = {
+ _rsvg_node_chars_free,
+ NULL,
+ NULL
+ };
self = g_new (RsvgNodeChars, 1);
- _rsvg_node_init (&self->super, RSVG_NODE_TYPE_CHARS);
+ _rsvg_node_init (&self->super, RSVG_NODE_TYPE_CHARS, &vtable);
if (!g_utf8_validate (text, len, NULL)) {
char *utf8;
@@ -903,7 +908,6 @@ rsvg_new_node_chars (const char *text,
self->contents = g_string_new_len (text, len);
}
- self->super.free = _rsvg_node_chars_free;
self->super.state->cond_true = FALSE;
return self;
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 10df9c8..bc9d8c3 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -1,25 +1,25 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 sts=4 ts=4 expandtab: */
-/*
+/*
rsvg-filter.c: Provides filters
-
+
Copyright (C) 2004 Caleb Moore
-
+
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-
+
Author: Caleb Moore <c moore student unsw edu au>
*/
@@ -412,10 +412,10 @@ rsvg_alpha_blt (cairo_surface_t *src,
}
static gboolean
-rsvg_art_affine_image (cairo_surface_t *img,
+rsvg_art_affine_image (cairo_surface_t *img,
cairo_surface_t *intermediate,
- cairo_matrix_t *affine,
- double w,
+ cairo_matrix_t *affine,
+ double w,
double h)
{
cairo_matrix_t inv_affine, raw_inv_affine;
@@ -553,14 +553,14 @@ node_is_filter_primitive (RsvgNode *node)
* Create a new surface applied the filter. This function will create
* a context for itself, set up the coordinate systems execute all its
* little primatives and then clean up its own mess.
- *
+ *
* Returns: (transfer full): a new #cairo_surface_t
**/
cairo_surface_t *
rsvg_filter_render (RsvgFilter *self,
cairo_surface_t *source,
- RsvgDrawingCtx *context,
- RsvgBbox *bounds,
+ RsvgDrawingCtx *context,
+ RsvgBbox *bounds,
char *channelmap)
{
RsvgFilterContext *ctx;
@@ -658,7 +658,7 @@ surface_get_alpha (cairo_surface_t *source,
cairo_surface_flush (source);
- pbsize = cairo_image_surface_get_width (source) *
+ pbsize = cairo_image_surface_get_width (source) *
cairo_image_surface_get_height (source);
surface = _rsvg_image_surface_new (cairo_image_surface_get_width (source),
@@ -707,7 +707,7 @@ rsvg_compile_bg (RsvgDrawingCtx * ctx)
/**
* rsvg_filter_get_bg:
- *
+ *
* Returns: (transfer none) (nullable): a #cairo_surface_t, or %NULL
*/
static cairo_surface_t *
@@ -776,7 +776,7 @@ rsvg_filter_get_result (GString * name, RsvgFilterContext * ctx)
* rsvg_filter_get_in:
* @name:
* @ctx:
- *
+ *
* Returns: (transfer full) (nullable): a new #cairo_surface_t, or %NULL
*/
static cairo_surface_t *
@@ -824,16 +824,21 @@ RsvgNode *
rsvg_new_filter (const char *element_name)
{
RsvgFilter *filter;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_filter_set_atts,
+ };
filter = g_new (RsvgFilter, 1);
- _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER);
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER, &vtable);
+
filter->filterunits = objectBoundingBox;
filter->primitiveunits = userSpaceOnUse;
filter->x = rsvg_length_parse ("-10%", LENGTH_DIR_HORIZONTAL);
filter->y = rsvg_length_parse ("-10%", LENGTH_DIR_VERTICAL);
filter->width = rsvg_length_parse ("120%", LENGTH_DIR_HORIZONTAL);
filter->height = rsvg_length_parse ("120%", LENGTH_DIR_VERTICAL);
- filter->super.set_atts = rsvg_filter_set_atts;
return (RsvgNode *) filter;
}
@@ -854,11 +859,11 @@ struct _RsvgFilterPrimitiveBlend {
};
static void
-rsvg_filter_blend (RsvgFilterPrimitiveBlendMode mode,
- cairo_surface_t *in,
+rsvg_filter_blend (RsvgFilterPrimitiveBlendMode mode,
+ cairo_surface_t *in,
cairo_surface_t *in2,
- cairo_surface_t* output,
- RsvgIRect boundarys,
+ cairo_surface_t* output,
+ RsvgIRect boundarys,
int *channelmap)
{
guchar i;
@@ -1056,15 +1061,20 @@ RsvgNode *
rsvg_new_filter_primitive_blend (const char *element_name)
{
RsvgFilterPrimitiveBlend *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_blend_free,
+ NULL,
+ rsvg_filter_primitive_blend_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveBlend, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_BLEND);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_BLEND, &vtable);
+
filter->mode = normal;
filter->super.in = g_string_new ("none");
filter->in2 = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->super.render = rsvg_filter_primitive_blend_render;
- filter->super.super.free = rsvg_filter_primitive_blend_free;
- filter->super.super.set_atts = rsvg_filter_primitive_blend_set_atts;
return (RsvgNode *) filter;
}
@@ -1307,8 +1317,15 @@ RsvgNode *
rsvg_new_filter_primitive_convolve_matrix (const char *element_name)
{
RsvgFilterPrimitiveConvolveMatrix *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_convolve_matrix_free,
+ NULL,
+ rsvg_filter_primitive_convolve_matrix_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveConvolveMatrix, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_CONVOLVE_MATRIX);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_CONVOLVE_MATRIX, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->KernelMatrix = NULL;
@@ -1319,8 +1336,6 @@ rsvg_new_filter_primitive_convolve_matrix (const char *element_name)
filter->preservealpha = FALSE;
filter->edgemode = 0;
filter->super.render = rsvg_filter_primitive_convolve_matrix_render;
- filter->super.super.free = rsvg_filter_primitive_convolve_matrix_free;
- filter->super.super.set_atts = rsvg_filter_primitive_convolve_matrix_set_atts;
return (RsvgNode *) filter;
}
@@ -1432,7 +1447,7 @@ box_blur_line (gint box_width, gint even_offset,
} else if (output >= 0) {
/* If the output is on the image, but the trailing edge isn't yet
* on the image. */
-
+
for (i = 0; i < bpp; i++) {
ac[i] += src[bpp * lead + i];
dest[bpp * output + i] = (ac[i] + (coverage >> 1)) / coverage;
@@ -1712,7 +1727,7 @@ gaussian_blur_surface (cairo_surface_t *in,
guchar *in_data, *out_data;
gint bpp;
gboolean out_has_data;
-
+
cairo_surface_flush (in);
width = cairo_image_surface_get_width (in);
@@ -1953,15 +1968,20 @@ RsvgNode *
rsvg_new_filter_primitive_gaussian_blur (const char *element_name)
{
RsvgFilterPrimitiveGaussianBlur *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_gaussian_blur_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveGaussianBlur, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_GAUSSIAN_BLUR);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_GAUSSIAN_BLUR, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->sdx = 0;
filter->sdy = 0;
filter->super.render = rsvg_filter_primitive_gaussian_blur_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_gaussian_blur_set_atts;
return (RsvgNode *) filter;
}
@@ -2073,15 +2093,20 @@ RsvgNode *
rsvg_new_filter_primitive_offset (const char *element_name)
{
RsvgFilterPrimitiveOffset *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_offset_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveOffset, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->dx = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
filter->dy = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
filter->super.render = rsvg_filter_primitive_offset_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_offset_set_atts;
return (RsvgNode *) filter;
}
@@ -2160,13 +2185,18 @@ RsvgNode *
rsvg_new_filter_primitive_merge (const char *element_name)
{
RsvgFilterPrimitiveMerge *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_merge_free,
+ NULL,
+ rsvg_filter_primitive_merge_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveMerge, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE, &vtable);
+
filter->super.result = g_string_new ("none");
filter->super.render = rsvg_filter_primitive_merge_render;
- filter->super.super.free = rsvg_filter_primitive_merge_free;
- filter->super.super.set_atts = rsvg_filter_primitive_merge_set_atts;
return (RsvgNode *) filter;
}
@@ -2202,12 +2232,17 @@ RsvgNode *
rsvg_new_filter_primitive_merge_node (const char *element_name)
{
RsvgFilterPrimitive *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_merge_node_free,
+ NULL,
+ rsvg_filter_primitive_merge_node_set_atts
+ };
+
filter = g_new (RsvgFilterPrimitive, 1);
- _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE);
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE, &vtable);
+
filter->in = g_string_new ("none");
- filter->super.free = rsvg_filter_primitive_merge_node_free;
filter->render = rsvg_filter_primitive_merge_node_render;
- filter->super.set_atts = rsvg_filter_primitive_merge_node_set_atts;
return (RsvgNode *) filter;
}
@@ -2324,7 +2359,7 @@ rsvg_filter_primitive_color_matrix_free (RsvgNode * self)
matrix = (RsvgFilterPrimitiveColorMatrix *) self;
g_free (matrix->KernelMatrix);
-
+
rsvg_filter_primitive_free (self);
}
@@ -2436,15 +2471,20 @@ RsvgNode *
rsvg_new_filter_primitive_color_matrix (const char *element_name)
{
RsvgFilterPrimitiveColorMatrix *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_color_matrix_free,
+ NULL,
+ rsvg_filter_primitive_color_matrix_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveColorMatrix, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COLOR_MATRIX);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COLOR_MATRIX, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->KernelMatrix = NULL;
filter->super.render = rsvg_filter_primitive_color_matrix_render;
- filter->super.super.free = rsvg_filter_primitive_color_matrix_free;
- filter->super.super.set_atts = rsvg_filter_primitive_color_matrix_set_atts;
return (RsvgNode *) filter;
}
@@ -2658,14 +2698,19 @@ RsvgNode *
rsvg_new_filter_primitive_component_transfer (const char *element_name)
{
RsvgFilterPrimitiveComponentTransfer *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_component_transfer_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveComponentTransfer, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER, &vtable);
+
filter->super.result = g_string_new ("none");
filter->super.in = g_string_new ("none");
filter->super.render = rsvg_filter_primitive_component_transfer_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_component_transfer_set_atts;
return (RsvgNode *) filter;
}
@@ -2715,7 +2760,7 @@ rsvg_node_component_transfer_function_set_atts (RsvgNode * self,
}
static void
-rsvg_component_transfer_function_free (RsvgNode * self)
+rsvg_node_component_transfer_function_free (RsvgNode * self)
{
RsvgNodeComponentTransferFunc *filter = (RsvgNodeComponentTransferFunc *) self;
if (filter->nbTableValues)
@@ -2727,6 +2772,12 @@ RsvgNode *
rsvg_new_node_component_transfer_function (const char *element_name)
{
RsvgNodeComponentTransferFunc *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_node_component_transfer_function_free,
+ NULL,
+ rsvg_node_component_transfer_function_set_atts
+ };
+
char channel;
if (strcmp (element_name, "feFuncR") == 0)
@@ -2743,9 +2794,8 @@ rsvg_new_node_component_transfer_function (const char *element_name)
}
filter = g_new0 (RsvgNodeComponentTransferFunc, 1);
- _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION);
- filter->super.free = rsvg_component_transfer_function_free;
- filter->super.set_atts = rsvg_node_component_transfer_function_set_atts;
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION, &vtable);
+
filter->function = identity_component_transfer_func;
filter->nbTableValues = 0;
filter->channel = channel;
@@ -2876,16 +2926,21 @@ RsvgNode *
rsvg_new_filter_primitive_erode (const char *element_name)
{
RsvgFilterPrimitiveErode *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_erode_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveErode, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_ERODE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_ERODE, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->rx = 0;
filter->ry = 0;
filter->mode = 0;
filter->super.render = rsvg_filter_primitive_erode_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_erode_set_atts;
return (RsvgNode *) filter;
}
@@ -3107,8 +3162,15 @@ RsvgNode *
rsvg_new_filter_primitive_composite (const char *element_name)
{
RsvgFilterPrimitiveComposite *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_composite_free,
+ NULL,
+ rsvg_filter_primitive_composite_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveComposite, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPOSITE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPOSITE, &vtable);
+
filter->mode = COMPOSITE_MODE_OVER;
filter->super.in = g_string_new ("none");
filter->in2 = g_string_new ("none");
@@ -3118,8 +3180,6 @@ rsvg_new_filter_primitive_composite (const char *element_name)
filter->k3 = 0;
filter->k4 = 0;
filter->super.render = rsvg_filter_primitive_composite_render;
- filter->super.super.free = rsvg_filter_primitive_composite_free;
- filter->super.super.set_atts = rsvg_filter_primitive_composite_set_atts;
return (RsvgNode *) filter;
}
@@ -3189,13 +3249,18 @@ RsvgNode *
rsvg_new_filter_primitive_flood (const char *element_name)
{
RsvgFilterPrimitive *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_flood_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitive, 1);
- _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_FLOOD);
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_FLOOD, &vtable);
+
filter->in = g_string_new ("none");
filter->result = g_string_new ("none");
filter->render = rsvg_filter_primitive_flood_render;
- filter->super.free = rsvg_filter_primitive_free;
- filter->super.set_atts = rsvg_filter_primitive_flood_set_atts;
return (RsvgNode *) filter;
}
@@ -3359,7 +3424,7 @@ rsvg_filter_primitive_displacement_map_set_atts (RsvgNode * self, RsvgHandle * c
g_string_assign (filter->super.result, value);
filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
-
+
if ((value = rsvg_property_bag_lookup (atts, "xChannelSelector")))
filter->xChannelSelector = (value)[0];
if ((value = rsvg_property_bag_lookup (atts, "yChannelSelector")))
@@ -3372,8 +3437,15 @@ RsvgNode *
rsvg_new_filter_primitive_displacement_map (const char *element_name)
{
RsvgFilterPrimitiveDisplacementMap *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_displacement_map_free,
+ NULL,
+ rsvg_filter_primitive_displacement_map_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveDisplacementMap, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DISPLACEMENT_MAP);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DISPLACEMENT_MAP, &vtable);
+
filter->super.in = g_string_new ("none");
filter->in2 = g_string_new ("none");
filter->super.result = g_string_new ("none");
@@ -3381,8 +3453,6 @@ rsvg_new_filter_primitive_displacement_map (const char *element_name)
filter->yChannelSelector = ' ';
filter->scale = 0;
filter->super.render = rsvg_filter_primitive_displacement_map_render;
- filter->super.super.free = rsvg_filter_primitive_displacement_map_free;
- filter->super.super.set_atts = rsvg_filter_primitive_displacement_map_set_atts;
return (RsvgNode *) filter;
}
@@ -3717,7 +3787,7 @@ rsvg_filter_primitive_turbulence_set_atts (RsvgNode * self, RsvgHandle * ctx,
g_string_assign (filter->super.result, value);
filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
-
+
if ((value = rsvg_property_bag_lookup (atts, "baseFrequency")))
rsvg_css_parse_number_optional_number (value, &filter->fBaseFreqX, &filter->fBaseFreqY);
if ((value = rsvg_property_bag_lookup (atts, "numOctaves")))
@@ -3734,8 +3804,15 @@ RsvgNode *
rsvg_new_filter_primitive_turbulence (const char *element_name)
{
RsvgFilterPrimitiveTurbulence *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_turbulence_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveTurbulence, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TURBULENCE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TURBULENCE, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->fBaseFreqX = 0;
@@ -3746,8 +3823,6 @@ rsvg_new_filter_primitive_turbulence (const char *element_name)
filter->bFractalSum = 0;
feTurbulence_init (filter);
filter->super.render = rsvg_filter_primitive_turbulence_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_turbulence_set_atts;
return (RsvgNode *) filter;
}
@@ -3834,7 +3909,7 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, RsvgFilterCo
cairo_surface_destroy (img);
- length = cairo_image_surface_get_height (intermediate) *
+ length = cairo_image_surface_get_height (intermediate) *
cairo_image_surface_get_stride (intermediate);
for (i = 0; i < 4; i++)
channelmap[i] = ctx->channelmap[i];
@@ -3951,13 +4026,18 @@ RsvgNode *
rsvg_new_filter_primitive_image (const char *element_name)
{
RsvgFilterPrimitiveImage *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_image_free,
+ NULL,
+ rsvg_filter_primitive_image_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveImage, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_IMAGE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_IMAGE, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->super.render = rsvg_filter_primitive_image_render;
- filter->super.super.free = rsvg_filter_primitive_image_free;
- filter->super.super.set_atts = rsvg_filter_primitive_image_set_atts;
filter->href = NULL;
return (RsvgNode *) filter;
}
@@ -4346,11 +4426,15 @@ RsvgNode *
rsvg_new_node_light_source (const char *element_name)
{
RsvgNodeLightSource *data;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_node_light_source_set_atts
+ };
data = g_new (RsvgNodeLightSource, 1);
- _rsvg_node_init (&data->super, RSVG_NODE_TYPE_LIGHT_SOURCE);
- data->super.free = _rsvg_node_free;
- data->super.set_atts = rsvg_node_light_source_set_atts;
+ _rsvg_node_init (&data->super, RSVG_NODE_TYPE_LIGHT_SOURCE, &vtable);
+
data->specularExponent = 1;
if (strcmp (element_name, "feDistantLight") == 0)
@@ -4501,7 +4585,7 @@ rsvg_filter_primitive_diffuse_lighting_set_atts (RsvgNode * self, RsvgHandle * c
g_string_assign (filter->super.result, value);
filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
-
+
if ((value = rsvg_property_bag_lookup (atts, "kernelUnitLength")))
rsvg_css_parse_number_optional_number (value, &filter->dx, &filter->dy);
if ((value = rsvg_property_bag_lookup (atts, "lighting-color")))
@@ -4516,8 +4600,15 @@ RsvgNode *
rsvg_new_filter_primitive_diffuse_lighting (const char *element_name)
{
RsvgFilterPrimitiveDiffuseLighting *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_diffuse_lighting_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveDiffuseLighting, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DIFFUSE_LIGHTING);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DIFFUSE_LIGHTING, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->surfaceScale = 1;
@@ -4526,8 +4617,6 @@ rsvg_new_filter_primitive_diffuse_lighting (const char *element_name)
filter->dy = 1;
filter->lightingcolor = 0xFFFFFFFF;
filter->super.render = rsvg_filter_primitive_diffuse_lighting_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_diffuse_lighting_set_atts;
return (RsvgNode *) filter;
}
@@ -4669,7 +4758,7 @@ rsvg_filter_primitive_specular_lighting_set_atts (RsvgNode * self, RsvgHandle *
g_string_assign (filter->super.result, value);
filter_primitive_set_x_y_width_height_atts ((RsvgFilterPrimitive *) filter, atts);
-
+
if ((value = rsvg_property_bag_lookup (atts, "lighting-color")))
filter->lightingcolor = rsvg_css_parse_color (value, 0);
if ((value = rsvg_property_bag_lookup (atts, "specularConstant")))
@@ -4685,8 +4774,15 @@ RsvgNode *
rsvg_new_filter_primitive_specular_lighting (const char *element_name)
{
RsvgFilterPrimitiveSpecularLighting *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_specular_lighting_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveSpecularLighting, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_SPECULAR_LIGHTING);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_SPECULAR_LIGHTING, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->surfaceScale = 1;
@@ -4694,8 +4790,6 @@ rsvg_new_filter_primitive_specular_lighting (const char *element_name)
filter->specularExponent = 1;
filter->lightingcolor = 0xFFFFFFFF;
filter->super.render = rsvg_filter_primitive_specular_lighting_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_specular_lighting_set_atts;
return (RsvgNode *) filter;
}
@@ -4789,12 +4883,17 @@ RsvgNode *
rsvg_new_filter_primitive_tile (const char *element_name)
{
RsvgFilterPrimitiveTile *filter;
+ RsvgNodeVtable vtable = {
+ rsvg_filter_primitive_free,
+ NULL,
+ rsvg_filter_primitive_tile_set_atts
+ };
+
filter = g_new0 (RsvgFilterPrimitiveTile, 1);
- _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TILE);
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TILE, &vtable);
+
filter->super.in = g_string_new ("none");
filter->super.result = g_string_new ("none");
filter->super.render = rsvg_filter_primitive_tile_render;
- filter->super.super.free = rsvg_filter_primitive_free;
- filter->super.super.set_atts = rsvg_filter_primitive_tile_set_atts;
return (RsvgNode *) filter;
}
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 65f11d0..d0a965d 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -106,8 +106,8 @@ free_nodes (RsvgHandle *self)
RsvgNode *node;
node = g_ptr_array_index (self->priv->all_nodes, i);
- g_assert (node->free != NULL);
- node->free (node);
+ g_assert (node->vtable->free != NULL);
+ node->vtable->free (node);
}
g_ptr_array_free (self->priv->all_nodes, TRUE);
diff --git a/rsvg-image.c b/rsvg-image.c
index 2692a6b..77e3b18 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -231,14 +231,18 @@ RsvgNode *
rsvg_new_image (const char *element_name)
{
RsvgNodeImage *image;
+ RsvgNodeVtable vtable = {
+ rsvg_node_image_free,
+ rsvg_node_image_draw,
+ rsvg_node_image_set_atts
+ };
+
image = g_new (RsvgNodeImage, 1);
- _rsvg_node_init (&image->super, RSVG_NODE_TYPE_IMAGE);
+ _rsvg_node_init (&image->super, RSVG_NODE_TYPE_IMAGE, &vtable);
+
g_assert (image->super.state);
image->surface = NULL;
image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
image->x = image->y = image->w = image->h = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
- image->super.free = rsvg_node_image_free;
- image->super.draw = rsvg_node_image_draw;
- image->super.set_atts = rsvg_node_image_set_atts;
return &image->super;
}
diff --git a/rsvg-marker.c b/rsvg-marker.c
index 180db73..8e44f02 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -90,8 +90,15 @@ RsvgNode *
rsvg_new_marker (const char *element_name)
{
RsvgMarker *marker;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_node_marker_set_atts
+ };
+
marker = g_new (RsvgMarker, 1);
- _rsvg_node_init (&marker->super, RSVG_NODE_TYPE_MARKER);
+ _rsvg_node_init (&marker->super, RSVG_NODE_TYPE_MARKER, &vtable);
+
marker->orient = 0;
marker->orientAuto = FALSE;
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
@@ -99,7 +106,6 @@ rsvg_new_marker (const char *element_name)
marker->width = marker->height = rsvg_length_parse ("3", LENGTH_DIR_BOTH);
marker->bbox = TRUE;
marker->vbox.active = FALSE;
- marker->super.set_atts = rsvg_node_marker_set_atts;
return &marker->super;
}
diff --git a/rsvg-mask.c b/rsvg-mask.c
index d145cd6..d167f94 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -63,16 +63,21 @@ RsvgNode *
rsvg_new_mask (const char *element_name)
{
RsvgMask *mask;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_mask_set_atts
+ };
mask = g_new (RsvgMask, 1);
- _rsvg_node_init (&mask->super, RSVG_NODE_TYPE_MASK);
+ _rsvg_node_init (&mask->super, RSVG_NODE_TYPE_MASK, &vtable);
+
mask->maskunits = objectBoundingBox;
mask->contentunits = userSpaceOnUse;
mask->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
mask->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
mask->width = rsvg_length_parse ("1", LENGTH_DIR_HORIZONTAL);
mask->height = rsvg_length_parse ("1", LENGTH_DIR_VERTICAL);
- mask->super.set_atts = rsvg_mask_set_atts;
return &mask->super;
}
@@ -113,11 +118,15 @@ RsvgNode *
rsvg_new_clip_path (const char *element_name)
{
RsvgClipPath *clip_path;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_clip_path_set_atts
+ };
clip_path = g_new (RsvgClipPath, 1);
- _rsvg_node_init (&clip_path->super, RSVG_NODE_TYPE_CLIP_PATH);
+ _rsvg_node_init (&clip_path->super, RSVG_NODE_TYPE_CLIP_PATH, &vtable);
+
clip_path->units = userSpaceOnUse;
- clip_path->super.set_atts = rsvg_clip_path_set_atts;
- clip_path->super.free = _rsvg_node_free;
return &clip_path->super;
}
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index bfc7f87..4c801f6 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -225,8 +225,14 @@ RsvgNode *
rsvg_new_stop (const char *element_name)
{
RsvgGradientStop *stop = g_new (RsvgGradientStop, 1);
- _rsvg_node_init (&stop->super, RSVG_NODE_TYPE_STOP);
- stop->super.set_atts = rsvg_stop_set_atts;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ rsvg_stop_set_atts
+ };
+
+ _rsvg_node_init (&stop->super, RSVG_NODE_TYPE_STOP, &vtable);
+
stop->offset = 0;
stop->rgba = 0xff000000;
stop->is_valid = FALSE;
@@ -292,8 +298,15 @@ RsvgNode *
rsvg_new_linear_gradient (const char *element_name)
{
RsvgLinearGradient *grad = NULL;
+ RsvgNodeVtable vtable = {
+ rsvg_linear_gradient_free,
+ NULL,
+ rsvg_linear_gradient_set_atts
+ };
+
grad = g_new (RsvgLinearGradient, 1);
- _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_LINEAR_GRADIENT);
+ _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_LINEAR_GRADIENT, &vtable);
+
cairo_matrix_init_identity (&grad->affine);
grad->x1 = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
grad->y1 = grad->y2 = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
@@ -301,8 +314,6 @@ rsvg_new_linear_gradient (const char *element_name)
grad->fallback = NULL;
grad->obj_bbox = TRUE;
grad->spread = CAIRO_EXTEND_PAD;
- grad->super.free = rsvg_linear_gradient_free;
- grad->super.set_atts = rsvg_linear_gradient_set_atts;
grad->hasx1 = grad->hasy1 = grad->hasx2 = grad->hasy2 = grad->hasbbox = grad->hasspread =
grad->hastransform = FALSE;
return &grad->super;
@@ -374,15 +385,20 @@ RsvgNode *
rsvg_new_radial_gradient (const char *element_name)
{
+ RsvgNodeVtable vtable = {
+ rsvg_radial_gradient_free,
+ NULL,
+ rsvg_radial_gradient_set_atts
+ };
+
RsvgRadialGradient *grad = g_new (RsvgRadialGradient, 1);
- _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_RADIAL_GRADIENT);
+ _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_RADIAL_GRADIENT, &vtable);
+
cairo_matrix_init_identity (&grad->affine);
grad->obj_bbox = TRUE;
grad->spread = CAIRO_EXTEND_PAD;
grad->fallback = NULL;
grad->cx = grad->cy = grad->r = grad->fx = grad->fy = rsvg_length_parse ("0.5", LENGTH_DIR_BOTH);
- grad->super.free = rsvg_radial_gradient_free;
- grad->super.set_atts = rsvg_radial_gradient_set_atts;
grad->hascx = grad->hascy = grad->hasfx = grad->hasfy = grad->hasr = grad->hasbbox =
grad->hasspread = grad->hastransform = FALSE;
return &grad->super;
@@ -453,7 +469,14 @@ RsvgNode *
rsvg_new_pattern (const char *element_name)
{
RsvgPattern *pattern = g_new (RsvgPattern, 1);
- _rsvg_node_init (&pattern->super, RSVG_NODE_TYPE_PATTERN);
+ RsvgNodeVtable vtable = {
+ rsvg_pattern_free,
+ NULL,
+ rsvg_pattern_set_atts
+ };
+
+ _rsvg_node_init (&pattern->super, RSVG_NODE_TYPE_PATTERN, &vtable);
+
cairo_matrix_init_identity (&pattern->affine);
pattern->obj_bbox = TRUE;
pattern->obj_cbbox = FALSE;
@@ -461,8 +484,6 @@ rsvg_new_pattern (const char *element_name)
pattern->fallback = NULL;
pattern->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
pattern->vbox.active = FALSE;
- pattern->super.free = rsvg_pattern_free;
- pattern->super.set_atts = rsvg_pattern_set_atts;
pattern->hasx = pattern->hasy = pattern->haswidth = pattern->hasheight = pattern->hasbbox =
pattern->hascbox = pattern->hasvbox = pattern->hasaspect = pattern->hastransform = FALSE;
return &pattern->super;
diff --git a/rsvg-private.h b/rsvg-private.h
index 4bc3a48..3dffc3b 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -329,14 +329,18 @@ 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;
+
struct _RsvgNode {
RsvgState *state;
RsvgNode *parent;
GPtrArray *children;
RsvgNodeType type;
- void (*free) (RsvgNode * self);
- void (*draw) (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
- void (*set_atts) (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *);
+ RsvgNodeVtable *vtable;
};
G_GNUC_INTERNAL
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index e7f407c..31bb1c7 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -87,12 +87,16 @@ RsvgNode *
rsvg_new_path (const char *element_name)
{
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);
+ _rsvg_node_init (&path->super, RSVG_NODE_TYPE_PATH, &vtable);
+
path->builder = NULL;
- path->super.free = rsvg_node_path_free;
- path->super.draw = rsvg_node_path_draw;
- path->super.set_atts = rsvg_node_path_set_atts;
return &path->super;
}
@@ -197,11 +201,15 @@ static RsvgNode *
rsvg_new_any_poly (RsvgNodeType type)
{
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);
- poly->super.free = _rsvg_node_poly_free;
- poly->super.draw = _rsvg_node_poly_draw;
- poly->super.set_atts = _rsvg_node_poly_set_atts;
+ _rsvg_node_init (&poly->super, type, &vtable);
+
poly->builder = NULL;
return &poly->super;
}
@@ -270,10 +278,15 @@ RsvgNode *
rsvg_new_line (const char *element_name)
{
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);
- line->super.draw = _rsvg_node_line_draw;
- line->super.set_atts = _rsvg_node_line_set_atts;
+ _rsvg_node_init (&line->super, RSVG_NODE_TYPE_LINE, &vtable);
+
line->x1 = line->x2 = line->y1 = line->y2 = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &line->super;
}
@@ -454,10 +467,15 @@ RsvgNode *
rsvg_new_rect (const char *element_name)
{
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);
- rect->super.draw = _rsvg_node_rect_draw;
- rect->super.set_atts = _rsvg_node_rect_set_atts;
+ _rsvg_node_init (&rect->super, RSVG_NODE_TYPE_RECT, &vtable);
+
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;
@@ -537,10 +555,15 @@ RsvgNode *
rsvg_new_circle (const char *element_name)
{
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);
- circle->super.draw = _rsvg_node_circle_draw;
- circle->super.set_atts = _rsvg_node_circle_set_atts;
+ _rsvg_node_init (&circle->super, RSVG_NODE_TYPE_CIRCLE, &vtable);
+
circle->cx = circle->cy = circle->r = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &circle->super;
}
@@ -622,10 +645,15 @@ RsvgNode *
rsvg_new_ellipse (const char *element_name)
{
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);
- ellipse->super.draw = _rsvg_node_ellipse_draw;
- ellipse->super.set_atts = _rsvg_node_ellipse_set_atts;
+ _rsvg_node_init (&ellipse->super, RSVG_NODE_TYPE_ELLIPSE, &vtable);
+
ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &ellipse->super;
}
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 0152202..0d8af08 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -53,7 +53,7 @@ rsvg_node_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
if (state->visible) {
rsvg_state_push (ctx);
- self->draw (self, ctx, dominate);
+ self->vtable->draw (self, ctx, dominate);
rsvg_state_pop (ctx);
}
@@ -102,15 +102,32 @@ _rsvg_node_dont_set_atts (RsvgNode * node, RsvgHandle * ctx, RsvgPropertyBag * a
void
_rsvg_node_init (RsvgNode * self,
- RsvgNodeType type)
+ RsvgNodeType type,
+ RsvgNodeVtable *vtable)
{
self->type = type;
self->parent = NULL;
self->children = g_ptr_array_new ();
self->state = rsvg_state_new ();
- self->free = _rsvg_node_free;
- self->draw = _rsvg_node_draw_nothing;
- self->set_atts = _rsvg_node_dont_set_atts;
+ 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;
+ }
+
+ if (vtable->set_atts) {
+ self->vtable->set_atts = vtable->set_atts;
+ } else {
+ self->vtable->set_atts = _rsvg_node_dont_set_atts;
+ }
}
void
@@ -128,6 +145,9 @@ _rsvg_node_free (RsvgNode * self)
self->parent = NULL;
self->type = RSVG_NODE_TYPE_INVALID;
+ g_free (self->vtable);
+ self->vtable = NULL;
+
g_free (self);
}
@@ -135,9 +155,15 @@ RsvgNode *
rsvg_new_group (const char *element_name)
{
RsvgNodeGroup *group;
+ RsvgNodeVtable vtable = {
+ NULL,
+ _rsvg_node_draw_children,
+ NULL
+ };
+
group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_GROUP);
- group->super.draw = _rsvg_node_draw_children;
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_GROUP, &vtable);
+
return &group->super;
}
@@ -344,7 +370,7 @@ _rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx)
}
static void
-_rsvg_svg_free (RsvgNode * self)
+rsvg_node_svg_free (RsvgNode * self)
{
RsvgNodeSvg *svg = (RsvgNodeSvg *) self;
@@ -360,17 +386,21 @@ RsvgNode *
rsvg_new_svg (const char *element_name)
{
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);
+ _rsvg_node_init (&svg->super, RSVG_NODE_TYPE_SVG, &vtable);
+
svg->vbox.active = FALSE;
svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
svg->x = rsvg_length_parse ("0", LENGTH_DIR_HORIZONTAL);
svg->y = rsvg_length_parse ("0", LENGTH_DIR_VERTICAL);
svg->w = rsvg_length_parse ("100%", LENGTH_DIR_HORIZONTAL);
svg->h = rsvg_length_parse ("100%", LENGTH_DIR_VERTICAL);
- svg->super.draw = rsvg_node_svg_draw;
- svg->super.free = _rsvg_svg_free;
- svg->super.set_atts = rsvg_node_svg_set_atts;
svg->atts = NULL;
return &svg->super;
}
@@ -410,11 +440,15 @@ RsvgNode *
rsvg_new_use (const char *element_name)
{
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);
- use->super.draw = rsvg_node_use_draw;
- use->super.free = rsvg_node_use_free;
- use->super.set_atts = rsvg_node_use_set_atts;
+ _rsvg_node_init (&use->super, RSVG_NODE_TYPE_USE, &vtable);
+
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);
@@ -440,12 +474,17 @@ RsvgNode *
rsvg_new_symbol (const char *element_name)
{
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);
+ _rsvg_node_init (&symbol->super, RSVG_NODE_TYPE_SYMBOL, &vtable);
+
symbol->vbox.active = FALSE;
symbol->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- symbol->super.draw = _rsvg_node_draw_nothing;
- symbol->super.set_atts = rsvg_node_symbol_set_atts;
return &symbol->super;
}
@@ -453,9 +492,15 @@ RsvgNode *
rsvg_new_defs (const char *element_name)
{
RsvgNodeGroup *group;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ NULL,
+ };
+
group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_DEFS);
- group->super.draw = _rsvg_node_draw_nothing;
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_DEFS, &vtable);
+
return &group->super;
}
@@ -491,8 +536,14 @@ RsvgNode *
rsvg_new_switch (const char *element_name)
{
RsvgNodeGroup *group;
+ RsvgNodeVtable vtable = {
+ NULL,
+ _rsvg_node_switch_draw,
+ NULL
+ };
+
group = g_new (RsvgNodeGroup, 1);
- _rsvg_node_init (&group->super, RSVG_NODE_TYPE_SWITCH);
- group->super.draw = _rsvg_node_switch_draw;
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_SWITCH, &vtable);
+
return &group->super;
}
diff --git a/rsvg-structure.h b/rsvg-structure.h
index cd75176..03d4694 100644
--- a/rsvg-structure.h
+++ b/rsvg-structure.h
@@ -86,8 +86,12 @@ 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);
+void _rsvg_node_init (RsvgNode * self,
+ RsvgNodeType type,
+ RsvgNodeVtable *vtable);
+
G_GNUC_INTERNAL
void _rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx);
diff --git a/rsvg-text.c b/rsvg-text.c
index 50ab02b..0090386 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -383,10 +383,15 @@ RsvgNode *
rsvg_new_text (const char *element_name)
{
RsvgNodeText *text;
+ RsvgNodeVtable vtable = {
+ NULL,
+ _rsvg_node_text_draw,
+ _rsvg_node_text_set_atts
+ };
+
text = g_new (RsvgNodeText, 1);
- _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TEXT);
- text->super.draw = _rsvg_node_text_draw;
- text->super.set_atts = _rsvg_node_text_set_atts;
+ _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TEXT, &vtable);
+
text->x = text->y = text->dx = text->dy = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &text->super;
}
@@ -466,9 +471,15 @@ RsvgNode *
rsvg_new_tspan (const char *element_name)
{
RsvgNodeText *text;
+ RsvgNodeVtable vtable = {
+ NULL,
+ NULL,
+ _rsvg_node_tspan_set_atts
+ };
+
text = g_new0 (RsvgNodeText, 1);
- _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TSPAN);
- text->super.set_atts = _rsvg_node_tspan_set_atts;
+ _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TSPAN, &vtable);
+
text->dx = text->dy = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
return &text->super;
}
@@ -536,10 +547,15 @@ RsvgNode *
rsvg_new_tref (const char *element_name)
{
RsvgNodeTref *text;
+ RsvgNodeVtable vtable = {
+ rsvg_node_tref_free,
+ NULL,
+ _rsvg_node_tref_set_atts
+ };
+
text = g_new (RsvgNodeTref, 1);
- _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TREF);
- text->super.free = rsvg_node_tref_free;
- text->super.set_atts = _rsvg_node_tref_set_atts;
+ _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TREF, &vtable);
+
text->link = NULL;
return &text->super;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]