summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--rsvg-art-mask.c6
-rw-r--r--rsvg-art-paint-server.c10
-rw-r--r--rsvg-filter.c231
-rw-r--r--rsvg-filter.h10
-rw-r--r--rsvg-image.c99
-rw-r--r--rsvg-image.h3
-rw-r--r--rsvg-marker.c158
-rw-r--r--rsvg-marker.h5
-rw-r--r--rsvg-mask.c82
-rw-r--r--rsvg-mask.h5
-rw-r--r--rsvg-paint-server.c19
-rw-r--r--rsvg-paint-server.h3
-rw-r--r--rsvg-private.h2
-rw-r--r--rsvg-structure.c186
-rw-r--r--rsvg-structure.h11
-rw-r--r--rsvg.c44
17 files changed, 386 insertions, 495 deletions
diff --git a/ChangeLog b/ChangeLog
index 65879564..8bfd0272 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-05-17 Caleb Moore <c.moore@student.unsw.edu.au>
+
+ * A_whole_bunch_o'_files: Did a bit of fiddling. Now Children are stored in the RsvgNode structure, since DOM seems to mandate that everything be able to have children. I shall get rid of virtual functions for adding children soon.
+ * rsvg-filters.c: Made merge nodes and light sources proper objects.
+ * rsvg-marker.c: Converted markers to use the new system and broke them BADLY.
+ * rsvg-structures.c: made structual element relating functions a bit more generic. Saves some code duplication.
+
2005-05-16 Caleb Moore <c.moore@student.unsw.edu.au>
* rsvg-filter.c, rsvg-structure.c, rsvg-mask.c, rsvg.c: more DOM stuff. Now orthodox nodes are created, then attributes are assigned then are packed onto the top of the tree. I have moved all conforming node creation bits to rsvg-filter-handler-start so I remember what's left to convert. Probably opened a few bugs, you know how it is. Theoretically, it is now possible to implement external DOM interfaces to create new nodes and add nodes to other nodes. Attributes can be edited as much as the user wants for many elements now.
diff --git a/rsvg-art-mask.c b/rsvg-art-mask.c
index 8dc76569..8bda31ea 100644
--- a/rsvg-art-mask.c
+++ b/rsvg-art-mask.c
@@ -131,9 +131,9 @@ rsvg_art_clip_path_render (RsvgClipPath * self, RsvgDrawingCtx *ctx)
save = ctx->render;
ctx->render = (RsvgRender *)asvpr;
- for (i = 0; i < group->children->len; i++)
+ for (i = 0; i < group->super.children->len; i++)
{
- rsvg_node_draw (g_ptr_array_index(group->children, i),
+ rsvg_node_draw (g_ptr_array_index(group->super.children, i),
ctx, 0);
}
@@ -163,7 +163,7 @@ rsvg_art_mask_render (RsvgMask *self, GdkPixbuf *tos, GdkPixbuf *nos, RsvgDrawin
((RsvgArtRender *)ctx->render)->pixbuf = mask;
rsvg_state_push(ctx);
- rsvg_node_mask_draw (self, ctx, 0);
+ _rsvg_node_draw_children ((RsvgNode *)self, ctx, 0);
rsvg_state_pop(ctx);
((RsvgArtRender *)ctx->render)->pixbuf = save;
diff --git a/rsvg-art-paint-server.c b/rsvg-art-paint-server.c
index 7a2f5687..363229fb 100644
--- a/rsvg-art-paint-server.c
+++ b/rsvg-art-paint-server.c
@@ -385,7 +385,7 @@ static void
rsvg_art_paint_server_pattern_render (RsvgPattern *pattern, ArtRender *ar,
const RsvgPSCtx *ctx)
{
- RsvgNode *drawable = (RsvgNode *)pattern->g;
+ RsvgNode *drawable = (RsvgNode *)pattern;
RsvgDrawingCtx *hctx = ctx->ctx;
GdkPixbuf *pixbuf = ((RsvgArtRender *)hctx->render)->pixbuf;
double affine[6];
@@ -487,11 +487,11 @@ rsvg_art_paint_server_pattern_render (RsvgPattern *pattern, ArtRender *ar,
rsvg_state_current(hctx)->affine[i] = caffine[i];
}
- if (((RsvgNodeGroup *)drawable)->children->len ||
- pattern->gfallback == NULL)
- rsvg_node_draw (drawable, hctx, 2);
+ if (drawable->children->len ||
+ pattern->fallback == NULL)
+ _rsvg_node_draw_children (drawable, hctx, 2);
else
- rsvg_node_draw ((RsvgNode *)pattern->gfallback, hctx, 2);
+ _rsvg_node_draw_children (pattern->fallback, hctx, 2);
rsvg_state_pop(ctx->ctx);
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 91713796..c4102e13 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -321,9 +321,9 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
ctx->lastresult.Aused = 1;
ctx->lastresult.bounds = rsvg_filter_primitive_get_bounds (NULL, ctx);
- for (i = 0; i < self->primitives->len; i++)
+ for (i = 0; i < self->super.children->len; i++)
{
- current = g_ptr_array_index (self->primitives, i);
+ current = g_ptr_array_index (self->super.children, i);
rsvg_filter_primitive_render (current, ctx);
}
@@ -527,29 +527,6 @@ rsvg_filter_parse (const RsvgDefs * defs, const char *str)
return NULL;
}
-static void
-rsvg_filter_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgFilter *self = (RsvgFilter *)overself;
- g_ptr_array_add (self->primitives, child);
-}
-
-/**
- * rsvg_filter_free: Free a filter.
- * @dself: The defval to be freed
- *
- * Frees a filter and all primatives associated with this filter, this is
- * to be set as its free function to be used with rsvg defs
- **/
-static void
-rsvg_filter_free (RsvgNode * dself)
-{
- RsvgFilter *self;
-
- self = (RsvgFilter *) dself;
- g_ptr_array_free(self->primitives, FALSE);
-}
-
static void
rsvg_filter_set_args (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
{
@@ -605,6 +582,13 @@ rsvg_filter_set_args (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
}
}
+static void
+rsvg_filter_free (RsvgNode *self)
+{
+ g_ptr_array_free(self->children, TRUE);
+ g_free (self);
+}
+
/**
* rsvg_new_filter: Creates a black filter
*
@@ -622,10 +606,11 @@ rsvg_new_filter (void)
filter->y = -0.1;
filter->width = 1.2;
filter->height = 1.2;
- filter->primitives = g_ptr_array_new ();
+ filter->super.children = g_ptr_array_new ();
filter->super.type = RSVG_NODE_FILTER;
filter->super.free = rsvg_filter_free;
- filter->super.add_child = rsvg_filter_add_child;
+ filter->super.draw = _rsvg_node_draw_nothing;
+ filter->super.add_child = rsvg_node_add_child;
filter->super.set_atts = rsvg_filter_set_args;
return &filter->super;
}
@@ -1819,7 +1804,6 @@ typedef struct _RsvgFilterPrimitiveMerge RsvgFilterPrimitiveMerge;
struct _RsvgFilterPrimitiveMerge
{
RsvgFilterPrimitive super;
- GPtrArray *nodes;
};
static void
@@ -1839,9 +1823,9 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self,
output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
- for (i = 0; i < mself->nodes->len; i++)
+ for (i = 0; i < mself->super.super.children->len; i++)
{
- in = rsvg_filter_get_in (g_ptr_array_index (mself->nodes, i), ctx);
+ in = rsvg_filter_get_in (g_ptr_array_index (mself->super.super.children, i), ctx);
rsvg_art_alpha_blt (in, boundarys.x1, boundarys.y1, boundarys.x2 - boundarys.x1,
boundarys.y2 - boundarys.y1, output, boundarys.x1,
boundarys.y1);
@@ -1857,14 +1841,11 @@ static void
rsvg_filter_primitive_merge_free (RsvgNode * self)
{
RsvgFilterPrimitiveMerge *mself;
- guint i;
mself = (RsvgFilterPrimitiveMerge *) self;
g_string_free (mself->super.result, TRUE);
- for (i = 0; i < mself->nodes->len; i++)
- g_string_free (g_ptr_array_index (mself->nodes, i), TRUE);
- g_ptr_array_free (mself->nodes, TRUE);
+ g_ptr_array_free (mself->super.super.children, TRUE);
g_free (mself);
}
@@ -1931,39 +1912,48 @@ rsvg_new_filter_primitive_merge (void)
filter = g_new (RsvgFilterPrimitiveMerge, 1);
filter->super.result = g_string_new ("none");
filter->super.sizedefaults = 1;
- filter->nodes = g_ptr_array_new ();
filter->super.render = &rsvg_filter_primitive_merge_render;
filter->super.super.free = &rsvg_filter_primitive_merge_free;
filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE;
filter->super.super.set_atts = rsvg_filter_primitive_merge_set_atts;
+ filter->super.super.children = g_ptr_array_new();
+ filter->super.super.add_child = rsvg_node_add_child;
return (RsvgNode *)filter;
}
-void
-rsvg_start_filter_primitive_merge_node (RsvgHandle * ctx,
- RsvgPropertyBag * atts)
+static void
+rsvg_filter_primitive_merge_node_set_atts (RsvgNode * self,
+ RsvgHandle * ctx,
+ RsvgPropertyBag * atts)
{
- const char *value;
- int needdefault = 1;
- if (!(ctx && ctx->currentnode))
- return;
-
+ const char * value;
if (rsvg_property_bag_size (atts))
{
/* see bug 145149 - sodipodi generates bad SVG... */
if ((value = rsvg_property_bag_lookup (atts, "in")))
- {
- needdefault = 0;
- g_ptr_array_add (((RsvgFilterPrimitiveMerge *)
- (ctx->currentnode))->
- nodes, g_string_new (value));
- }
+ g_string_assign (((RsvgFilterPrimitive *)self)->in, value);
}
-
- if (needdefault)
- g_ptr_array_add (((RsvgFilterPrimitiveMerge *)
- (ctx->currentnode))->
- nodes, g_string_new ("none"));
+}
+
+static void
+rsvg_filter_primitive_merge_node_free (RsvgNode * self)
+{
+ RsvgFilterPrimitive *mself;
+ mself = (RsvgFilterPrimitive *) self;
+ g_string_free (mself->in, TRUE);
+ g_free (mself);
+}
+
+RsvgNode *
+rsvg_new_filter_primitive_merge_node (void)
+{
+ RsvgFilterPrimitive *filter;
+ filter = g_new (RsvgFilterPrimitive, 1);
+ filter->in = g_string_new ("none");
+ filter->super.free = rsvg_filter_primitive_merge_node_free;
+ filter->super.set_atts = rsvg_filter_primitive_merge_node_set_atts;
+ filter->super.type = RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE;
+ return &filter->super;
}
/*************************************************************/
@@ -4317,10 +4307,11 @@ typedef enum {
DISTANTLIGHT, POINTLIGHT, SPOTLIGHT
} lightType;
-typedef struct _lightSource lightSource;
+typedef struct _RsvgNodeLightSource RsvgNodeLightSource;
-struct _lightSource
+struct _RsvgNodeLightSource
{
+ RsvgNode super;
lightType type;
gdouble x; /*doubles as azimuth*/
gdouble y; /*dounles as elevation*/
@@ -4333,7 +4324,7 @@ struct _lightSource
};
static vector3
-get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdouble * affine)
+get_light_direction (RsvgNodeLightSource * source, gdouble x1, gdouble y1, gdouble z, gdouble * affine)
{
vector3 output;
@@ -4342,18 +4333,18 @@ get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdou
x = affine[0] * x1 + affine[2] * y1 + affine[4];
y = affine[1] * x1 + affine[3] * y1 + affine[5];
- switch (source.type)
+ switch (source->type)
{
case DISTANTLIGHT:
- output.x = cos(source.x)*cos(source.y);
- output.y = sin(source.x)*cos(source.y);
- output.z = sin(source.y);
+ output.x = cos(source->x)*cos(source->y);
+ output.y = sin(source->x)*cos(source->y);
+ output.z = sin(source->y);
break;
case POINTLIGHT:
case SPOTLIGHT:
- output.x = source.x - x;
- output.y = source.y - y;
- output.z = source.z - z;
+ output.x = source->x - x;
+ output.y = source->y - y;
+ output.z = source->z - z;
output = normalise(output);
break;
}
@@ -4361,7 +4352,7 @@ get_light_direction (lightSource source, gdouble x1, gdouble y1, gdouble z, gdou
}
static vector3
-get_light_colour(lightSource source, vector3 colour,
+get_light_colour(RsvgNodeLightSource * source, vector3 colour,
gdouble x1, gdouble y1, gdouble z, gdouble * affine)
{
double base, angle, x, y;
@@ -4369,27 +4360,27 @@ get_light_colour(lightSource source, vector3 colour,
vector3 L;
vector3 output;
- if (source.type != SPOTLIGHT)
+ if (source->type != SPOTLIGHT)
return colour;
x = affine[0] * x1 + affine[2] * y1 + affine[4];
y = affine[1] * x1 + affine[3] * y1 + affine[5];
- L.x = source.x - x;
- L.y = source.y - y;
- L.z = source.z - z;
+ L.x = source->x - x;
+ L.y = source->y - y;
+ L.z = source->z - z;
L = normalise(L);
- s.x = source.pointsAtX - source.x;
- s.y = source.pointsAtY - source.y;
- s.z = source.pointsAtZ - source.z;
+ s.x = source->pointsAtX - source->x;
+ s.y = source->pointsAtY - source->y;
+ s.z = source->pointsAtZ - source->z;
s = normalise(s);
base = -dotproduct(L, s);
angle = acos(base) * 180.0 / M_PI;
- if (base < 0 || angle > source.limitingconeAngle)
+ if (base < 0 || angle > source->limitingconeAngle)
{
output.x = 0;
output.y = 0;
@@ -4397,34 +4388,25 @@ get_light_colour(lightSource source, vector3 colour,
return output;
}
- output.x = colour.x*pow(base, source.specularExponent);
- output.y = colour.y*pow(base, source.specularExponent);
- output.z = colour.z*pow(base, source.specularExponent);
+ output.x = colour.x*pow(base, source->specularExponent);
+ output.y = colour.y*pow(base, source->specularExponent);
+ output.z = colour.z*pow(base, source->specularExponent);
return output;
}
-void
-rsvg_start_filter_primitive_light_source (RsvgHandle * ctx,
- RsvgPropertyBag * atts, char type)
+static void
+rsvg_filter_primitive_light_source_set_atts (RsvgNode * self,
+ RsvgHandle * ctx,
+ RsvgPropertyBag * atts)
{
- lightSource * data;
+ RsvgNodeLightSource * data;
const char *value;
double font_size;
font_size = rsvg_state_current_font_size (ctx);
- data = (lightSource *)ctx->currentnode;
- data->specularExponent = 1;
-
- if (type == 's')
- data->type = SPOTLIGHT;
- else if (type == 'd')
- data->type = DISTANTLIGHT;
- else
- data->type = POINTLIGHT;
-
- data->limitingconeAngle = 180;
+ data = (RsvgNodeLightSource *)self;
if (rsvg_property_bag_size (atts))
{
@@ -4475,6 +4457,29 @@ rsvg_start_filter_primitive_light_source (RsvgHandle * ctx,
}
}
+static void
+rsvg_filter_primitive_light_source_free(RsvgNode * tofree)
+{
+ g_free(tofree);
+}
+
+RsvgNode *
+rsvg_new_filter_primitive_light_source(char type)
+{
+ RsvgNodeLightSource * data;
+ data = g_new(RsvgNodeLightSource, 1);
+ data->super.free = rsvg_filter_primitive_light_source_free;
+ data->super.set_atts = rsvg_filter_primitive_light_source_set_atts;
+ data->specularExponent = 1;
+ if (type == 's')
+ data->type = SPOTLIGHT;
+ else if (type == 'd')
+ data->type = DISTANTLIGHT;
+ else
+ data->type = POINTLIGHT;
+ data->limitingconeAngle = 180;
+ return &data->super;
+}
/*************************************************************/
/*************************************************************/
@@ -4487,7 +4492,6 @@ struct _RsvgFilterPrimitiveDiffuseLighting
gdouble dx, dy;
double diffuseConstant;
double surfaceScale;
- lightSource source;
guint32 lightingcolour;
};
@@ -4503,7 +4507,7 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
vector3 lightcolour, L, N;
vector3 colour;
gdouble iaffine[6];
-
+ RsvgNodeLightSource * source = NULL;
FPBox boundarys;
guchar *in_pixels;
@@ -4513,7 +4517,18 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
GdkPixbuf *output;
GdkPixbuf *in;
-
+ unsigned int i;
+
+ for (i = 0; i < self->super.children->len; i++)
+ {
+ RsvgNode * temp;
+ temp = g_ptr_array_index(self->super.children, i);
+ if (temp->type == RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE)
+ source = (RsvgNodeLightSource *)temp;
+ }
+ if (source == NULL)
+ return;
+
oself = (RsvgFilterPrimitiveDiffuseLighting *) self;
boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
@@ -4556,11 +4571,11 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
for (x = boundarys.x1; x < boundarys.x2; x++)
{
z = surfaceScale * (double)in_pixels[y * rowstride + x * 4 + 3];
- L = get_light_direction(oself->source, x, y, z, iaffine);
+ L = get_light_direction(source, x, y, z, iaffine);
N = get_surface_normal(in_pixels, boundarys, x, y,
dx, dy, rawdx, rawdy, oself->surfaceScale,
rowstride);
- lightcolour = get_light_colour(oself->source, colour, x, y, z,
+ lightcolour = get_light_colour(source, colour, x, y, z,
iaffine);
factor = dotproduct(N, L);
@@ -4677,6 +4692,8 @@ rsvg_new_filter_primitive_diffuse_lighting (void)
filter->super.super.free = &rsvg_filter_primitive_diffuse_lighting_free;
filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE;
filter->super.super.set_atts = rsvg_filter_primitive_diffuse_lighting_set_atts;
+ filter->super.super.children = g_ptr_array_new();
+ filter->super.super.add_child = rsvg_node_add_child;
return (RsvgNode *)filter;
}
@@ -4691,7 +4708,6 @@ struct _RsvgFilterPrimitiveSpecularLighting
double specularConstant;
double specularExponent;
double surfaceScale;
- lightSource source;
guint32 lightingcolour;
};
@@ -4708,7 +4724,8 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
vector3 L;
gdouble iaffine[6];
FPBox boundarys;
-
+ RsvgNodeLightSource *source = NULL;
+
guchar *in_pixels;
guchar *output_pixels;
@@ -4716,6 +4733,18 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
GdkPixbuf *output;
GdkPixbuf *in;
+
+ unsigned int i;
+
+ for (i = 0; i < self->super.children->len; i++)
+ {
+ RsvgNode * temp;
+ temp = g_ptr_array_index(self->super.children, i);
+ if (temp->type == RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE)
+ source = (RsvgNodeLightSource *)temp;
+ }
+ if (source == NULL)
+ return;
oself = (RsvgFilterPrimitiveSpecularLighting *) self;
boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
@@ -4744,11 +4773,11 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
for (x = boundarys.x1; x < boundarys.x2; x++)
{
z = in_pixels[y * rowstride + x * 4 + 3] * surfaceScale;
- L = get_light_direction(oself->source, x, y, z, iaffine);
+ L = get_light_direction(source, x, y, z, iaffine);
L.z += 1;
L = normalise(L);
- lightcolour = get_light_colour(oself->source, colour, x, y, z,
+ lightcolour = get_light_colour(source, colour, x, y, z,
iaffine);
base = dotproduct(get_surface_normal(in_pixels, boundarys, x, y,
1, 1, 1.0 / ctx->paffine[0], 1.0 / ctx->paffine[3],
@@ -4886,6 +4915,8 @@ rsvg_new_filter_primitive_specular_lighting (void)
filter->super.super.free = &rsvg_filter_primitive_specular_lighting_free;
filter->super.super.type = RSVG_NODE_FILTER_PRIMITIVE;
filter->super.super.set_atts = rsvg_filter_primitive_specular_lighting_set_atts;
+ filter->super.super.children = g_ptr_array_new();
+ filter->super.super.add_child = rsvg_node_add_child;
return (RsvgNode *)filter;
}
diff --git a/rsvg-filter.h b/rsvg-filter.h
index f341454c..9b140546 100644
--- a/rsvg-filter.h
+++ b/rsvg-filter.h
@@ -36,7 +36,6 @@ typedef RsvgCoordUnits RsvgFilterUnits;
struct _RsvgFilter {
RsvgNode super;
int refcnt;
- GPtrArray * primitives;
double x, y, width, height;
RsvgFilterUnits filterunits;
RsvgFilterUnits primitiveunits;
@@ -69,8 +68,8 @@ rsvg_new_filter_primitive_offset (void);
RsvgNode *
rsvg_new_filter_primitive_merge (void);
-void
-rsvg_start_filter_primitive_merge_node (RsvgHandle *ctx, RsvgPropertyBag *atts);
+RsvgNode *
+rsvg_new_filter_primitive_merge_node (void);
RsvgNode *
rsvg_new_filter_primitive_colour_matrix (void);
@@ -103,9 +102,8 @@ rsvg_new_filter_primitive_image (void);
RsvgNode *
rsvg_new_filter_primitive_diffuse_lighting (void);
-void
-rsvg_start_filter_primitive_light_source (RsvgHandle * ctx,
- RsvgPropertyBag * atts, char type);
+RsvgNode *
+rsvg_new_filter_primitive_light_source (char type);
RsvgNode *
rsvg_new_filter_primitive_specular_lighting (void);
diff --git a/rsvg-image.c b/rsvg-image.c
index ea624081..6b090a72 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -525,79 +525,78 @@ rsvg_node_image_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
rsvg_pop_discrete_layer(ctx);
}
-void
-rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts)
+static void
+rsvg_node_image_set_atts (RsvgNode *self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
- double x = 0., y = 0., w = -1., h = -1., font_size;
- const char * href = NULL;
+ double font_size;
const char * klazz = NULL, * id = NULL, *value;
- int aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
GdkPixbuf *img;
GError *err = NULL;
- RsvgState * state;
- RsvgNodeImage *image;
- gboolean overflow = FALSE;
- state = g_new(RsvgState, 1);
- rsvg_state_init(state);
+ RsvgNodeImage *image = (RsvgNodeImage *)self;
+
font_size = rsvg_state_current_font_size(ctx);
if (rsvg_property_bag_size (atts))
{
if ((value = rsvg_property_bag_lookup (atts, "x")))
- x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
+ image->x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
if ((value = rsvg_property_bag_lookup (atts, "y")))
- y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
+ image->y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
if ((value = rsvg_property_bag_lookup (atts, "width")))
- w = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
+ image->w = rsvg_css_parse_normalized_length (value, ctx->dpi_x, (gdouble)ctx->width, font_size);
if ((value = rsvg_property_bag_lookup (atts, "height")))
- h = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
+ image->h = rsvg_css_parse_normalized_length (value, ctx->dpi_y, (gdouble)ctx->height, font_size);
/* path is used by some older adobe illustrator versions */
if ((value = rsvg_property_bag_lookup (atts, "path")) || (value = rsvg_property_bag_lookup (atts, "xlink:href")))
- href = value;
+ {
+ img = rsvg_pixbuf_new_from_href (value,
+ rsvg_handle_get_base_uri (ctx),
+ NULL);
+
+ if (!img)
+ {
+ if (err)
+ {
+ g_warning (_("Couldn't load image: %s\n"), err->message);
+ g_error_free (err);
+ }
+ return;
+ }
+ image->img = img;
+ }
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "id")))
- id = value;
+ {
+ id = value;
+ rsvg_defs_register_name (ctx->defs, id, &image->super);
+ }
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
- aspect_ratio = rsvg_css_parse_aspect_ratio (value);
+ image->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
if ((value = rsvg_property_bag_lookup (atts, "overflow")))
- overflow = rsvg_css_parse_overflow(value);
-
- rsvg_parse_style_attrs (ctx, state, "image", klazz, id, atts);
- }
-
- if (!href || w <= 0. || h <= 0.)
- return;
+ image->overflow = rsvg_css_parse_overflow(value);
- /*hmm, passing the error thingie into the next thing makes it screw up when using vfs*/
- img = rsvg_pixbuf_new_from_href (href, rsvg_handle_get_base_uri (ctx), NULL);
+ rsvg_parse_style_attrs (ctx, image->super.state, "image", klazz, id, atts);
+ }
+}
- if (!img)
- {
- if (err)
- {
- g_warning (_("Couldn't load image: %s\n"), err->message);
- g_error_free (err);
- }
- return;
- }
-
+RsvgNode *
+rsvg_new_image (void)
+{
+ RsvgNodeImage *image;
image = g_new (RsvgNodeImage, 1);
- image->img = img;
- image->preserve_aspect_ratio = aspect_ratio;
- image->x = x;
- image->y = y;
- image->w = w;
- image->h = h;
- image->overflow = overflow;
- image->super.state = state;
+ image->img = NULL;
+ image->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
+ image->x = 0;
+ image->y = 0;
+ image->w = -1;
+ image->h = -1;
+ image->overflow = FALSE;
+ image->super.state = g_new(RsvgState, 1);
+ rsvg_state_init(image->super.state);
image->super.type = RSVG_NODE_PATH;
image->super.free = rsvg_node_image_free;
image->super.draw = rsvg_node_image_draw;
- rsvg_defs_set (ctx->defs, id, &image->super);
-
- image->super.parent = (RsvgNode *)ctx->currentnode;
- if (image->super.parent != NULL)
- rsvg_node_group_pack(image->super.parent, &image->super);
-
+ image->super.set_atts = rsvg_node_image_set_atts;
+ return &image->super;
}
diff --git a/rsvg-image.h b/rsvg-image.h
index 2f9772f8..24db9af2 100644
--- a/rsvg-image.h
+++ b/rsvg-image.h
@@ -33,7 +33,8 @@
G_BEGIN_DECLS
-void rsvg_start_image (RsvgHandle *ctx, RsvgPropertyBag *atts);
+RsvgNode *
+rsvg_new_image (void);
typedef struct _RsvgNodeImage RsvgNodeImage;
diff --git a/rsvg-marker.c b/rsvg-marker.c
index dfae2fb8..90c1f468 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -36,64 +36,42 @@
#include <math.h>
#include <errno.h>
-static void
-rsvg_marker_free(RsvgNode* self)
-{
- RsvgMarker *marker;
- marker = (RsvgMarker *)self;
- g_free(self);
-}
-
-void
-rsvg_start_marker (RsvgHandle *ctx, RsvgPropertyBag *atts)
+static void
+rsvg_node_marker_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
const char *klazz = NULL, *id = NULL, *value;
RsvgMarker *marker;
double font_size;
- double x = 0., y = 0., w = 0., h = 0.;
- double vbx = 0., vby = 0., vbw = 1., vbh = 1.;
- gboolean obj_bbox = TRUE;
- RsvgState state;
- gboolean got_x, got_y, got_bbox, got_vbox, got_width, got_height;
- got_x = got_y = got_bbox = got_vbox = got_width = got_height = FALSE;
-
font_size = rsvg_state_current_font_size (ctx);
- marker = g_new (RsvgMarker, 1);
-
- rsvg_state_init(&state);
-
- marker->orient = 0;
- marker->orientAuto = FALSE;
- marker->overflow = FALSE;
- marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
+ marker = (RsvgMarker *)self;
if (rsvg_property_bag_size (atts))
{
if ((value = rsvg_property_bag_lookup (atts, "id")))
- id = value;
+ {
+ id = value;
+ rsvg_defs_register_name (ctx->defs, id, &marker->super);
+ }
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
if ((value = rsvg_property_bag_lookup (atts, "viewBox")))
{
- got_vbox = rsvg_css_parse_vbox (value, &vbx, &vby,
- &vbw, &vbh);
+ marker->vbox = rsvg_css_parse_vbox (value, &marker->vbx, &marker->vby,
+ &marker->vbw, &marker->vbh);
+ if (marker->vbox)
+ {
+ ctx->width = marker->vbw;
+ ctx->height = marker->vbh;
+ }
}
- if ((value = rsvg_property_bag_lookup (atts, "refX"))) {
- x = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
- got_x = TRUE;
- }
- if ((value = rsvg_property_bag_lookup (atts, "refY"))) {
- y = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
- got_y = TRUE;
- }
- if ((value = rsvg_property_bag_lookup (atts, "markerWidth"))) {
- w = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
- got_width = TRUE;
- }
- if ((value = rsvg_property_bag_lookup (atts, "markerHeight"))) {
- h = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
- got_height = TRUE;
- }
+ if ((value = rsvg_property_bag_lookup (atts, "refX")))
+ marker->refX = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
+ if ((value = rsvg_property_bag_lookup (atts, "refY")))
+ marker->refY = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
+ if ((value = rsvg_property_bag_lookup (atts, "markerWidth")))
+ marker->width = rsvg_css_parse_normalized_length (value, ctx->dpi_x, 1, font_size);
+ if ((value = rsvg_property_bag_lookup (atts, "markerHeight")))
+ marker->height = rsvg_css_parse_normalized_length (value, ctx->dpi_y, 1, font_size);
if ((value = rsvg_property_bag_lookup (atts, "orient"))) {
if (!strcmp (value, "auto"))
marker->orientAuto = TRUE;
@@ -102,65 +80,44 @@ rsvg_start_marker (RsvgHandle *ctx, RsvgPropertyBag *atts)
}
if ((value = rsvg_property_bag_lookup (atts, "markerUnits"))) {
if (!strcmp (value, "userSpaceOnUse"))
- obj_bbox = FALSE;
+ marker->bbox = FALSE;
else
- obj_bbox = TRUE;
- got_bbox = TRUE;
+ marker->bbox = TRUE;
}
if ((value = rsvg_property_bag_lookup (atts, "preserveAspectRatio")))
marker->preserve_aspect_ratio = rsvg_css_parse_aspect_ratio (value);
if ((value = rsvg_property_bag_lookup (atts, "overflow")))
marker->overflow = rsvg_css_parse_overflow(value);
}
-
- if (got_x)
- marker->refX = x;
- else
- marker->refX = 0;
-
- if (got_y)
- marker->refY = y;
- else
- marker->refY = 0;
-
- if (got_width)
- marker->width = w;
- else
- marker->width = 1;
-
- if (got_height)
- marker->height = h;
- else
- marker->height = 1;
-
- if (got_bbox)
- marker->bbox = obj_bbox;
- else
- marker->bbox = TRUE;
+}
- if (got_vbox)
- {
- marker->vbx = vbx;
- marker->vby = vby;
- marker->vbw = vbw;
- marker->vbh = vbh;
- marker->vbox = TRUE;
- ctx->width = vbw;
- ctx->height = vbh;
- }
- else
- marker->vbox = FALSE;
-
- /* set up the defval stuff */
+RsvgNode *
+rsvg_new_marker (void)
+{
+ RsvgMarker *marker;
+ marker = g_new (RsvgMarker, 1);
+ marker->super.state = g_new(RsvgState, 1);
+ rsvg_state_init(marker->super.state);
+ marker->orient = 0;
+ marker->orientAuto = FALSE;
+ marker->overflow = FALSE;
+ marker->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
+ marker->refX = 0;
+ marker->refY = 0;
+ marker->width = 1;
+ marker->height = 1;
+ marker->bbox = TRUE;
+ marker->vbox = FALSE;
marker->super.type = RSVG_NODE_MARKER;
-
- marker->contents = (RsvgNode *)rsvg_push_part_def_group(ctx, NULL, &state);
-
- marker->super.free = rsvg_marker_free;
-
- rsvg_defs_set (ctx->defs, id, &marker->super);
+ marker->super.children = g_ptr_array_new();
+ marker->super.free = rsvg_node_free;
+ marker->super.draw = _rsvg_node_draw_nothing;
+ marker->super.add_child = rsvg_node_add_child;
+ marker->super.set_atts = rsvg_node_marker_set_atts;
+ return &marker->super;
}
+
static void
rsvg_state_reassemble(RsvgNode * self, RsvgState * state)
{
@@ -182,7 +139,7 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
{
gdouble affine[6];
gdouble taffine[6];
- int i;
+ unsigned int i;
gdouble rotation;
RsvgState * state = rsvg_state_current(ctx);
@@ -235,11 +192,6 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
_rsvg_affine_multiply(affine, affine, taffine);
- /*don't inherit anything from the current context*/
- rsvg_state_finalize(state);
- rsvg_state_init(state);
- rsvg_state_reassemble((RsvgNode *)self->contents, state);
-
rsvg_state_push(ctx);
state = rsvg_state_current(ctx);
@@ -248,7 +200,15 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
state->affine[i] = affine[i];
}
- rsvg_node_draw (self->contents, ctx, 3);
+ for (i = 0; i < self->super.children->len; i++)
+ {
+ rsvg_state_push(ctx);
+
+ rsvg_node_draw (g_ptr_array_index(self->super.children, i),
+ ctx, 0);
+
+ rsvg_state_pop(ctx);
+ }
rsvg_state_pop(ctx);
}
diff --git a/rsvg-marker.h b/rsvg-marker.h
index fa9d02c6..2c8e02ad 100644
--- a/rsvg-marker.h
+++ b/rsvg-marker.h
@@ -33,7 +33,6 @@ typedef struct _RsvgMarker RsvgMarker;
struct _RsvgMarker {
RsvgNode super;
- RsvgNode * contents;
gboolean bbox;
double refX, refY, orient;
double vbx, vby, vbw, vbh, width, height;
@@ -41,8 +40,8 @@ struct _RsvgMarker {
gboolean vbox, orientAuto, overflow;
};
-void
-rsvg_start_marker (RsvgHandle *ctx, RsvgPropertyBag *atts);
+RsvgNode *
+rsvg_new_marker (void);
void
rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdouble linewidth, RsvgDrawingCtx *ctx);
diff --git a/rsvg-mask.c b/rsvg-mask.c
index c1afc492..dde61dcb 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -29,38 +29,6 @@
#include <string.h>
static void
-rsvg_mask_free (RsvgNode * self)
-{
- RsvgMask *z = (RsvgMask *)self;
- g_ptr_array_free(z->children, TRUE);
- rsvg_state_finalize (z->super.state);
- g_free(z->super.state);
- g_free (z);
-}
-
-void
-rsvg_node_mask_draw (RsvgMask *group, RsvgDrawingCtx *ctx,
- int dominate)
-{
- guint i;
-
- rsvg_state_reinherit_top(ctx, group->super.state, 0);
-
- rsvg_push_discrete_layer (ctx);
-
- for (i = 0; i < group->children->len; i++)
- {
- rsvg_state_push(ctx);
-
- rsvg_node_draw (g_ptr_array_index(group->children, i), ctx, 0);
-
- rsvg_state_pop(ctx);
- }
-
- rsvg_pop_discrete_layer (ctx);
-}
-
-static void
rsvg_mask_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
const char *id = NULL, *klazz = NULL, *value;
@@ -122,21 +90,6 @@ rsvg_mask_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
rsvg_parse_style_attrs (ctx, mask->super.state, "mask", klazz, id, atts);
}
-static void
-rsvg_mask_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgMask *self = (RsvgMask *)overself;
- if (self == NULL)
- return;
- g_ptr_array_add(self->children, child);
-}
-
-static void
-rsvg_draw_nothing (RsvgNode * self, RsvgDrawingCtx *ctx,
- int dominate)
-{
-}
-
RsvgNode *
rsvg_new_mask (void)
{
@@ -151,11 +104,11 @@ rsvg_new_mask (void)
mask->height = 1;
mask->super.state = g_new(RsvgState, 1);
rsvg_state_init(mask->super.state);
- mask->children = g_ptr_array_new ();
+ mask->super.children = g_ptr_array_new ();
mask->super.type = RSVG_NODE_MASK;
- mask->super.free = rsvg_mask_free;
- mask->super.draw = rsvg_draw_nothing;
- mask->super.add_child = rsvg_mask_add_child;
+ mask->super.free = rsvg_node_free;
+ mask->super.draw = _rsvg_node_draw_nothing;
+ mask->super.add_child = rsvg_node_add_child;
mask->super.set_atts = rsvg_mask_set_atts;
return &mask->super;
}
@@ -197,16 +150,6 @@ rsvg_mask_parse (const RsvgDefs * defs, const char *str)
}
static void
-rsvg_clip_path_free (RsvgNode * self)
-{
- RsvgClipPath *z = (RsvgClipPath *)self;
- g_ptr_array_free(z->children, TRUE);
- rsvg_state_finalize (z->super.state);
- g_free(z->super.state);
- g_free (z);
-}
-
-static void
rsvg_clip_path_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
const char *id = NULL, *klazz = NULL, *value = NULL;
@@ -239,28 +182,19 @@ rsvg_clip_path_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts
rsvg_parse_style_attrs (ctx, clip_path->super.state, "clipPath", klazz, id, atts);
}
-static void
-rsvg_clip_path_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgClipPath *self = (RsvgClipPath *)overself;
- if (self == NULL)
- return;
- g_ptr_array_add(self->children, child);
-}
-
RsvgNode *
rsvg_new_clip_path (void)
{
RsvgClipPath *clip_path;
clip_path = g_new (RsvgClipPath, 1);
- clip_path->children = g_ptr_array_new ();
+ clip_path->super.children = g_ptr_array_new ();
clip_path->units = userSpaceOnUse;
clip_path->super.state = g_new(RsvgState, 1);
clip_path->super.type = RSVG_NODE_CLIP_PATH;
- clip_path->super.free = rsvg_clip_path_free;
- clip_path->super.add_child = rsvg_clip_path_add_child;
- clip_path->super.draw = rsvg_draw_nothing;
+ clip_path->super.free = rsvg_node_free;
+ clip_path->super.add_child = rsvg_node_add_child;
+ clip_path->super.draw = _rsvg_node_draw_nothing;
clip_path->super.set_atts = rsvg_clip_path_set_atts;
return &clip_path->super;
}
diff --git a/rsvg-mask.h b/rsvg-mask.h
index 7f148512..a504fb37 100644
--- a/rsvg-mask.h
+++ b/rsvg-mask.h
@@ -39,7 +39,6 @@ typedef struct _RsvgMask RsvgMask;
struct _RsvgMask {
RsvgNode super;
- GPtrArray *children;
double x, y, width, height;
RsvgMaskUnits maskunits;
RsvgMaskUnits contentunits;
@@ -59,7 +58,6 @@ typedef struct _RsvgClipPath RsvgClipPath;
struct _RsvgClipPath {
RsvgNode super;
RsvgCoordUnits units;
- GPtrArray *children;
};
RsvgNode *
@@ -71,9 +69,6 @@ rsvg_end_clip_path (RsvgHandle *ctx);
RsvgNode *
rsvg_clip_path_parse (const RsvgDefs * defs, const char *str);
-void
-rsvg_node_mask_draw (RsvgMask *group, RsvgDrawingCtx *ctx, int dominate);
-
G_END_DECLS
#endif
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 8b05c6a0..fd91b004 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -304,11 +304,11 @@ rsvg_clone_pattern (const RsvgPattern *pattern)
for (i = 0; i < 6; i++)
clone->affine[i] = pattern->affine[i];
- if (((RsvgNodeGroup *)pattern->g)->children->len ||
- pattern->gfallback == NULL)
- clone->gfallback = pattern->g;
+ if (pattern->super.children->len ||
+ pattern->fallback == NULL)
+ clone->fallback = (RsvgNode *)pattern;
else
- clone->gfallback = pattern->gfallback;
+ clone->fallback = (RsvgNode *)pattern->fallback;
clone->x = pattern->x;
clone->y = pattern->y;
@@ -863,7 +863,7 @@ rsvg_start_pattern (RsvgHandle *ctx, RsvgPropertyBag *atts)
pattern = g_new (RsvgPattern, 1);
pattern->super.type = RSVG_NODE_PATTERN;
pattern->super.free = rsvg_pattern_free;
- pattern->gfallback = NULL;
+ pattern->fallback = NULL;
}
rsvg_defs_set (ctx->defs, id, &pattern->super);
@@ -891,7 +891,12 @@ rsvg_start_pattern (RsvgHandle *ctx, RsvgPropertyBag *atts)
pattern->vbw = (cloned && !got_vbox) ? pattern->vbw : vbw;
pattern->vbh = (cloned && !got_vbox) ? pattern->vbh : vbh;
pattern->vbox = (cloned && !got_vbox) ? pattern->vbox : got_vbox;
-
- pattern->g = (rsvg_push_part_def_group (ctx, NULL, &state));
+ pattern->super.add_child = rsvg_node_add_child;
+ pattern->super.draw = _rsvg_node_draw_nothing;
+ pattern->super.state = g_new(RsvgState, 1);
+ rsvg_state_init(pattern->super.state);
+ pattern->super.children = g_ptr_array_new();
+ rsvg_node_group_pack(ctx->currentnode, &pattern->super);
+ ctx->currentnode = &pattern->super;
}
diff --git a/rsvg-paint-server.h b/rsvg-paint-server.h
index 53a1a82f..b677bf31 100644
--- a/rsvg-paint-server.h
+++ b/rsvg-paint-server.h
@@ -103,8 +103,7 @@ struct _RsvgPattern {
double affine[6]; /* user space to actual at time of gradient def */
double x, y, width, height;
double vbx, vby, vbh, vbw;
- RsvgNode * g;
- RsvgNode * gfallback;
+ RsvgNode * fallback;
unsigned int preserve_aspect_ratio;
};
diff --git a/rsvg-private.h b/rsvg-private.h
index 598c3c8e..251e42b5 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -189,6 +189,7 @@ typedef enum {
RSVG_NODE_PATH,
RSVG_NODE_FILTER,
RSVG_NODE_FILTER_PRIMITIVE,
+ RSVG_NODE_FILTER_PRIMITIVE_MERGE_NODE,
RSVG_NODE_MASK,
RSVG_NODE_MARKER,
RSVG_NODE_SYMBOL,
@@ -199,6 +200,7 @@ struct _RsvgNode {
RsvgNodeType type;
RsvgState * state;
RsvgNode * parent;
+ GPtrArray *children;
void (*add_child) (RsvgNode *self, RsvgNode *child);
void (*free) (RsvgNode *self);
void (*draw) (RsvgNode * self, RsvgDrawingCtx *ctx, int dominate);
diff --git a/rsvg-structure.c b/rsvg-structure.c
index be02d72f..918e8437 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -46,6 +46,51 @@ rsvg_node_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
self->draw(self, ctx, dominate);
}
+/* generic function for drawing all of the children of a particular node */
+void
+_rsvg_node_draw_children (RsvgNode * self, RsvgDrawingCtx *ctx,
+ int dominate)
+{
+ guint i;
+ if (dominate != -1)
+ {
+ rsvg_state_reinherit_top(ctx, self->state, dominate);
+
+ rsvg_push_discrete_layer (ctx);
+ }
+ for (i = 0; i < self->children->len; i++)
+ {
+ rsvg_state_push(ctx);
+ rsvg_node_draw (g_ptr_array_index(self->children, i),
+ ctx, 0);
+ rsvg_state_pop(ctx);
+ }
+ if (dominate != -1)
+ rsvg_pop_discrete_layer (ctx);
+}
+
+/* generic function that doesn't draw anything at all */
+void
+_rsvg_node_draw_nothing (RsvgNode * self, RsvgDrawingCtx *ctx,
+ int dominate)
+{
+}
+
+void
+rsvg_node_add_child (RsvgNode *self, RsvgNode *child)
+{
+ g_ptr_array_add(self->children, child);
+}
+
+void
+rsvg_node_free (RsvgNode *self)
+{
+ rsvg_state_finalize (self->state);
+ g_free(self->state);
+ g_ptr_array_free(self->children, TRUE);
+ g_free (self);
+}
+
static void
rsvg_node_group_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
@@ -71,62 +116,18 @@ rsvg_end_g (RsvgHandle *ctx)
rsvg_pop_def_group (ctx);
}
-static void
-rsvg_node_group_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
- int dominate)
-{
- RsvgNodeGroup *group = (RsvgNodeGroup*)self;
- guint i;
-
- rsvg_state_reinherit_top(ctx, self->state, dominate);
-
- rsvg_push_discrete_layer (ctx);
-
- for (i = 0; i < group->children->len; i++)
- {
- rsvg_state_push(ctx);
- rsvg_node_draw (g_ptr_array_index(group->children, i),
- ctx, 0);
- rsvg_state_pop(ctx);
- }
-
- rsvg_pop_discrete_layer (ctx);
-}
-
-static void
-rsvg_node_group_free (RsvgNode *self)
-{
- RsvgNodeGroup *z = (RsvgNodeGroup *)self;
- rsvg_state_finalize (z->super.state);
- g_free(z->super.state);
- g_ptr_array_free(z->children, TRUE);
- g_free (z);
-}
-
-/* exported for group derived things... hopefully group derived things
- shouldn't be used for much longer */
-
-void
-rsvg_node_group_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgNodeGroup *self = (RsvgNodeGroup *)overself;
- if (self == NULL)
- return;
- g_ptr_array_add(self->children, child);
-}
-
RsvgNode *
rsvg_new_group (void)
{
RsvgNodeGroup *group;
group = g_new (RsvgNodeGroup, 1);
- group->children = g_ptr_array_new();
+ group->super.children = g_ptr_array_new();
group->super.state = g_new(RsvgState, 1);
rsvg_state_init(group->super.state);
group->super.type = RSVG_NODE_PATH;
- group->super.free = rsvg_node_group_free;
- group->super.add_child = rsvg_node_group_add_child;
- group->super.draw = rsvg_node_group_draw;
+ group->super.free = rsvg_node_free;
+ group->super.add_child = rsvg_node_add_child;
+ group->super.draw = _rsvg_node_draw_children;
group->super.set_atts = rsvg_node_group_set_atts;
return &group->super;
}
@@ -138,14 +139,14 @@ rsvg_push_part_def_group (RsvgHandle *ctx, const char * id,
RsvgNodeGroup *group;
group = g_new (RsvgNodeGroup, 1);
- group->children = g_ptr_array_new();
+ group->super.children = g_ptr_array_new();
group->super.state = g_new(RsvgState, 1);
*group->super.state = *state;
group->super.type = RSVG_NODE_PATH;
- group->super.free = rsvg_node_group_free;
- group->super.draw = rsvg_node_group_draw;
- group->super.add_child = rsvg_node_group_add_child;
+ group->super.free = rsvg_node_free;
+ group->super.draw = _rsvg_node_draw_children;
+ group->super.add_child = rsvg_node_add_child;
rsvg_defs_set (ctx->defs, id, &group->super);
@@ -307,11 +308,11 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
state->affine);
}
- for (i = 0; i < sself->children->len; i++)
+ for (i = 0; i < self->children->len; i++)
{
rsvg_state_push(ctx);
- rsvg_node_draw (g_ptr_array_index(sself->children, i),
+ rsvg_node_draw (g_ptr_array_index(self->children, i),
ctx, 0);
rsvg_state_pop(ctx);
@@ -320,23 +321,6 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
rsvg_pop_discrete_layer (ctx);
}
-static void
-rsvg_node_svg_free (RsvgNode *self)
-{
- RsvgNodeSvg *z = (RsvgNodeSvg *)self;
- rsvg_state_finalize (self->state);
- g_free (self->state);
- g_ptr_array_free(z->children, TRUE);
- g_free (z);
-}
-
-static void
-rsvg_node_svg_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgNodeSvg *self = (RsvgNodeSvg *)overself;
- g_ptr_array_add(self->children, child);
-}
-
static void
rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle *ctx, RsvgPropertyBag *atts)
{
@@ -395,13 +379,13 @@ rsvg_new_svg (void)
svg->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
svg->x = 0; svg->y = 0; svg->w = -1; svg->h = -1;
svg->vbx = 0; svg->vby = 0; svg->vbw = 0; svg->vbh = 0;
- svg->children = g_ptr_array_new();
+ svg->super.children = g_ptr_array_new();
svg->super.state = g_new(RsvgState, 1);
rsvg_state_init(svg->super.state);
svg->super.type = RSVG_NODE_PATH;
- svg->super.free = rsvg_node_svg_free;
+ svg->super.free = rsvg_node_free;
svg->super.draw = rsvg_node_svg_draw;
- svg->super.add_child = rsvg_node_svg_add_child;
+ svg->super.add_child = rsvg_node_add_child;
svg->super.set_atts = rsvg_node_svg_set_atts;
svg->overflow = FALSE;
return &svg->super;
@@ -471,17 +455,6 @@ rsvg_new_use ()
return (RsvgNode *)use;
}
-
-static void
-rsvg_node_symbol_free (RsvgNode *self)
-{
- RsvgNodeSymbol *z = (RsvgNodeSymbol *)self;
- rsvg_state_finalize (self->state);
- g_free(self->state);
- g_ptr_array_free(z->children, TRUE);
- g_free (z);
-}
-
static void
rsvg_node_symbol_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
int dominate)
@@ -501,11 +474,11 @@ rsvg_node_symbol_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
rsvg_add_clipping_rect(ctx, sself->x, sself->y, sself->width, sself->height);
}
- for (i = 0; i < sself->children->len; i++)
+ for (i = 0; i < self->children->len; i++)
{
rsvg_state_push(ctx);
- rsvg_node_draw (g_ptr_array_index(sself->children, i),
+ rsvg_node_draw (g_ptr_array_index(self->children, i),
ctx, 0);
rsvg_state_pop(ctx);
@@ -550,12 +523,6 @@ rsvg_node_symbol_set_atts(RsvgNode *self, RsvgHandle *ctx, RsvgPropertyBag *atts
rsvg_parse_style_attrs (ctx, self->state, "symbol", klazz, id, atts);
}
-static void
-rsvg_node_symbol_add_child (RsvgNode *overself, RsvgNode *child)
-{
- RsvgNodeSymbol *self = (RsvgNodeSymbol *)overself;
- g_ptr_array_add(self->children, child);
-}
RsvgNode *
rsvg_new_symbol(void)
@@ -565,35 +532,29 @@ rsvg_new_symbol(void)
symbol->has_vbox = 0;
symbol->overflow = 0;
symbol->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
- symbol->children = g_ptr_array_new();
+ symbol->super.children = g_ptr_array_new();
symbol->super.state = g_new(RsvgState, 1);
rsvg_state_init(symbol->super.state);
symbol->super.type = RSVG_NODE_SYMBOL;
- symbol->super.free = rsvg_node_symbol_free;
+ symbol->super.free = rsvg_node_free;
symbol->super.draw = rsvg_node_symbol_draw;
- symbol->super.add_child = rsvg_node_symbol_add_child;
+ symbol->super.add_child = rsvg_node_add_child;
symbol->super.set_atts = rsvg_node_symbol_set_atts;
return &symbol->super;
}
-static void
-_rsvg_node_defs_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
- int dominate)
-{
-}
-
RsvgNode *
rsvg_new_defs ()
{
RsvgNodeGroup *group;
group = g_new (RsvgNodeGroup, 1);
- group->children = g_ptr_array_new();
+ group->super.children = g_ptr_array_new();
group->super.state = g_new(RsvgState, 1);
rsvg_state_init(group->super.state);
group->super.type = RSVG_NODE_PATH;
- group->super.free = rsvg_node_group_free;
- group->super.add_child = rsvg_node_group_add_child;
- group->super.draw = _rsvg_node_defs_draw;
+ group->super.free = rsvg_node_free;
+ group->super.add_child = rsvg_node_add_child;
+ group->super.draw = _rsvg_node_draw_nothing;
group->super.set_atts = rsvg_node_group_set_atts;
return &group->super;
}
@@ -602,20 +563,19 @@ static void
_rsvg_node_switch_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
int dominate)
{
- RsvgNodeGroup *group = (RsvgNodeGroup*)self;
guint i;
rsvg_state_reinherit_top(ctx, self->state, dominate);
rsvg_push_discrete_layer (ctx);
- for (i = 0; i < group->children->len; i++)
+ for (i = 0; i < self->children->len; i++)
{
- RsvgNode * drawable = g_ptr_array_index(group->children, i);
+ RsvgNode * drawable = g_ptr_array_index(self->children, i);
if (drawable->state->cond_true) {
rsvg_state_push(ctx);
- rsvg_node_draw (g_ptr_array_index(group->children, i),
+ rsvg_node_draw (g_ptr_array_index(self->children, i),
ctx, 0);
rsvg_state_pop(ctx);
@@ -631,12 +591,12 @@ rsvg_new_switch (void)
{
RsvgNodeGroup *group;
group = g_new (RsvgNodeGroup, 1);
- group->children = g_ptr_array_new();
+ group->super.children = g_ptr_array_new();
group->super.state = g_new(RsvgState, 1);
rsvg_state_init(group->super.state);
group->super.type = RSVG_NODE_PATH;
- group->super.free = rsvg_node_group_free;
- group->super.add_child = rsvg_node_group_add_child;
+ group->super.free = rsvg_node_free;
+ group->super.add_child = rsvg_node_add_child;
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 dec33c24..72885fe6 100644
--- a/rsvg-structure.h
+++ b/rsvg-structure.h
@@ -52,12 +52,10 @@ typedef struct _RsvgNodeSvg RsvgNodeSvg;
struct _RsvgNodeGroup {
RsvgNode super;
- GPtrArray *children;
};
struct _RsvgNodeSymbol {
RsvgNode super;
- GPtrArray *children;
gint preserve_aspect_ratio;
gboolean overflow, has_vbox;
double x, y, width, height;
@@ -76,17 +74,22 @@ struct _RsvgNodeSvg {
gdouble vbx, vby, vbw, vbh;
gboolean overflow, has_vbox;
GdkPixbuf *img;
- GPtrArray *children;
};
RsvgNode *
rsvg_push_part_def_group (RsvgHandle *ctx, const char * id, RsvgState *state);
void rsvg_pop_def_group (RsvgHandle *ctx);
void rsvg_node_group_pack (RsvgNode *self, RsvgNode *child);
-void rsvg_node_group_add_child (RsvgNode *overself, RsvgNode *child);
+void rsvg_node_add_child (RsvgNode *overself, RsvgNode *child);
void rsvg_node_draw (RsvgNode * self, RsvgDrawingCtx *ctx,
int dominate);
+void _rsvg_node_draw_nothing (RsvgNode * self, RsvgDrawingCtx *ctx,
+ int dominate);
+void _rsvg_node_draw_children (RsvgNode * self, RsvgDrawingCtx *ctx,
+ int dominate);
+void rsvg_node_free (RsvgNode *self);
+
G_END_DECLS
diff --git a/rsvg.c b/rsvg.c
index 3975ad30..8d9657cd 100644
--- a/rsvg.c
+++ b/rsvg.c
@@ -199,6 +199,8 @@ rsvg_filter_handler_start (RsvgHandle *ctx, const xmlChar *name,
newnode = rsvg_new_filter_primitive_tile();
else if (!strcmp ((char *)name, "feTurbulence"))
newnode = rsvg_new_filter_primitive_turbulence();
+ else if (!strcmp ((char *)name, "feMergeNode"))
+ newnode = rsvg_new_filter_primitive_merge_node();
else if (!strcmp ((char *)name, "g"))
newnode = rsvg_new_group ();
else if (!strcmp ((char *)name, "a")) /*treat anchors as groups for now*/
@@ -217,6 +219,16 @@ rsvg_filter_handler_start (RsvgHandle *ctx, const xmlChar *name,
newnode = rsvg_new_mask();
else if (!strcmp ((char *)name, "clipPath"))
newnode = rsvg_new_clip_path();
+ else if (!strcmp ((char *)name, "image"))
+ newnode = rsvg_new_image ();
+ else if (!strcmp ((char *)name, "marker"))
+ newnode = rsvg_new_marker ();
+ else if (!strcmp ((char *)name, "feDistantLight"))
+ newnode = rsvg_new_filter_primitive_light_source('d');
+ else if (!strcmp ((char *)name, "feSpotLight"))
+ newnode = rsvg_new_filter_primitive_light_source('s');
+ else if (!strcmp ((char *)name, "fePointLight"))
+ newnode = rsvg_new_filter_primitive_light_source('p');
if (newnode)
{
rsvg_node_set_atts(newnode, ctx, atts);
@@ -509,8 +521,6 @@ rsvg_start_element (void *data, const xmlChar *name,
rsvg_start_polyline (ctx, bag);
else if (!strcmp ((char *)name, "text"))
rsvg_start_text (ctx, bag);
- else if (!strcmp ((char *)name, "image"))
- rsvg_start_image (ctx, bag);
else if (!strcmp ((char *)name, "style"))
rsvg_start_style (ctx, bag);
else if (!strcmp ((char *)name, "title"))
@@ -519,8 +529,6 @@ rsvg_start_element (void *data, const xmlChar *name,
rsvg_start_desc (ctx, bag);
else if (!strcmp ((char *)name, "metadata"))
rsvg_start_metadata (ctx, bag);
- else if (!strcmp ((char *)name, "marker"))
- rsvg_start_marker (ctx, bag);
/* see conicalGradient discussion above */
else if (!strcmp ((char *)name, "linearGradient"))
rsvg_start_linear_gradient (ctx, bag);
@@ -530,14 +538,6 @@ rsvg_start_element (void *data, const xmlChar *name,
rsvg_start_radial_gradient (ctx, bag, "conicalGradient");
else if (!strcmp ((char *)name, "pattern"))
rsvg_start_pattern (ctx, bag);
- else if (!strcmp ((char *)name, "feDistantLight"))
- rsvg_start_filter_primitive_light_source(ctx, bag, 'd');
- else if (!strcmp ((char *)name, "feSpotLight"))
- rsvg_start_filter_primitive_light_source(ctx, bag, 's');
- else if (!strcmp ((char *)name, "fePointLight"))
- rsvg_start_filter_primitive_light_source(ctx, bag, 'p');
- else if (!strcmp ((char *)name, "feMergeNode"))
- rsvg_start_filter_primitive_merge_node(ctx, bag);
else if (!strcmp ((char *)name, "feFuncR"))
rsvg_start_filter_primitive_component_transfer_function(ctx, bag, 'r');
else if (!strcmp ((char *)name, "feFuncG"))
@@ -597,20 +597,18 @@ rsvg_end_element (void *data, const xmlChar *name)
else if (!strcmp ((char *)name, "clipPath"))
rsvg_end_clip_path(ctx);
else if (!strcmp ((char *)name, "marker"))
- rsvg_pop_def_group(ctx);
+ rsvg_end_filter(ctx);
else if (!strcmp ((char *)name, "switch"))
- rsvg_end_switch (ctx); /* treat switches as groups for now */
+ rsvg_end_filter (ctx); /* treat switches as groups for now */
else if (!strcmp ((char *)name, "pattern"))
rsvg_pop_def_group(ctx);
- else if (!strncmp ((char *)name, "fe", 2))
- {
- if (strncmp ((char *)name, "feFunc", 6) &&
- strcmp ((char *)name, "feMergeNode") &&
- strcmp ((char *)name, "feDistantLight") &&
- strcmp ((char *)name, "feSpotLight") &&
- strcmp ((char *)name, "fePointLight"))
- rsvg_end_filter(ctx);
- }
+ else if (!strcmp ((char *)name, "image") ||
+ !strcmp ((char *)name, "use"))
+ rsvg_end_filter(ctx);
+ else if (!strncmp ((char *)name, "fe", 2) &&
+ strncmp ((char *)name, "feFunc", 6))
+ rsvg_end_filter(ctx);
+
}
}