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.
parent 3f685fe1
......@@ -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;
......
This diff is collapsed.
......@@ -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);
......
......@@ -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;
}
......@@ -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;
}
......
......@@ -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;
}
......@@ -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;
......
......@@ -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
......
......@@ -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;
}
......@@ -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;
}
......@@ -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);
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment