1089 lines
44 KiB
Diff
1089 lines
44 KiB
Diff
librsvg: CVE-2011-3146
|
|
|
|
Store node type separately in RsvgNode
|
|
|
|
commit 34c95743ca692ea0e44778e41a7c0a129363de84 upstream
|
|
|
|
The node name (formerly RsvgNode:type) cannot be used to infer
|
|
the sub-type of RsvgNode that we're dealing with, since for unknown
|
|
elements we put type = node-name. This lead to a (potentially exploitable)
|
|
crash e.g. when the element name started with "fe" which tricked
|
|
the old code into considering it as a RsvgFilterPrimitive.
|
|
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-3146
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=658014
|
|
---
|
|
rsvg-base.c | 68 ++++++++++++++++++++++++++------------------
|
|
rsvg-cairo-draw.c | 2 +-
|
|
rsvg-filter.c | 79 +++++++++++++++++++++++++++------------------------
|
|
rsvg-filter.h | 2 +-
|
|
rsvg-image.c | 2 +-
|
|
rsvg-marker.c | 4 +-
|
|
rsvg-mask.c | 8 ++--
|
|
rsvg-paint-server.c | 25 ++++++++--------
|
|
rsvg-private.h | 60 ++++++++++++++++++++++++++++++++++++++-
|
|
rsvg-shapes.c | 25 ++++++++--------
|
|
rsvg-shapes.h | 2 +-
|
|
rsvg-structure.c | 25 ++++++++--------
|
|
rsvg-structure.h | 5 ++-
|
|
rsvg-text.c | 22 ++++++++------
|
|
14 files changed, 204 insertions(+), 125 deletions(-)
|
|
|
|
diff --git a/rsvg-base.c b/rsvg-base.c
|
|
index 1f5c48c..b1a2d8b 100644
|
|
--- a/rsvg-base.c
|
|
+++ b/rsvg-base.c
|
|
@@ -147,7 +147,6 @@ rsvg_start_style (RsvgHandle * ctx, RsvgPropertyBag * atts)
|
|
static void
|
|
rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag * atts)
|
|
{
|
|
-
|
|
/*replace this stuff with a hash for fast reading! */
|
|
RsvgNode *newnode = NULL;
|
|
if (!strcmp (name, "g"))
|
|
@@ -241,11 +240,11 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
|
|
else if (!strcmp (name, "feFuncA"))
|
|
newnode = rsvg_new_node_component_transfer_function ('a');
|
|
else if (!strcmp (name, "feDistantLight"))
|
|
- newnode = rsvg_new_filter_primitive_light_source ('d');
|
|
+ newnode = rsvg_new_node_light_source ('d');
|
|
else if (!strcmp (name, "feSpotLight"))
|
|
- newnode = rsvg_new_filter_primitive_light_source ('s');
|
|
+ newnode = rsvg_new_node_light_source ('s');
|
|
else if (!strcmp (name, "fePointLight"))
|
|
- newnode = rsvg_new_filter_primitive_light_source ('p');
|
|
+ newnode = rsvg_new_node_light_source ('p');
|
|
/* hack to make multiImage sort-of work */
|
|
else if (!strcmp (name, "multiImage"))
|
|
newnode = rsvg_new_switch ();
|
|
@@ -259,21 +258,22 @@ rsvg_standard_element_start (RsvgHandle * ctx, const char *name, RsvgPropertyBag
|
|
newnode = rsvg_new_tspan ();
|
|
else if (!strcmp (name, "tref"))
|
|
newnode = rsvg_new_tref ();
|
|
- else {
|
|
+ else {
|
|
/* hack for bug 401115. whenever we encounter a node we don't understand, push it into a group.
|
|
this will allow us to handle things like conditionals properly. */
|
|
newnode = rsvg_new_group ();
|
|
}
|
|
|
|
if (newnode) {
|
|
- newnode->type = g_string_new (name);
|
|
+ g_assert (RSVG_NODE_TYPE (newnode) != RSVG_NODE_TYPE_INVALID);
|
|
+ newnode->name = (char *) name; /* libxml will keep this while parsing */
|
|
newnode->parent = ctx->priv->currentnode;
|
|
rsvg_node_set_atts (newnode, ctx, atts);
|
|
rsvg_defs_register_memory (ctx->priv->defs, newnode);
|
|
if (ctx->priv->currentnode) {
|
|
rsvg_node_group_pack (ctx->priv->currentnode, newnode);
|
|
ctx->priv->currentnode = newnode;
|
|
- } else if (!strcmp (name, "svg")) {
|
|
+ } else if (RSVG_NODE_TYPE (newnode) == RSVG_NODE_TYPE_SVG) {
|
|
ctx->priv->treebase = newnode;
|
|
ctx->priv->currentnode = newnode;
|
|
}
|
|
@@ -689,10 +689,11 @@ rsvg_end_element (void *data, const xmlChar * name)
|
|
ctx->priv->handler = NULL;
|
|
}
|
|
|
|
- if (ctx->priv->currentnode
|
|
- && !strcmp ((const char *) name, ctx->priv->currentnode->type->str))
|
|
- rsvg_pop_def_group (ctx);
|
|
+ if (ctx->priv->currentnode &&
|
|
+ !strcmp ((const char *) name, ctx->priv->currentnode->name))
|
|
+ rsvg_pop_def_group (ctx);
|
|
|
|
+ /* FIXMEchpe: shouldn't this check that currentnode == treebase or sth like that? */
|
|
if (ctx->priv->treebase && !strcmp ((const char *)name, "svg"))
|
|
_rsvg_node_svg_apply_atts ((RsvgNodeSvg *)ctx->priv->treebase, ctx);
|
|
}
|
|
@@ -706,6 +707,30 @@ _rsvg_node_chars_free (RsvgNode * node)
|
|
_rsvg_node_free (node);
|
|
}
|
|
|
|
+static RsvgNodeChars *
|
|
+rsvg_new_node_chars (const char *text,
|
|
+ int len)
|
|
+{
|
|
+ RsvgNodeChars *self;
|
|
+
|
|
+ self = g_new (RsvgNodeChars, 1);
|
|
+ _rsvg_node_init (&self->super, RSVG_NODE_TYPE_CHARS);
|
|
+
|
|
+ if (!g_utf8_validate (text, len, NULL)) {
|
|
+ char *utf8;
|
|
+ utf8 = rsvg_make_valid_utf8 (text, len);
|
|
+ self->contents = g_string_new (utf8);
|
|
+ g_free (utf8);
|
|
+ } else {
|
|
+ self->contents = g_string_new_len (text, len);
|
|
+ }
|
|
+
|
|
+ self->super.free = _rsvg_node_chars_free;
|
|
+ self->super.state->cond_true = FALSE;
|
|
+
|
|
+ return self;
|
|
+}
|
|
+
|
|
static void
|
|
rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
|
|
{
|
|
@@ -715,8 +740,9 @@ rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
|
|
return;
|
|
|
|
if (ctx->priv->currentnode) {
|
|
- if (!strcmp ("tspan", ctx->priv->currentnode->type->str) ||
|
|
- !strcmp ("text", ctx->priv->currentnode->type->str)) {
|
|
+ RsvgNodeType type = RSVG_NODE_TYPE (ctx->priv->currentnode);
|
|
+ if (type == RSVG_NODE_TYPE_TSPAN ||
|
|
+ type == RSVG_NODE_TYPE_TEXT) {
|
|
guint i;
|
|
|
|
/* find the last CHARS node in the text or tspan node, so that we
|
|
@@ -724,7 +750,7 @@ rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
|
|
self = NULL;
|
|
for (i = 0; i < ctx->priv->currentnode->children->len; i++) {
|
|
RsvgNode *node = g_ptr_array_index (ctx->priv->currentnode->children, i);
|
|
- if (!strcmp (node->type->str, "RSVG_NODE_CHARS")) {
|
|
+ if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_CHARS) {
|
|
self = (RsvgNodeChars*)node;
|
|
}
|
|
}
|
|
@@ -744,21 +770,7 @@ rsvg_characters_impl (RsvgHandle * ctx, const xmlChar * ch, int len)
|
|
}
|
|
}
|
|
|
|
- self = g_new (RsvgNodeChars, 1);
|
|
- _rsvg_node_init (&self->super);
|
|
-
|
|
- if (!g_utf8_validate ((char *) ch, len, NULL)) {
|
|
- char *utf8;
|
|
- utf8 = rsvg_make_valid_utf8 ((char *) ch, len);
|
|
- self->contents = g_string_new (utf8);
|
|
- g_free (utf8);
|
|
- } else {
|
|
- self->contents = g_string_new_len ((char *) ch, len);
|
|
- }
|
|
-
|
|
- self->super.type = g_string_new ("RSVG_NODE_CHARS");
|
|
- self->super.free = _rsvg_node_chars_free;
|
|
- self->super.state->cond_true = FALSE;
|
|
+ self = rsvg_new_node_chars ((char *) ch, len);
|
|
|
|
rsvg_defs_register_memory (ctx->priv->defs, (RsvgNode *) self);
|
|
if (ctx->priv->currentnode)
|
|
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
|
|
index 0b74e22..c01cd17 100644
|
|
--- a/rsvg-cairo-draw.c
|
|
+++ b/rsvg-cairo-draw.c
|
|
@@ -147,7 +147,7 @@ _pattern_add_rsvg_color_stops (cairo_pattern_t * pattern,
|
|
|
|
for (i = 0; i < stops->len; i++) {
|
|
node = (RsvgNode *) g_ptr_array_index (stops, i);
|
|
- if (strcmp (node->type->str, "stop"))
|
|
+ if (RSVG_NODE_TYPE (node) != RSVG_NODE_TYPE_STOP)
|
|
continue;
|
|
stop = (RsvgGradientStop *) node;
|
|
rgba = stop->rgba;
|
|
diff --git a/rsvg-filter.c b/rsvg-filter.c
|
|
index e65be41..ce96c4f 100644
|
|
--- a/rsvg-filter.c
|
|
+++ b/rsvg-filter.c
|
|
@@ -495,7 +495,7 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source,
|
|
|
|
for (i = 0; i < self->super.children->len; i++) {
|
|
current = g_ptr_array_index (self->super.children, i);
|
|
- if (!strncmp (current->super.type->str, "fe", 2))
|
|
+ if (RSVG_NODE_IS_FILTER_PRIMITIVE (¤t->super))
|
|
rsvg_filter_primitive_render (current, ctx);
|
|
}
|
|
|
|
@@ -703,7 +703,7 @@ rsvg_filter_parse (const RsvgDefs * defs, const char *str)
|
|
val = rsvg_defs_lookup (defs, name);
|
|
g_free (name);
|
|
|
|
- if (val && (!strcmp (val->type->str, "filter")))
|
|
+ if (val && RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_FILTER)
|
|
return (RsvgFilter *) val;
|
|
}
|
|
return NULL;
|
|
@@ -754,7 +754,7 @@ rsvg_new_filter (void)
|
|
RsvgFilter *filter;
|
|
|
|
filter = g_new (RsvgFilter, 1);
|
|
- _rsvg_node_init (&filter->super);
|
|
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER);
|
|
filter->filterunits = objectBoundingBox;
|
|
filter->primitiveunits = userSpaceOnUse;
|
|
filter->x = _rsvg_css_parse_length ("-10%");
|
|
@@ -978,7 +978,7 @@ rsvg_new_filter_primitive_blend (void)
|
|
{
|
|
RsvgFilterPrimitiveBlend *filter;
|
|
filter = g_new (RsvgFilterPrimitiveBlend, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_BLEND);
|
|
filter->mode = normal;
|
|
filter->super.in = g_string_new ("none");
|
|
filter->in2 = g_string_new ("none");
|
|
@@ -1230,7 +1230,7 @@ rsvg_new_filter_primitive_convolve_matrix (void)
|
|
{
|
|
RsvgFilterPrimitiveConvolveMatrix *filter;
|
|
filter = g_new (RsvgFilterPrimitiveConvolveMatrix, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_CONVOLVE_MATRIX);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -1471,7 +1471,7 @@ rsvg_new_filter_primitive_gaussian_blur (void)
|
|
{
|
|
RsvgFilterPrimitiveGaussianBlur *filter;
|
|
filter = g_new (RsvgFilterPrimitiveGaussianBlur, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_GAUSSIAN_BLUR);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -1607,7 +1607,7 @@ rsvg_new_filter_primitive_offset (void)
|
|
{
|
|
RsvgFilterPrimitiveOffset *filter;
|
|
filter = g_new (RsvgFilterPrimitiveOffset, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -1648,7 +1648,7 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self, RsvgFilterContex
|
|
for (i = 0; i < upself->super.super.children->len; i++) {
|
|
RsvgFilterPrimitive *mn;
|
|
mn = g_ptr_array_index (upself->super.super.children, i);
|
|
- if (strcmp (mn->super.type->str, "feMergeNode"))
|
|
+ if (RSVG_NODE_TYPE (&mn->super) != RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE)
|
|
continue;
|
|
in = rsvg_filter_get_in (mn->in, ctx);
|
|
rsvg_alpha_blt (in, boundarys.x0, boundarys.y0, boundarys.x1 - boundarys.x0,
|
|
@@ -1701,7 +1701,7 @@ rsvg_new_filter_primitive_merge (void)
|
|
{
|
|
RsvgFilterPrimitiveMerge *filter;
|
|
filter = g_new (RsvgFilterPrimitiveMerge, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE);
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
filter->super.height.factor = 'n';
|
|
@@ -1744,7 +1744,7 @@ rsvg_new_filter_primitive_merge_node (void)
|
|
{
|
|
RsvgFilterPrimitive *filter;
|
|
filter = g_new (RsvgFilterPrimitive, 1);
|
|
- _rsvg_node_init (&filter->super);
|
|
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE);
|
|
filter->in = g_string_new ("none");
|
|
filter->super.free = rsvg_filter_primitive_merge_node_free;
|
|
filter->render = &rsvg_filter_primitive_merge_node_render;
|
|
@@ -1978,7 +1978,7 @@ rsvg_new_filter_primitive_colour_matrix (void)
|
|
{
|
|
RsvgFilterPrimitiveColourMatrix *filter;
|
|
filter = g_new (RsvgFilterPrimitiveColourMatrix, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COLOUR_MATRIX);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -2010,8 +2010,9 @@ struct _RsvgNodeComponentTransferFunc {
|
|
gint slope;
|
|
gint intercept;
|
|
gint amplitude;
|
|
- gdouble exponent;
|
|
gint offset;
|
|
+ gdouble exponent;
|
|
+ char channel;
|
|
};
|
|
|
|
struct _RsvgFilterPrimitiveComponentTransfer {
|
|
@@ -2107,15 +2108,18 @@ rsvg_filter_primitive_component_transfer_render (RsvgFilterPrimitive *
|
|
for (c = 0; c < 4; c++) {
|
|
char channel = "RGBA"[c];
|
|
for (i = 0; i < self->super.children->len; i++) {
|
|
- RsvgNodeComponentTransferFunc *temp;
|
|
- temp = (RsvgNodeComponentTransferFunc *)
|
|
- g_ptr_array_index (self->super.children, i);
|
|
- if (!strncmp (temp->super.type->str, "feFunc", 6))
|
|
- if (temp->super.type->str[6] == channel) {
|
|
+ RsvgNode *child_node;
|
|
+
|
|
+ child_node = (RsvgNode *) g_ptr_array_index (self->super.children, i);
|
|
+ if (RSVG_NODE_TYPE (child_node) == RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER) {
|
|
+ RsvgNodeComponentTransferFunc *temp = (RsvgNodeComponentTransferFunc *) child_node;
|
|
+
|
|
+ if (temp->channel == channel) {
|
|
functions[ctx->channelmap[c]] = temp->function;
|
|
channels[ctx->channelmap[c]] = temp;
|
|
break;
|
|
}
|
|
+ }
|
|
}
|
|
if (i == self->super.children->len)
|
|
functions[ctx->channelmap[c]] = identity_component_transfer_func;
|
|
@@ -2198,7 +2202,7 @@ rsvg_new_filter_primitive_component_transfer (void)
|
|
RsvgFilterPrimitiveComponentTransfer *filter;
|
|
|
|
filter = g_new (RsvgFilterPrimitiveComponentTransfer, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER);
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -2272,7 +2276,7 @@ rsvg_new_node_component_transfer_function (char channel)
|
|
RsvgNodeComponentTransferFunc *filter;
|
|
|
|
filter = g_new (RsvgNodeComponentTransferFunc, 1);
|
|
- _rsvg_node_init (&filter->super);
|
|
+ _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;
|
|
filter->function = identity_component_transfer_func;
|
|
@@ -2414,7 +2418,7 @@ rsvg_new_filter_primitive_erode (void)
|
|
{
|
|
RsvgFilterPrimitiveErode *filter;
|
|
filter = g_new (RsvgFilterPrimitiveErode, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_ERODE);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -2639,7 +2643,7 @@ rsvg_new_filter_primitive_composite (void)
|
|
{
|
|
RsvgFilterPrimitiveComposite *filter;
|
|
filter = g_new (RsvgFilterPrimitiveComposite, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPOSITE);
|
|
filter->mode = COMPOSITE_MODE_OVER;
|
|
filter->super.in = g_string_new ("none");
|
|
filter->in2 = g_string_new ("none");
|
|
@@ -2744,7 +2748,7 @@ rsvg_new_filter_primitive_flood (void)
|
|
{
|
|
RsvgFilterPrimitive *filter;
|
|
filter = g_new (RsvgFilterPrimitive, 1);
|
|
- _rsvg_node_init (&filter->super);
|
|
+ _rsvg_node_init (&filter->super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_FLOOD);
|
|
filter->in = g_string_new ("none");
|
|
filter->result = g_string_new ("none");
|
|
filter->x.factor = filter->y.factor = filter->width.factor = filter->height.factor = 'n';
|
|
@@ -2920,7 +2924,7 @@ rsvg_new_filter_primitive_displacement_map (void)
|
|
{
|
|
RsvgFilterPrimitiveDisplacementMap *filter;
|
|
filter = g_new (RsvgFilterPrimitiveDisplacementMap, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DISPLACEMENT_MAP);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->in2 = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
@@ -3291,7 +3295,7 @@ rsvg_new_filter_primitive_turbulence (void)
|
|
{
|
|
RsvgFilterPrimitiveTurbulence *filter;
|
|
filter = g_new (RsvgFilterPrimitiveTurbulence, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TURBULENCE);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -3510,7 +3514,7 @@ rsvg_new_filter_primitive_image (void)
|
|
{
|
|
RsvgFilterPrimitiveImage *filter;
|
|
filter = g_new (RsvgFilterPrimitiveImage, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_IMAGE);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -3871,8 +3875,8 @@ get_light_colour (RsvgNodeLightSource * source, vector3 colour,
|
|
|
|
|
|
static void
|
|
-rsvg_filter_primitive_light_source_set_atts (RsvgNode * self,
|
|
- RsvgHandle * ctx, RsvgPropertyBag * atts)
|
|
+rsvg_node_light_source_set_atts (RsvgNode * self,
|
|
+ RsvgHandle * ctx, RsvgPropertyBag * atts)
|
|
{
|
|
RsvgNodeLightSource *data;
|
|
const char *value;
|
|
@@ -3904,13 +3908,13 @@ rsvg_filter_primitive_light_source_set_atts (RsvgNode * self,
|
|
}
|
|
|
|
RsvgNode *
|
|
-rsvg_new_filter_primitive_light_source (char type)
|
|
+rsvg_new_node_light_source (char type)
|
|
{
|
|
RsvgNodeLightSource *data;
|
|
data = g_new (RsvgNodeLightSource, 1);
|
|
- _rsvg_node_init (&data->super);
|
|
+ _rsvg_node_init (&data->super, RSVG_NODE_TYPE_LIGHT_SOURCE);
|
|
data->super.free = _rsvg_node_free;
|
|
- data->super.set_atts = rsvg_filter_primitive_light_source_set_atts;
|
|
+ data->super.set_atts = rsvg_node_light_source_set_atts;
|
|
data->specularExponent = 1;
|
|
if (type == 's')
|
|
data->type = SPOTLIGHT;
|
|
@@ -3960,10 +3964,11 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self, RsvgF
|
|
|
|
for (i = 0; i < self->super.children->len; i++) {
|
|
RsvgNode *temp;
|
|
+
|
|
temp = g_ptr_array_index (self->super.children, i);
|
|
- if (!strcmp (temp->type->str, "feDistantLight") ||
|
|
- !strcmp (temp->type->str, "fePointLight") || !strcmp (temp->type->str, "feSpotLight"))
|
|
+ if (RSVG_NODE_TYPE (temp) == RSVG_NODE_TYPE_LIGHT_SOURCE) {
|
|
source = (RsvgNodeLightSource *) temp;
|
|
+ }
|
|
}
|
|
if (source == NULL)
|
|
return;
|
|
@@ -4080,7 +4085,7 @@ rsvg_new_filter_primitive_diffuse_lighting (void)
|
|
{
|
|
RsvgFilterPrimitiveDiffuseLighting *filter;
|
|
filter = g_new (RsvgFilterPrimitiveDiffuseLighting, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_DIFFUSE_LIGHTING);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -4135,9 +4140,9 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self, Rsvg
|
|
for (i = 0; i < self->super.children->len; i++) {
|
|
RsvgNode *temp;
|
|
temp = g_ptr_array_index (self->super.children, i);
|
|
- if (!strcmp (temp->type->str, "feDistantLight") ||
|
|
- !strcmp (temp->type->str, "fePointLight") || !strcmp (temp->type->str, "feSpotLight"))
|
|
+ if (RSVG_NODE_TYPE (temp) == RSVG_NODE_TYPE_LIGHT_SOURCE) {
|
|
source = (RsvgNodeLightSource *) temp;
|
|
+ }
|
|
}
|
|
if (source == NULL)
|
|
return;
|
|
@@ -4259,7 +4264,7 @@ rsvg_new_filter_primitive_specular_lighting (void)
|
|
{
|
|
RsvgFilterPrimitiveSpecularLighting *filter;
|
|
filter = g_new (RsvgFilterPrimitiveSpecularLighting, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_SPECULAR_LIGHTING);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
@@ -4381,7 +4386,7 @@ rsvg_new_filter_primitive_tile (void)
|
|
{
|
|
RsvgFilterPrimitiveTile *filter;
|
|
filter = g_new (RsvgFilterPrimitiveTile, 1);
|
|
- _rsvg_node_init (&filter->super.super);
|
|
+ _rsvg_node_init (&filter->super.super, RSVG_NODE_TYPE_FILTER_PRIMITIVE_TILE);
|
|
filter->super.in = g_string_new ("none");
|
|
filter->super.result = g_string_new ("none");
|
|
filter->super.x.factor = filter->super.y.factor = filter->super.width.factor =
|
|
diff --git a/rsvg-filter.h b/rsvg-filter.h
|
|
index 25dac75..0aeda22 100644
|
|
--- a/rsvg-filter.h
|
|
+++ b/rsvg-filter.h
|
|
@@ -64,7 +64,7 @@ RsvgNode *rsvg_new_filter_primitive_displacement_map (void);
|
|
RsvgNode *rsvg_new_filter_primitive_turbulence (void);
|
|
RsvgNode *rsvg_new_filter_primitive_image (void);
|
|
RsvgNode *rsvg_new_filter_primitive_diffuse_lighting (void);
|
|
-RsvgNode *rsvg_new_filter_primitive_light_source (char type);
|
|
+RsvgNode *rsvg_new_node_light_source (char type);
|
|
RsvgNode *rsvg_new_filter_primitive_specular_lighting (void);
|
|
RsvgNode *rsvg_new_filter_primitive_tile (void);
|
|
|
|
diff --git a/rsvg-image.c b/rsvg-image.c
|
|
index a81dcf5..02882bd 100644
|
|
--- a/rsvg-image.c
|
|
+++ b/rsvg-image.c
|
|
@@ -356,7 +356,7 @@ rsvg_new_image (void)
|
|
{
|
|
RsvgNodeImage *image;
|
|
image = g_new (RsvgNodeImage, 1);
|
|
- _rsvg_node_init (&image->super);
|
|
+ _rsvg_node_init (&image->super, RSVG_NODE_TYPE_IMAGE);
|
|
g_assert (image->super.state);
|
|
image->img = NULL;
|
|
image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
|
|
diff --git a/rsvg-marker.c b/rsvg-marker.c
|
|
index 591e1e0..c7e76f1 100644
|
|
--- a/rsvg-marker.c
|
|
+++ b/rsvg-marker.c
|
|
@@ -84,7 +84,7 @@ rsvg_new_marker (void)
|
|
{
|
|
RsvgMarker *marker;
|
|
marker = g_new (RsvgMarker, 1);
|
|
- _rsvg_node_init (&marker->super);
|
|
+ _rsvg_node_init (&marker->super, RSVG_NODE_TYPE_MARKER);
|
|
marker->orient = 0;
|
|
marker->orientAuto = FALSE;
|
|
marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
|
|
@@ -198,7 +198,7 @@ rsvg_marker_parse (const RsvgDefs * defs, const char *str)
|
|
val = rsvg_defs_lookup (defs, name);
|
|
g_free (name);
|
|
|
|
- if (val && (!strcmp (val->type->str, "marker")))
|
|
+ if (val && RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_MARKER)
|
|
return val;
|
|
}
|
|
return NULL;
|
|
diff --git a/rsvg-mask.c b/rsvg-mask.c
|
|
index dd36a38..8e3cba3 100644
|
|
--- a/rsvg-mask.c
|
|
+++ b/rsvg-mask.c
|
|
@@ -74,7 +74,7 @@ rsvg_new_mask (void)
|
|
RsvgMask *mask;
|
|
|
|
mask = g_new (RsvgMask, 1);
|
|
- _rsvg_node_init (&mask->super);
|
|
+ _rsvg_node_init (&mask->super, RSVG_NODE_TYPE_MASK);
|
|
mask->maskunits = objectBoundingBox;
|
|
mask->contentunits = userSpaceOnUse;
|
|
mask->x = _rsvg_css_parse_length ("0");
|
|
@@ -113,7 +113,7 @@ rsvg_mask_parse (const RsvgDefs * defs, const char *str)
|
|
val = rsvg_defs_lookup (defs, name);
|
|
g_free (name);
|
|
|
|
- if (val && (!strcmp (val->type->str, "mask")))
|
|
+ if (val && RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_MASK)
|
|
return val;
|
|
}
|
|
return NULL;
|
|
@@ -130,7 +130,7 @@ rsvg_clip_path_parse (const RsvgDefs * defs, const char *str)
|
|
val = rsvg_defs_lookup (defs, name);
|
|
g_free (name);
|
|
|
|
- if (val && (!strcmp (val->type->str, "clipPath")))
|
|
+ if (val && RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_CLIP_PATH)
|
|
return val;
|
|
}
|
|
return NULL;
|
|
@@ -168,7 +168,7 @@ rsvg_new_clip_path (void)
|
|
RsvgClipPath *clip_path;
|
|
|
|
clip_path = g_new (RsvgClipPath, 1);
|
|
- _rsvg_node_init (&clip_path->super);
|
|
+ _rsvg_node_init (&clip_path->super, RSVG_NODE_TYPE_CLIP_PATH);
|
|
clip_path->units = userSpaceOnUse;
|
|
clip_path->super.set_atts = rsvg_clip_path_set_atts;
|
|
clip_path->super.free = _rsvg_node_free;
|
|
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
|
|
index 4967e03..7903684 100644
|
|
--- a/rsvg-paint-server.c
|
|
+++ b/rsvg-paint-server.c
|
|
@@ -129,11 +129,11 @@ rsvg_paint_server_parse (gboolean * inherit, const RsvgDefs * defs, const char *
|
|
|
|
if (val == NULL)
|
|
return NULL;
|
|
- if (!strcmp (val->type->str, "linearGradient"))
|
|
+ if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_LINEAR_GRADIENT)
|
|
return rsvg_paint_server_lin_grad ((RsvgLinearGradient *) val);
|
|
- else if (!strcmp (val->type->str, "radialGradient"))
|
|
+ else if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_RADIAL_GRADIENT)
|
|
return rsvg_paint_server_rad_grad ((RsvgRadialGradient *) val);
|
|
- else if (!strcmp (val->type->str, "pattern"))
|
|
+ else if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_PATTERN)
|
|
return rsvg_paint_server_pattern ((RsvgPattern *) val);
|
|
else
|
|
return NULL;
|
|
@@ -224,7 +224,7 @@ RsvgNode *
|
|
rsvg_new_stop (void)
|
|
{
|
|
RsvgGradientStop *stop = g_new (RsvgGradientStop, 1);
|
|
- _rsvg_node_init (&stop->super);
|
|
+ _rsvg_node_init (&stop->super, RSVG_NODE_TYPE_STOP);
|
|
stop->super.set_atts = rsvg_stop_set_atts;
|
|
stop->offset = 0;
|
|
stop->rgba = 0;
|
|
@@ -293,7 +293,7 @@ rsvg_new_linear_gradient (void)
|
|
{
|
|
RsvgLinearGradient *grad = NULL;
|
|
grad = g_new (RsvgLinearGradient, 1);
|
|
- _rsvg_node_init (&grad->super);
|
|
+ _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_LINEAR_GRADIENT);
|
|
_rsvg_affine_identity (grad->affine);
|
|
grad->has_current_color = FALSE;
|
|
grad->x1 = grad->y1 = grad->y2 = _rsvg_css_parse_length ("0");
|
|
@@ -376,7 +376,7 @@ rsvg_new_radial_gradient (void)
|
|
{
|
|
|
|
RsvgRadialGradient *grad = g_new (RsvgRadialGradient, 1);
|
|
- _rsvg_node_init (&grad->super);
|
|
+ _rsvg_node_init (&grad->super, RSVG_NODE_TYPE_RADIAL_GRADIENT);
|
|
_rsvg_affine_identity (grad->affine);
|
|
grad->has_current_color = FALSE;
|
|
grad->obj_bbox = TRUE;
|
|
@@ -458,7 +458,7 @@ RsvgNode *
|
|
rsvg_new_pattern (void)
|
|
{
|
|
RsvgPattern *pattern = g_new (RsvgPattern, 1);
|
|
- _rsvg_node_init (&pattern->super);
|
|
+ _rsvg_node_init (&pattern->super, RSVG_NODE_TYPE_PATTERN);
|
|
pattern->obj_bbox = TRUE;
|
|
pattern->obj_cbbox = FALSE;
|
|
pattern->x = pattern->y = pattern->width = pattern->height = _rsvg_css_parse_length ("0");
|
|
@@ -477,7 +477,8 @@ hasstop (GPtrArray * lookin)
|
|
{
|
|
unsigned int i;
|
|
for (i = 0; i < lookin->len; i++) {
|
|
- if (!strcmp (((RsvgNode *) g_ptr_array_index (lookin, i))->type->str, "stop"))
|
|
+ RsvgNode *node = g_ptr_array_index (lookin, i);
|
|
+ if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_STOP)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
@@ -490,7 +491,7 @@ rsvg_linear_gradient_fix_fallback (RsvgLinearGradient * grad)
|
|
int i;
|
|
ufallback = grad->fallback;
|
|
while (ufallback != NULL) {
|
|
- if (!strcmp (ufallback->type->str, "linearGradient")) {
|
|
+ if (RSVG_NODE_TYPE (ufallback) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
|
|
RsvgLinearGradient *fallback = (RsvgLinearGradient *) ufallback;
|
|
if (!grad->hasx1 && fallback->hasx1) {
|
|
grad->hasx1 = TRUE;
|
|
@@ -525,7 +526,7 @@ rsvg_linear_gradient_fix_fallback (RsvgLinearGradient * grad)
|
|
grad->super.children = fallback->super.children;
|
|
}
|
|
ufallback = fallback->fallback;
|
|
- } else if (!strcmp (ufallback->type->str, "radialGradient")) {
|
|
+ } else if (RSVG_NODE_TYPE (ufallback) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
|
|
RsvgRadialGradient *fallback = (RsvgRadialGradient *) ufallback;
|
|
if (!grad->hastransform && fallback->hastransform) {
|
|
grad->hastransform = TRUE;
|
|
@@ -555,7 +556,7 @@ rsvg_radial_gradient_fix_fallback (RsvgRadialGradient * grad)
|
|
int i;
|
|
ufallback = grad->fallback;
|
|
while (ufallback != NULL) {
|
|
- if (!strcmp (ufallback->type->str, "radialGradient")) {
|
|
+ if (RSVG_NODE_TYPE (ufallback) == RSVG_NODE_TYPE_RADIAL_GRADIENT) {
|
|
RsvgRadialGradient *fallback = (RsvgRadialGradient *) ufallback;
|
|
if (!grad->hascx && fallback->hascx) {
|
|
grad->hascx = TRUE;
|
|
@@ -594,7 +595,7 @@ rsvg_radial_gradient_fix_fallback (RsvgRadialGradient * grad)
|
|
grad->super.children = fallback->super.children;
|
|
}
|
|
ufallback = fallback->fallback;
|
|
- } else if (!strcmp (ufallback->type->str, "linearGradient")) {
|
|
+ } else if (RSVG_NODE_TYPE (ufallback) == RSVG_NODE_TYPE_LINEAR_GRADIENT) {
|
|
RsvgLinearGradient *fallback = (RsvgLinearGradient *) ufallback;
|
|
if (!grad->hastransform && fallback->hastransform) {
|
|
grad->hastransform = TRUE;
|
|
diff --git a/rsvg-private.h b/rsvg-private.h
|
|
index 288c2de..162917a 100644
|
|
--- a/rsvg-private.h
|
|
+++ b/rsvg-private.h
|
|
@@ -255,16 +255,74 @@ struct RsvgSizeCallbackData {
|
|
|
|
void _rsvg_size_callback (int *width, int *height, gpointer data);
|
|
|
|
+typedef enum {
|
|
+ RSVG_NODE_TYPE_INVALID = 0,
|
|
+
|
|
+ RSVG_NODE_TYPE_CHARS,
|
|
+ RSVG_NODE_TYPE_CIRCLE,
|
|
+ RSVG_NODE_TYPE_CLIP_PATH,
|
|
+ RSVG_NODE_TYPE_COMPONENT_TRANFER_FUNCTION,
|
|
+ RSVG_NODE_TYPE_DEFS,
|
|
+ RSVG_NODE_TYPE_ELLIPSE,
|
|
+ RSVG_NODE_TYPE_FILTER,
|
|
+ RSVG_NODE_TYPE_GROUP,
|
|
+ RSVG_NODE_TYPE_IMAGE,
|
|
+ RSVG_NODE_TYPE_LIGHT_SOURCE,
|
|
+ RSVG_NODE_TYPE_LINE,
|
|
+ RSVG_NODE_TYPE_LINEAR_GRADIENT,
|
|
+ RSVG_NODE_TYPE_MARKER,
|
|
+ RSVG_NODE_TYPE_MASK,
|
|
+ RSVG_NODE_TYPE_PATH,
|
|
+ RSVG_NODE_TYPE_PATTERN,
|
|
+ RSVG_NODE_TYPE_POLYGON,
|
|
+ RSVG_NODE_TYPE_POLYLINE,
|
|
+ RSVG_NODE_TYPE_RADIAL_GRADIENT,
|
|
+ RSVG_NODE_TYPE_RECT,
|
|
+ RSVG_NODE_TYPE_STOP,
|
|
+ RSVG_NODE_TYPE_SVG,
|
|
+ RSVG_NODE_TYPE_SWITCH,
|
|
+ RSVG_NODE_TYPE_SYMBOL,
|
|
+ RSVG_NODE_TYPE_TEXT,
|
|
+ RSVG_NODE_TYPE_TREF,
|
|
+ RSVG_NODE_TYPE_TSPAN,
|
|
+ RSVG_NODE_TYPE_USE,
|
|
+
|
|
+ /* Filter primitives */
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE = 64,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_BLEND,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_COLOUR_MATRIX,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPONENT_TRANSFER,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_COMPOSITE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_CONVOLVE_MATRIX,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_DIFFUSE_LIGHTING,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_DISPLACEMENT_MAP,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_ERODE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_FLOOD,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_GAUSSIAN_BLUR,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_IMAGE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_MERGE_NODE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_OFFSET,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_SPECULAR_LIGHTING,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_TILE,
|
|
+ RSVG_NODE_TYPE_FILTER_PRIMITIVE_TURBULENCE,
|
|
+
|
|
+} RsvgNodeType;
|
|
+
|
|
struct _RsvgNode {
|
|
RsvgState *state;
|
|
RsvgNode *parent;
|
|
- GString *type;
|
|
GPtrArray *children;
|
|
+ RsvgNodeType type;
|
|
+ const char *name; /* owned by the xmlContext, invalid after parsing! */
|
|
void (*free) (RsvgNode * self);
|
|
void (*draw) (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
|
|
void (*set_atts) (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *);
|
|
};
|
|
|
|
+#define RSVG_NODE_TYPE(node) ((node)->type)
|
|
+#define RSVG_NODE_IS_FILTER_PRIMITIVE(node) (RSVG_NODE_TYPE((node)) & RSVG_NODE_TYPE_FILTER_PRIMITIVE)
|
|
+
|
|
struct _RsvgNodeChars {
|
|
RsvgNode super;
|
|
GString *contents;
|
|
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
|
|
index d481abf..07baf24 100644
|
|
--- a/rsvg-shapes.c
|
|
+++ b/rsvg-shapes.c
|
|
@@ -89,7 +89,7 @@ rsvg_new_path (void)
|
|
{
|
|
RsvgNodePath *path;
|
|
path = g_new (RsvgNodePath, 1);
|
|
- _rsvg_node_init (&path->super);
|
|
+ _rsvg_node_init (&path->super, RSVG_NODE_TYPE_PATH);
|
|
path->d = NULL;
|
|
path->super.free = rsvg_node_path_free;
|
|
path->super.draw = rsvg_node_path_draw;
|
|
@@ -101,7 +101,6 @@ rsvg_new_path (void)
|
|
struct _RsvgNodePoly {
|
|
RsvgNode super;
|
|
gdouble *pointlist;
|
|
- gboolean is_polyline;
|
|
guint pointlist_len;
|
|
};
|
|
|
|
@@ -126,7 +125,8 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
|
|
rsvg_defs_register_name (ctx->priv->defs, value, self);
|
|
}
|
|
|
|
- rsvg_parse_style_attrs (ctx, self->state, (poly->is_polyline ? "polyline" : "polygon"),
|
|
+ rsvg_parse_style_attrs (ctx, self->state,
|
|
+ RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYLINE ? "polyline" : "polygon",
|
|
klazz, id, atts);
|
|
}
|
|
|
|
@@ -160,7 +160,7 @@ _rsvg_node_poly_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
|
|
g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), poly->pointlist[i + 1]));
|
|
}
|
|
|
|
- if (!poly->is_polyline)
|
|
+ if (RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYGON)
|
|
g_string_append (d, " Z");
|
|
|
|
rsvg_state_reinherit_top (ctx, self->state, dominate);
|
|
@@ -181,16 +181,15 @@ _rsvg_node_poly_free (RsvgNode * self)
|
|
|
|
|
|
static RsvgNode *
|
|
-rsvg_new_any_poly (gboolean is_polyline)
|
|
+rsvg_new_any_poly (RsvgNodeType type)
|
|
{
|
|
RsvgNodePoly *poly;
|
|
poly = g_new (RsvgNodePoly, 1);
|
|
- _rsvg_node_init (&poly->super);
|
|
+ _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;
|
|
poly->pointlist = NULL;
|
|
- poly->is_polyline = is_polyline;
|
|
poly->pointlist_len = 0;
|
|
return &poly->super;
|
|
}
|
|
@@ -198,13 +197,13 @@ rsvg_new_any_poly (gboolean is_polyline)
|
|
RsvgNode *
|
|
rsvg_new_polygon (void)
|
|
{
|
|
- return rsvg_new_any_poly (FALSE);
|
|
+ return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYGON);
|
|
}
|
|
|
|
RsvgNode *
|
|
rsvg_new_polyline (void)
|
|
{
|
|
- return rsvg_new_any_poly (TRUE);
|
|
+ return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYLINE);
|
|
}
|
|
|
|
|
|
@@ -275,7 +274,7 @@ rsvg_new_line (void)
|
|
{
|
|
RsvgNodeLine *line;
|
|
line = g_new (RsvgNodeLine, 1);
|
|
- _rsvg_node_init (&line->super);
|
|
+ _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;
|
|
line->x1 = line->x2 = line->y1 = line->y2 = _rsvg_css_parse_length ("0");
|
|
@@ -451,7 +450,7 @@ rsvg_new_rect (void)
|
|
{
|
|
RsvgNodeRect *rect;
|
|
rect = g_new (RsvgNodeRect, 1);
|
|
- _rsvg_node_init (&rect->super);
|
|
+ _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;
|
|
rect->x = rect->y = rect->w = rect->h = rect->rx = rect->ry = _rsvg_css_parse_length ("0");
|
|
@@ -577,7 +576,7 @@ rsvg_new_circle (void)
|
|
{
|
|
RsvgNodeCircle *circle;
|
|
circle = g_new (RsvgNodeCircle, 1);
|
|
- _rsvg_node_init (&circle->super);
|
|
+ _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;
|
|
circle->cx = circle->cy = circle->r = _rsvg_css_parse_length ("0");
|
|
@@ -703,7 +702,7 @@ rsvg_new_ellipse (void)
|
|
{
|
|
RsvgNodeEllipse *ellipse;
|
|
ellipse = g_new (RsvgNodeEllipse, 1);
|
|
- _rsvg_node_init (&ellipse->super);
|
|
+ _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;
|
|
ellipse->cx = ellipse->cy = ellipse->rx = ellipse->ry = _rsvg_css_parse_length ("0");
|
|
diff --git a/rsvg-shapes.h b/rsvg-shapes.h
|
|
index 7cf6621..baad98f 100644
|
|
--- a/rsvg-shapes.h
|
|
+++ b/rsvg-shapes.h
|
|
@@ -34,7 +34,7 @@
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
-RsvgNode * rsvg_new_path (void);
|
|
+RsvgNode *rsvg_new_path (void);
|
|
RsvgNode *rsvg_new_polygon (void);
|
|
RsvgNode *rsvg_new_polyline (void);
|
|
RsvgNode *rsvg_new_line (void);
|
|
diff --git a/rsvg-structure.c b/rsvg-structure.c
|
|
index b078fea..33889be 100644
|
|
--- a/rsvg-structure.c
|
|
+++ b/rsvg-structure.c
|
|
@@ -103,8 +103,10 @@ _rsvg_node_dont_set_atts (RsvgNode * node, RsvgHandle * ctx, RsvgPropertyBag * a
|
|
}
|
|
|
|
void
|
|
-_rsvg_node_init (RsvgNode * self)
|
|
+_rsvg_node_init (RsvgNode * self,
|
|
+ RsvgNodeType type)
|
|
{
|
|
+ self->type = type;
|
|
self->parent = NULL;
|
|
self->children = g_ptr_array_new ();
|
|
self->state = g_new (RsvgState, 1);
|
|
@@ -112,7 +114,6 @@ _rsvg_node_init (RsvgNode * self)
|
|
self->free = _rsvg_node_free;
|
|
self->draw = _rsvg_node_draw_nothing;
|
|
self->set_atts = _rsvg_node_dont_set_atts;
|
|
- self->type = NULL;
|
|
}
|
|
|
|
void
|
|
@@ -124,8 +125,6 @@ _rsvg_node_finalize (RsvgNode * self)
|
|
}
|
|
if (self->children != NULL)
|
|
g_ptr_array_free (self->children, TRUE);
|
|
- if (self->type != NULL)
|
|
- g_string_free (self->type, TRUE);
|
|
}
|
|
|
|
void
|
|
@@ -157,7 +156,7 @@ rsvg_new_group (void)
|
|
{
|
|
RsvgNodeGroup *group;
|
|
group = g_new (RsvgNodeGroup, 1);
|
|
- _rsvg_node_init (&group->super);
|
|
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_GROUP);
|
|
group->super.draw = _rsvg_node_draw_children;
|
|
group->super.set_atts = rsvg_node_group_set_atts;
|
|
return &group->super;
|
|
@@ -166,8 +165,8 @@ rsvg_new_group (void)
|
|
void
|
|
rsvg_pop_def_group (RsvgHandle * ctx)
|
|
{
|
|
- if (ctx->priv->currentnode != NULL)
|
|
- ctx->priv->currentnode = ctx->priv->currentnode->parent;
|
|
+ g_assert (ctx->priv->currentnode != NULL);
|
|
+ ctx->priv->currentnode = ctx->priv->currentnode->parent;
|
|
}
|
|
|
|
void
|
|
@@ -218,7 +217,7 @@ rsvg_node_use_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
|
|
return;
|
|
|
|
state = rsvg_current_state (ctx);
|
|
- if (strcmp (child->type->str, "symbol")) {
|
|
+ if (RSVG_NODE_TYPE (child) != RSVG_NODE_TYPE_SYMBOL) {
|
|
_rsvg_affine_translate (affine, x, y);
|
|
_rsvg_affine_multiply (state->affine, affine, state->affine);
|
|
|
|
@@ -397,7 +396,7 @@ rsvg_new_svg (void)
|
|
{
|
|
RsvgNodeSvg *svg;
|
|
svg = g_new (RsvgNodeSvg, 1);
|
|
- _rsvg_node_init (&svg->super);
|
|
+ _rsvg_node_init (&svg->super, RSVG_NODE_TYPE_SVG);
|
|
svg->vbox.active = FALSE;
|
|
svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
|
|
svg->x = _rsvg_css_parse_length ("0");
|
|
@@ -444,7 +443,7 @@ rsvg_new_use (void)
|
|
{
|
|
RsvgNodeUse *use;
|
|
use = g_new (RsvgNodeUse, 1);
|
|
- _rsvg_node_init (&use->super);
|
|
+ _rsvg_node_init (&use->super, RSVG_NODE_TYPE_USE);
|
|
use->super.draw = rsvg_node_use_draw;
|
|
use->super.set_atts = rsvg_node_use_set_atts;
|
|
use->x = _rsvg_css_parse_length ("0");
|
|
@@ -485,7 +484,7 @@ rsvg_new_symbol (void)
|
|
{
|
|
RsvgNodeSymbol *symbol;
|
|
symbol = g_new (RsvgNodeSymbol, 1);
|
|
- _rsvg_node_init (&symbol->super);
|
|
+ _rsvg_node_init (&symbol->super, RSVG_NODE_TYPE_SYMBOL);
|
|
symbol->vbox.active = FALSE;
|
|
symbol->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
|
|
symbol->super.draw = _rsvg_node_draw_nothing;
|
|
@@ -498,7 +497,7 @@ rsvg_new_defs (void)
|
|
{
|
|
RsvgNodeGroup *group;
|
|
group = g_new (RsvgNodeGroup, 1);
|
|
- _rsvg_node_init (&group->super);
|
|
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_DEFS);
|
|
group->super.draw = _rsvg_node_draw_nothing;
|
|
group->super.set_atts = rsvg_node_group_set_atts;
|
|
return &group->super;
|
|
@@ -533,7 +532,7 @@ rsvg_new_switch (void)
|
|
{
|
|
RsvgNodeGroup *group;
|
|
group = g_new (RsvgNodeGroup, 1);
|
|
- _rsvg_node_init (&group->super);
|
|
+ _rsvg_node_init (&group->super, RSVG_NODE_TYPE_SWITCH);
|
|
group->super.draw = _rsvg_node_switch_draw;
|
|
group->super.set_atts = rsvg_node_group_set_atts;
|
|
return &group->super;
|
|
diff --git a/rsvg-structure.h b/rsvg-structure.h
|
|
index d672977..7d17c82 100644
|
|
--- a/rsvg-structure.h
|
|
+++ b/rsvg-structure.h
|
|
@@ -36,7 +36,7 @@
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
-RsvgNode * rsvg_new_use (void);
|
|
+RsvgNode *rsvg_new_use (void);
|
|
RsvgNode *rsvg_new_symbol (void);
|
|
RsvgNode *rsvg_new_svg (void);
|
|
RsvgNode *rsvg_new_defs (void);
|
|
@@ -50,6 +50,7 @@ typedef struct _RsvgNodeSvg RsvgNodeSvg;
|
|
|
|
struct _RsvgNodeGroup {
|
|
RsvgNode super;
|
|
+ char *name;
|
|
};
|
|
|
|
struct _RsvgNodeSymbol {
|
|
@@ -80,7 +81,7 @@ void rsvg_node_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate
|
|
void _rsvg_node_draw_children (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate);
|
|
void _rsvg_node_finalize (RsvgNode * self);
|
|
void _rsvg_node_free (RsvgNode * self);
|
|
-void _rsvg_node_init (RsvgNode * self);
|
|
+void _rsvg_node_init (RsvgNode * self, RsvgNodeType type);
|
|
void _rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx);
|
|
|
|
G_END_DECLS
|
|
diff --git a/rsvg-text.c b/rsvg-text.c
|
|
index 7066f24..89720de 100644
|
|
--- a/rsvg-text.c
|
|
+++ b/rsvg-text.c
|
|
@@ -170,17 +170,19 @@ _rsvg_node_text_type_children (RsvgNode * self, RsvgDrawingCtx * ctx,
|
|
rsvg_push_discrete_layer (ctx);
|
|
for (i = 0; i < self->children->len; i++) {
|
|
RsvgNode *node = g_ptr_array_index (self->children, i);
|
|
- if (!strcmp (node->type->str, "RSVG_NODE_CHARS")) {
|
|
+ RsvgNodeType type = RSVG_NODE_TYPE (node);
|
|
+
|
|
+ if (type == RSVG_NODE_TYPE_CHARS) {
|
|
RsvgNodeChars *chars = (RsvgNodeChars *) node;
|
|
GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace);
|
|
rsvg_text_render_text (ctx, str->str, x, y);
|
|
g_string_free (str, TRUE);
|
|
- } else if (!strcmp (node->type->str, "tspan")) {
|
|
+ } else if (type == RSVG_NODE_TYPE_TSPAN) {
|
|
RsvgNodeText *tspan = (RsvgNodeText *) node;
|
|
rsvg_state_push (ctx);
|
|
_rsvg_node_text_type_tspan (tspan, ctx, x, y, lastwasspace);
|
|
rsvg_state_pop (ctx);
|
|
- } else if (!strcmp (node->type->str, "tref")) {
|
|
+ } else if (type == RSVG_NODE_TYPE_TREF) {
|
|
RsvgNodeTref *tref = (RsvgNodeTref *) node;
|
|
_rsvg_node_text_type_tref (tref, ctx, x, y, lastwasspace);
|
|
}
|
|
@@ -206,17 +208,19 @@ _rsvg_node_text_length_children (RsvgNode * self, RsvgDrawingCtx * ctx,
|
|
int out = FALSE;
|
|
for (i = 0; i < self->children->len; i++) {
|
|
RsvgNode *node = g_ptr_array_index (self->children, i);
|
|
+ RsvgNodeType type = RSVG_NODE_TYPE (node);
|
|
+
|
|
rsvg_state_push (ctx);
|
|
rsvg_state_reinherit_top (ctx, node->state, 0);
|
|
- if (!strcmp (node->type->str, "RSVG_NODE_CHARS")) {
|
|
+ if (type == RSVG_NODE_TYPE_CHARS) {
|
|
RsvgNodeChars *chars = (RsvgNodeChars *) node;
|
|
GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace);
|
|
*x += rsvg_text_length_text_as_string (ctx, str->str);
|
|
g_string_free (str, TRUE);
|
|
- } else if (!strcmp (node->type->str, "tspan")) {
|
|
+ } else if (type == RSVG_NODE_TYPE_TSPAN) {
|
|
RsvgNodeText *tspan = (RsvgNodeText *) node;
|
|
out = _rsvg_node_text_length_tspan (tspan, ctx, x, lastwasspace);
|
|
- } else if (!strcmp (node->type->str, "tref")) {
|
|
+ } else if (type == RSVG_NODE_TYPE_TREF) {
|
|
RsvgNodeTref *tref = (RsvgNodeTref *) node;
|
|
out = _rsvg_node_text_length_tref (tref, ctx, x, lastwasspace);
|
|
}
|
|
@@ -259,7 +263,7 @@ rsvg_new_text (void)
|
|
{
|
|
RsvgNodeText *text;
|
|
text = g_new (RsvgNodeText, 1);
|
|
- _rsvg_node_init (&text->super);
|
|
+ _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;
|
|
text->x = text->y = text->dx = text->dy = _rsvg_css_parse_length ("0");
|
|
@@ -331,7 +335,7 @@ rsvg_new_tspan (void)
|
|
{
|
|
RsvgNodeText *text;
|
|
text = g_new (RsvgNodeText, 1);
|
|
- _rsvg_node_init (&text->super);
|
|
+ _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TSPAN);
|
|
text->super.set_atts = _rsvg_node_tspan_set_atts;
|
|
text->x.factor = text->y.factor = 'n';
|
|
text->dx = text->dy = _rsvg_css_parse_length ("0");
|
|
@@ -374,7 +378,7 @@ rsvg_new_tref (void)
|
|
{
|
|
RsvgNodeTref *text;
|
|
text = g_new (RsvgNodeTref, 1);
|
|
- _rsvg_node_init (&text->super);
|
|
+ _rsvg_node_init (&text->super, RSVG_NODE_TYPE_TREF);
|
|
text->super.set_atts = _rsvg_node_tref_set_atts;
|
|
text->link = NULL;
|
|
return &text->super;
|
|
--
|
|
1.7.0.5
|
|
|