summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDom Lachowicz <doml@src.gnome.org>2004-08-14 14:01:03 +0000
committerDom Lachowicz <doml@src.gnome.org>2004-08-14 14:01:03 +0000
commit04c949a0dc30c258a8e32aaa5d861167b2fe2d0e (patch)
tree8dc397e06857e545ea2d0daf2625747a8db7d465
parent1a07cca1788d8e3ab823e684bfc25842f3fac5b3 (diff)
downloadlibrsvg-04c949a0dc30c258a8e32aaa5d861167b2fe2d0e.tar.gz
backport significant amount from HEAD
-rw-r--r--ChangeLog10
-rw-r--r--configure.in4
-rw-r--r--rsvg-filter.c101
-rw-r--r--rsvg-mask.c90
-rw-r--r--rsvg-paint-server.c19
-rw-r--r--rsvg-private.h12
-rw-r--r--rsvg-shapes.c211
-rw-r--r--rsvg-styles.c88
-rw-r--r--rsvg-styles.h5
-rw-r--r--rsvg-text.c14
-rw-r--r--rsvg.c51
11 files changed, 269 insertions, 336 deletions
diff --git a/ChangeLog b/ChangeLog
index a956314e..736b091c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-08-13 Dom Lachowicz <cinamod@hotmail.com>
+
+ * rsvg-styles.c: Fix memory leak in the new "state stack thingie".
+ * rsvg.c: Use a GMemChunk to (marginally) speed up state allocation
+
+2004-08-13 Caleb Moore <c.moore@student.unsw.edu.au>
+
+ * prettymuch-everywhere: Huge number of small bugfixes
+ * rsvg-styles.c: rewrote the whole state stack thingie
+
2004-07-23 Caleb Moore <c.moore@student.unsw.edu.au>
* rsvg-shapes.c, rsvg-mask.c: ClipPaths now partially working
diff --git a/configure.in b/configure.in
index b5b4abfa..4391ca10 100644
--- a/configure.in
+++ b/configure.in
@@ -19,8 +19,8 @@ AC_SUBST(POPT_REQUIRED)
dnl ===========================================================================
LIBRSVG_MAJOR_VERSION=2
-LIBRSVG_MINOR_VERSION=8
-LIBRSVG_MICRO_VERSION=0
+LIBRSVG_MINOR_VERSION=7
+LIBRSVG_MICRO_VERSION=90
AC_SUBST(LIBRSVG_MAJOR_VERSION)
AC_SUBST(LIBRSVG_MINOR_VERSION)
AC_SUBST(LIBRSVG_MICRO_VERSION)
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 5ab99dba..5de70908 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -37,6 +37,9 @@
#define M_PI 3.14159265358979323846
#endif /* M_PI */
+/* probably poor form, but it saves us from whacking it in the header file */
+void rsvg_clip_image(GdkPixbuf *intermediate, ArtSVP *path);
+
#define PERFECTBLUR 0
/*************************************************************/
@@ -169,9 +172,9 @@ rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self,
return output;
}
-static GdkPixbuf *
-gdk_pixbuf_new_cleared (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample,
- int width, int height)
+GdkPixbuf *
+_rsvg_pixbuf_new_cleared (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample,
+ int width, int height)
{
GdkPixbuf *pb;
guchar *data;
@@ -432,6 +435,9 @@ rsvg_filter_render (RsvgFilter * self, GdkPixbuf * source, GdkPixbuf * output,
bounds = rsvg_filter_primitive_get_bounds (NULL, ctx);
+ if (rsvg_state_current (context)->clippath)
+ rsvg_clip_image(ctx->lastresult.result, rsvg_state_current (context)->clippath);
+
rsvg_alpha_blt (ctx->lastresult.result, bounds.x1, bounds.y1, bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1, output, bounds.x1, bounds.y1);
context->bbox.x0 = bounds.x1;
@@ -501,9 +507,9 @@ pixbuf_get_alpha (GdkPixbuf * pb)
pbsize = gdk_pixbuf_get_width (pb) * gdk_pixbuf_get_height (pb);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
- gdk_pixbuf_get_width (pb),
- gdk_pixbuf_get_height (pb));
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
+ gdk_pixbuf_get_width (pb),
+ gdk_pixbuf_get_height (pb));
data = gdk_pixbuf_get_pixels (output);
pbdata = gdk_pixbuf_get_pixels (pb);
@@ -906,7 +912,7 @@ rsvg_filter_primitive_blend_render (RsvgFilterPrimitive * self,
in = rsvg_filter_get_in (self->in, ctx);
in2 = rsvg_filter_get_in (bself->in2, ctx);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, gdk_pixbuf_get_width (in), gdk_pixbuf_get_height (in));
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, gdk_pixbuf_get_width (in), gdk_pixbuf_get_height (in));
rsvg_filter_blend(bself->mode, in, in2, output, boundarys);
@@ -1130,7 +1136,7 @@ rsvg_filter_primitive_convolve_matrix_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
for (y = boundarys.y1; y < boundarys.y2; y++)
@@ -1513,6 +1519,12 @@ box_blur (GdkPixbuf *in, GdkPixbuf *output, GdkPixbuf *intermediate, gint kw,
rowstride = gdk_pixbuf_get_rowstride (in);
+ if (kw > boundarys.x2 - boundarys.x1)
+ kw = boundarys.x2 - boundarys.x1;
+
+ if (kh > boundarys.y2 - boundarys.y1)
+ kh = boundarys.y2 - boundarys.y1;
+
if (kw >= 1)
{
@@ -1709,10 +1721,10 @@ fast_blur (GdkPixbuf *in, GdkPixbuf *output, gfloat sx,
kx = floor(sx * 3*sqrt(2*M_PI)/4 + 0.5);
ky = floor(sy * 3*sqrt(2*M_PI)/4 + 0.5);
- intermediate1 = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
+ intermediate1 = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
gdk_pixbuf_get_width (in),
gdk_pixbuf_get_height (in));
- intermediate2 = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
+ intermediate2 = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
gdk_pixbuf_get_width (in),
gdk_pixbuf_get_height (in));
@@ -1745,7 +1757,7 @@ rsvg_filter_primitive_gaussian_blur_render (RsvgFilterPrimitive * self,
op = rsvg_filter_get_result (self->in, ctx);
in = op.result;
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8,
gdk_pixbuf_get_width (in),
gdk_pixbuf_get_height (in));
@@ -1899,7 +1911,7 @@ rsvg_filter_primitive_offset_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -2051,7 +2063,7 @@ rsvg_filter_primitive_merge_render (RsvgFilterPrimitive * self,
mself = (RsvgFilterPrimitiveMerge *) self;
boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
for (i = 0; i < mself->nodes->len; i++)
{
@@ -2152,14 +2164,26 @@ rsvg_start_filter_primitive_merge_node (RsvgHandle * ctx,
RsvgPropertyBag * atts)
{
const char *value;
+ int needdefault = 1;
+ if (!(ctx && ctx->currentsubfilter))
+ return;
+
if (rsvg_property_bag_size (atts))
{
/* see bug 145149 - sodipodi generates bad SVG... */
- if (ctx && ctx->currentsubfilter && (value = rsvg_property_bag_lookup (atts, "in")))
- g_ptr_array_add (((RsvgFilterPrimitiveMerge *) (ctx->
- currentsubfilter))->
- nodes, g_string_new (value));
+ if ((value = rsvg_property_bag_lookup (atts, "in")))
+ {
+ needdefault = 0;
+ g_ptr_array_add (((RsvgFilterPrimitiveMerge *)
+ (ctx->currentsubfilter))->
+ nodes, g_string_new (value));
+ }
}
+
+ if (needdefault)
+ g_ptr_array_add (((RsvgFilterPrimitiveMerge *)
+ (ctx->currentsubfilter))->
+ nodes, g_string_new ("none"));
}
/*************************************************************/
@@ -2212,7 +2236,7 @@ rsvg_filter_primitive_colour_matrix_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
for (y = boundarys.y1; y < boundarys.y2; y++)
@@ -2561,7 +2585,7 @@ rsvg_filter_primitive_component_transfer_render (RsvgFilterPrimitive *
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -2830,7 +2854,7 @@ rsvg_filter_primitive_erode_render (RsvgFilterPrimitive * self,
kx = cself->rx * ctx->paffine[0];
ky = cself->ry * ctx->paffine[3];
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -3020,7 +3044,7 @@ rsvg_filter_primitive_composite_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
if (bself->mode == COMPOSITE_MODE_ARITHMETIC)
@@ -3274,7 +3298,7 @@ rsvg_filter_primitive_flood_render (RsvgFilterPrimitive * self,
height = ctx->height;
width = ctx->width;
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
rowstride = gdk_pixbuf_get_rowstride (output);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -3438,7 +3462,7 @@ rsvg_filter_primitive_displacement_map_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -3849,7 +3873,7 @@ rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self,
tileWidth = (boundarys.x2 - boundarys.x1);
tileHeight = (boundarys.y2 - boundarys.y1);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
for (y = 0; y < tileHeight; y++)
@@ -4016,30 +4040,19 @@ rsvg_filter_primitive_image_render_in (RsvgFilterPrimitive * self,
boundarys = rsvg_filter_primitive_get_bounds (self, context);
- img = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, context->width, context->height);
+ img = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, context->width, context->height);
save = ctx->pixbuf;
ctx->pixbuf = img;
for (i = 0; i < 6; i++)
- ctx->state[ctx->n_state - 1].affine[i] = context->paffine[i];
-
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_current(ctx)->affine[i] = context->paffine[i];
+
+ rsvg_state_push(ctx);
rsvg_defs_drawable_draw (drawable, ctx, 0);
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
ctx->pixbuf = save;
return img;
@@ -4104,7 +4117,7 @@ rsvg_filter_primitive_image_render (RsvgFilterPrimitive * self,
boundarys = rsvg_filter_primitive_get_bounds (self, ctx);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
img = rsvg_filter_primitive_image_render_in (self, ctx);
if (img == NULL)
@@ -4677,7 +4690,7 @@ rsvg_filter_primitive_diffuse_lighting_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -4874,7 +4887,7 @@ rsvg_filter_primitive_specular_lighting_render (RsvgFilterPrimitive * self,
rowstride = gdk_pixbuf_get_rowstride (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
output_pixels = gdk_pixbuf_get_pixels (output);
@@ -5075,7 +5088,7 @@ rsvg_filter_primitive_tile_render (RsvgFilterPrimitive * self,
in_pixels = gdk_pixbuf_get_pixels (in);
- output = gdk_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
+ output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, ctx->width, ctx->height);
rowstride = gdk_pixbuf_get_rowstride (output);
output_pixels = gdk_pixbuf_get_pixels (output);
diff --git a/rsvg-mask.c b/rsvg-mask.c
index da5f31e0..0a292871 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -36,6 +36,7 @@ rsvg_mask_free (RsvgDefVal * self)
{
RsvgMask *z = (RsvgMask *)self;
g_ptr_array_free(z->super.children, TRUE);
+ rsvg_state_finalize (&z->super.super.state);
g_free (z);
}
@@ -53,34 +54,16 @@ rsvg_mask_render (RsvgMask *self, GdkPixbuf *tos, GdkPixbuf *nos, RsvgHandle *ct
drawable = (RsvgDefsDrawable*)self;
- mask = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8,
- gdk_pixbuf_get_width(tos),
- gdk_pixbuf_get_height(tos));
-
- gdk_pixbuf_fill(mask, 0x00000000);
+ mask = _rsvg_pixbuf_new_cleared(GDK_COLORSPACE_RGB, 1, 8,
+ gdk_pixbuf_get_width(tos),
+ gdk_pixbuf_get_height(tos));
save = ctx->pixbuf;
ctx->pixbuf = mask;
-
-/* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
-
+ rsvg_state_push(ctx);
rsvg_defs_drawable_draw (drawable, ctx, 0);
-
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
-
-
+ rsvg_state_pop(ctx);
ctx->pixbuf = save;
@@ -92,7 +75,7 @@ rsvg_mask_render (RsvgMask *self, GdkPixbuf *tos, GdkPixbuf *nos, RsvgHandle *ct
if (!gdk_pixbuf_get_has_alpha (nos))
{
- g_warning ("push/pop transparency group on non-alpha buffer nyi");
+ g_warning (_("push/pop transparency group on non-alpha buffer nyi"));
return;
}
@@ -148,32 +131,19 @@ rsvg_defs_drawable_mask_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
RsvgDefsDrawableGroup *group = (RsvgDefsDrawableGroup*)self;
guint i;
- /* combine state definitions */
- if (ctx->n_state > 1)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
+ rsvg_state_reinherit_top(ctx, &self->state, 0);
if (state->opacity != 0xff || state->filter)
rsvg_push_discrete_layer (ctx);
for (i = 0; i < group->children->len; i++)
{
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
rsvg_defs_drawable_draw (g_ptr_array_index(group->children, i),
ctx, 0);
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
if (state->opacity != 0xff || state->filter)
@@ -201,7 +171,7 @@ rsvg_new_mask (void)
void
rsvg_start_mask (RsvgHandle *ctx, RsvgPropertyBag *atts)
{
- const char *id = NULL, *value;
+ const char *id = NULL, *klazz = NULL, *value;
RsvgMask *mask;
double font_size;
@@ -250,16 +220,24 @@ rsvg_start_mask (RsvgHandle *ctx, RsvgPropertyBag *atts)
font_size);
if ((value = rsvg_property_bag_lookup (atts, "id")))
id = value;
+ if ((value = rsvg_property_bag_lookup (atts, "class")))
+ klazz = value;
}
+
+ rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "mask", klazz, id, atts);
+
mask->super.super.parent = (RsvgDefsDrawable *)ctx->current_defs_group;
ctx->current_defs_group = &mask->super;
+
+ rsvg_state_clone (&mask->super.super.state, rsvg_state_current (ctx));
/* set up the defval stuff */
mask->super.super.super.type = RSVG_DEF_MASK;
mask->super.super.super.free = &rsvg_mask_free;
mask->super.super.draw = &rsvg_defs_drawable_mask_draw;
+
rsvg_defs_set (ctx->defs, id, &mask->super.super.super);
}
@@ -308,6 +286,7 @@ rsvg_clip_path_free (RsvgDefVal * self)
{
RsvgClipPath *z = (RsvgClipPath *)self;
g_ptr_array_free(z->super.children, TRUE);
+ rsvg_state_finalize (&z->super.super.state);
g_free (z);
}
@@ -320,10 +299,8 @@ rsvg_clip_path_render (RsvgClipPath * self, RsvgHandle *ctx)
ArtSVP *svp, *svpx;
svpx = NULL;
-
- /* combine state definitions */
- if (ctx->n_state > 1)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
+
+ rsvg_state_reinherit_top(ctx, &self->super.super.state, 0);
if (self->units == objectBoundingBox)
{
@@ -337,16 +314,7 @@ rsvg_clip_path_render (RsvgClipPath * self, RsvgHandle *ctx)
for (i = 0; i < group->children->len; i++)
{
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
svp = rsvg_defs_drawable_draw_as_svp (g_ptr_array_index(group->children, i),
ctx, 0);
@@ -365,9 +333,7 @@ rsvg_clip_path_render (RsvgClipPath * self, RsvgHandle *ctx)
svpx = svp;
}
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
return svpx;
@@ -388,7 +354,7 @@ rsvg_new_clip_path (void)
void
rsvg_start_clip_path (RsvgHandle *ctx, RsvgPropertyBag *atts)
{
- const char *id = NULL, *value = NULL;
+ const char *id = NULL, *klazz = NULL, *value = NULL;
RsvgClipPath *clip_path;
double font_size;
@@ -406,9 +372,13 @@ rsvg_start_clip_path (RsvgHandle *ctx, RsvgPropertyBag *atts)
}
if ((value = rsvg_property_bag_lookup (atts, "id")))
id = value;
+ if ((value = rsvg_property_bag_lookup (atts, "class")))
+ klazz = value;
}
- rsvg_parse_style_pairs (ctx, rsvg_state_current(ctx), atts);
+ rsvg_parse_style_attrs (ctx, rsvg_state_current (ctx), "clipPath", klazz, id, atts);
+
+ rsvg_state_clone (&clip_path->super.super.state, rsvg_state_current (ctx));
clip_path->super.super.parent = (RsvgDefsDrawable *)ctx->current_defs_group;
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 133bff07..40830f40 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -561,21 +561,14 @@ rsvg_paint_server_pattern_render (RsvgPaintServer *self, ArtRender *ar,
if (maxy > gdk_pixbuf_get_height(hctx->pixbuf))
yoffset = -maxy;
- render = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8,
- gdk_pixbuf_get_width(hctx->pixbuf),
- gdk_pixbuf_get_height(hctx->pixbuf));
-
- gdk_pixbuf_fill(render, 0x00000000);
+ render = _rsvg_pixbuf_new_cleared(GDK_COLORSPACE_RGB, 1, 8,
+ gdk_pixbuf_get_width(hctx->pixbuf),
+ gdk_pixbuf_get_height(hctx->pixbuf));
save = hctx->pixbuf;
hctx->pixbuf = render;
- /* push the state stack */
- if (hctx->n_state == hctx->n_state_max)
- hctx->state = g_renew (RsvgState, hctx->state,
- hctx->n_state_max <<= 1);
- rsvg_state_init (&hctx->state[hctx->n_state]);
- hctx->n_state++;
+ rsvg_state_push(ctx->ctx);
caffine[4] += xoffset;
caffine[5] += yoffset;
@@ -592,9 +585,7 @@ rsvg_paint_server_pattern_render (RsvgPaintServer *self, ArtRender *ar,
else
rsvg_defs_drawable_draw ((RsvgDefsDrawable *)pattern->gfallback, hctx, 2);
- /* pop the state stack */
- hctx->n_state--;
- rsvg_state_finalize (&hctx->state[hctx->n_state]);
+ rsvg_state_pop(ctx->ctx);
hctx->pixbuf = save;
diff --git a/rsvg-private.h b/rsvg-private.h
index 03559753..0c374ec7 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -32,6 +32,7 @@
#include <libxml/xmlmemory.h>
#include <pango/pango.h>
#include <libart_lgpl/art_rect.h>
+#include <glib/gslist.h>
G_BEGIN_DECLS
@@ -62,9 +63,8 @@ struct RsvgHandle {
ArtIRect bbox;
/* stack; there is a state for each element */
- RsvgState *state;
- int n_state;
- int n_state_max;
+
+ GSList * state;
RsvgDefs *defs;
guint in_defs;
@@ -100,6 +100,8 @@ struct RsvgHandle {
void * currentfilter;
void * currentsubfilter;
+ GMemChunk * state_allocator;
+
/* virtual fns */
gboolean (* write) (RsvgHandle *handle,
const guchar *buf,
@@ -181,6 +183,10 @@ void rsvg_handle_set_base_uri (RsvgHandle *handle,
gboolean
rsvg_eval_switch_attributes (RsvgPropertyBag *atts, gboolean * p_has_cond);
+GdkPixbuf *
+_rsvg_pixbuf_new_cleared (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample,
+ int width, int height);
+
G_END_DECLS
#endif
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 3b468987..aee8f6a4 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -512,21 +512,10 @@ static void
rsvg_defs_drawable_path_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
int dominate)
{
- RsvgState *state = rsvg_state_current (ctx);
RsvgDefsDrawablePath *path = (RsvgDefsDrawablePath*)self;
- /* combine state definitions */
-
- rsvg_state_clone (state, &self->state);
- if (ctx->n_state > 1)
- {
- if (dominate)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
- else
- rsvg_state_reinherit(state, &ctx->state[ctx->n_state - 2]);
- }
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
- /* always want to render inside of a <use/> */
rsvg_render_path (ctx, path->d);
}
@@ -535,21 +524,10 @@ static ArtSVP *
rsvg_defs_drawable_path_draw_as_svp (RsvgDefsDrawable * self, RsvgHandle *ctx,
int dominate)
{
- RsvgState *state = rsvg_state_current (ctx);
RsvgDefsDrawablePath *path = (RsvgDefsDrawablePath*)self;
- /* combine state definitions */
-
- rsvg_state_clone (state, &self->state);
- if (ctx->n_state > 1)
- {
- if (dominate)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
- else
- rsvg_state_reinherit(state, &ctx->state[ctx->n_state - 2]);
- }
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
- /* always want to render inside of a <use/> */
return rsvg_render_path_as_svp (ctx, path->d);
}
@@ -567,57 +545,21 @@ static void
rsvg_defs_drawable_group_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
int dominate)
{
-
- RsvgState *state = rsvg_state_current (ctx);
RsvgDefsDrawableGroup *group = (RsvgDefsDrawableGroup*)self;
guint i;
- double tempaffine[6];
- for (i = 0; i < 6; i++)
- {
- tempaffine[i] = ctx->state[ctx->n_state - 1].affine[i];
- }
-
- /* combine state definitions */
- rsvg_state_clone (state, &self->state);
- if (ctx->n_state > 1)
- {
- /*This is a special domination mode for patterns, the style
- is simply reinherited, wheras the transform is totally overridden*/
- if (dominate == 2)
- {
- for (i = 0; i < 6; i++)
- {
- state->affine[i] = tempaffine[i];
- }
- }
- else if (dominate)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
- else
- rsvg_state_reinherit(state, &ctx->state[ctx->n_state - 2]);
- }
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
rsvg_push_discrete_layer (ctx);
for (i = 0; i < group->children->len; i++)
{
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
rsvg_defs_drawable_draw (g_ptr_array_index(group->children, i),
ctx, 0);
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
rsvg_pop_discrete_layer (ctx);
@@ -627,49 +569,17 @@ static ArtSVP *
rsvg_defs_drawable_group_draw_as_svp (RsvgDefsDrawable * self, RsvgHandle *ctx,
int dominate)
{
- RsvgState *state = rsvg_state_current (ctx);
RsvgDefsDrawableGroup *group = (RsvgDefsDrawableGroup*)self;
guint i;
- double tempaffine[6];
ArtSVP *svp1, *svp2, *svp3;
svp1 = NULL;
- for (i = 0; i < 6; i++)
- {
- tempaffine[i] = ctx->state[ctx->n_state - 1].affine[i];
- }
- /* combine state definitions */
- rsvg_state_clone (state, &self->state);
- if (ctx->n_state > 1)
- {
- /*This is a special domination mode for patterns, the style
- is simply reinherited, wheras the transform is totally overridden*/
- if (dominate == 2)
- {
- for (i = 0; i < 6; i++)
- {
- state->affine[i] = tempaffine[i];
- }
- }
- else if (dominate)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
- else
- rsvg_state_reinherit(state, &ctx->state[ctx->n_state - 2]);
- }
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
for (i = 0; i < group->children->len; i++)
{
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
svp2 = rsvg_defs_drawable_draw_as_svp (g_ptr_array_index(group->children, i),
ctx, 0);
@@ -679,10 +589,8 @@ rsvg_defs_drawable_group_draw_as_svp (RsvgDefsDrawable * self, RsvgHandle *ctx,
art_free(svp1);
svp1 = svp3;
}
-
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+
+ rsvg_state_pop(ctx);
}
return svp1;
}
@@ -702,45 +610,45 @@ rsvg_defs_drawable_use_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
RsvgState *state = rsvg_state_current (ctx);
RsvgDefsDrawableUse *use = (RsvgDefsDrawableUse*)self;
- /* combine state definitions */
-
- rsvg_state_clone (state, &self->state);
- if (ctx->n_state > 1)
- {
- if (dominate)
- rsvg_state_dominate(state, &ctx->state[ctx->n_state - 2]);
- else
- rsvg_state_reinherit(state, &ctx->state[ctx->n_state - 2]);
- }
-
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
+
if (state->opacity != 0xff || rsvg_needs_discrete_layer(state))
rsvg_push_discrete_layer (ctx);
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
rsvg_defs_drawable_draw (use->child, ctx, 1);
-
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+
+ rsvg_state_pop(ctx);
if (state->opacity != 0xff || rsvg_needs_discrete_layer(state))
rsvg_pop_discrete_layer (ctx);
+}
+
+static ArtSVP *
+rsvg_defs_drawable_use_draw_as_svp (RsvgDefsDrawable * self, RsvgHandle *ctx,
+ int dominate)
+{
+ RsvgDefsDrawableUse *use = (RsvgDefsDrawableUse*)self;
+ ArtSVP * svp;
+
+ rsvg_state_reinherit_top(ctx, &self->state, dominate);
+
+ rsvg_state_push(ctx);
+
+ svp = rsvg_defs_drawable_draw_as_svp (use->child, ctx, 1);
+
+ rsvg_state_pop(ctx);
+
+ return svp;
}
static void
rsvg_defs_drawable_group_pack (RsvgDefsDrawableGroup *self, RsvgDefsDrawable *child)
{
+ if (self == NULL)
+ return;
RsvgDefsDrawableGroup *z = (RsvgDefsDrawableGroup *)self;
g_ptr_array_add(z->children, child);
}
@@ -1832,7 +1740,9 @@ rsvg_affine_image(GdkPixbuf *img, GdkPixbuf *intermediate,
}
}
-static void
+void rsvg_clip_image(GdkPixbuf *intermediate, ArtSVP *path);
+
+void
rsvg_clip_image(GdkPixbuf *intermediate, ArtSVP *path)
{
gint intstride;
@@ -2038,6 +1948,8 @@ rsvg_start_use (RsvgHandle *ctx, RsvgPropertyBag *atts)
xlink_href = value;
}
+ rsvg_parse_style_attrs (ctx, state, "use", klazz, id, atts);
+
/* < 0 is an error, 0 disables rendering. TODO: handle positive values correctly */
if (got_width || got_height)
if (width <= 0. || height <= 0.)
@@ -2055,33 +1967,25 @@ rsvg_start_use (RsvgHandle *ctx, RsvgPropertyBag *atts)
RsvgDefsDrawableUse * use;
use = g_new (RsvgDefsDrawableUse, 1);
use->child = drawable;
- rsvg_parse_style_attrs (ctx, state, "use", klazz, id, atts);
rsvg_state_clone (&use->super.state, state);
use->super.super.type = RSVG_DEF_PATH;
use->super.super.free = rsvg_defs_drawable_use_free;
use->super.draw = rsvg_defs_drawable_use_draw;
+ use->super.draw_as_svp = rsvg_defs_drawable_use_draw_as_svp;
art_affine_translate(affine, x, y);
art_affine_multiply(use->super.state.affine, affine, use->super.state.affine);
- art_affine_multiply(use->super.state.personal_affine, affine, use->super.state.personal_affine);
+ art_affine_multiply(use->super.state.personal_affine, affine, use->super.state.personal_affine);
+
+ rsvg_defs_set (ctx->defs, id, &use->super.super);
+
+ use->super.parent = (RsvgDefsDrawable *)ctx->current_defs_group;
+ if (use->super.parent != NULL)
+ rsvg_defs_drawable_group_pack((RsvgDefsDrawableGroup *)use->super.parent,
+ &use->super);
if (!ctx->in_defs)
- {
- rsvg_defs_drawable_draw (&use->super, ctx, 1);
- use->super.super.free(&use->super.super);
- break;
- }
- else
- {
- rsvg_defs_set (ctx->defs, id, &use->super.super);
-
- use->super.parent = (RsvgDefsDrawable *)ctx->current_defs_group;
- if (use->super.parent != NULL)
- rsvg_defs_drawable_group_pack((RsvgDefsDrawableGroup *)use->super.parent,
- &use->super);
-
-
- break;
- }
+ rsvg_defs_drawable_draw (&use->super, ctx, 0);
+ break;
}
default:
g_warning (_("Unhandled defs entry/type %s %d\n"), id,
@@ -2246,16 +2150,7 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
art_affine_multiply(affine, affine, taffine);
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state,
- ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
for (i = 0; i < 6; i++)
{
@@ -2265,9 +2160,7 @@ rsvg_marker_render (RsvgMarker *self, gdouble x, gdouble y, gdouble orient, gdou
rsvg_defs_drawable_draw (self->contents, ctx, 2);
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
RsvgDefVal *
diff --git a/rsvg-styles.c b/rsvg-styles.c
index 755b0926..98c6b5c9 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -335,7 +335,6 @@ rsvg_state_dominate (RsvgState *dst, const RsvgState *src)
dst->dash.dash[i] = src->dash.dash[i];
}
art_affine_multiply (dst->affine, dst->personal_affine, src->affine);
-
dst->clippath = src->clippath;
}
@@ -1259,7 +1258,7 @@ rsvg_lookup_apply_css_style (RsvgHandle *ctx, const char * target)
if (value != NULL)
{
- rsvg_parse_style (ctx, &ctx->state[ctx->n_state - 1],
+ rsvg_parse_style (ctx, rsvg_state_current(ctx),
value);
return TRUE;
}
@@ -1397,7 +1396,7 @@ rsvg_push_discrete_layer (RsvgHandle *ctx)
art_u8 *pixels;
int width, height, rowstride;
- state = &ctx->state[ctx->n_state - 1];
+ state = rsvg_state_current(ctx);
pixbuf = ctx->pixbuf;
rsvg_state_clip_path_assure(ctx);
@@ -1530,9 +1529,8 @@ rsvg_compile_bg(RsvgHandle *ctx, RsvgState *topstate)
lastintermediate = gdk_pixbuf_copy(topstate->save_pixbuf);
- for (i = ctx->n_state - 1; i >= 0; i--)
+ for (i = 0; (state = g_slist_nth_data(ctx->state, i)) != NULL; i++)
{
- state = &ctx->state[i];
if (state == topstate)
{
foundstate = 1;
@@ -1674,24 +1672,20 @@ rsvg_needs_discrete_layer(RsvgState *state)
RsvgState *
rsvg_state_current (RsvgHandle *ctx)
{
- if (ctx->n_state > 0)
- return &ctx->state[ctx->n_state - 1];
- return NULL;
+ return g_slist_nth_data(ctx->state, 0);
}
RsvgState *
rsvg_state_parent (RsvgHandle *ctx)
{
- if (ctx->n_state > 1)
- return &ctx->state[ctx->n_state - 2];
- return NULL;
+ return g_slist_nth_data(ctx->state, 1);
}
double
rsvg_state_current_font_size (RsvgHandle *ctx)
{
- if (ctx->n_state > 0)
- return ctx->state[ctx->n_state - 1].font_size;
+ if (rsvg_state_current(ctx) != NULL)
+ return rsvg_state_current(ctx)->font_size;
else
return 12.0;
}
@@ -1744,13 +1738,18 @@ rsvg_state_clip_path_assure(RsvgHandle * ctx)
if (state->clip_path_ref && !state->clip_path_loaded)
{
+ rsvg_state_push(ctx);
+
tmppath = rsvg_clip_path_render (state->clip_path_ref, ctx);
+
+ rsvg_state_pop(ctx);
+
state->clip_path_loaded = TRUE;
}
else
return;
- if (state->clippath)
+ if (state->clippath != NULL && tmppath != NULL)
{
tmppath2 = art_svp_intersect(tmppath, state->clippath);
art_free(tmppath);
@@ -1759,3 +1758,64 @@ rsvg_state_clip_path_assure(RsvgHandle * ctx)
else
state->clippath = tmppath;
}
+
+void
+rsvg_state_push(RsvgHandle * ctx)
+{
+ RsvgState * data;
+ RsvgState * baseon;
+
+ baseon = (RsvgState *)g_slist_nth_data(ctx->state, 0);
+ data = g_chunk_new(RsvgState, ctx->state_allocator);
+
+ if (baseon)
+ rsvg_state_inherit(data, baseon);
+ else
+ rsvg_state_init(data);
+
+ ctx->state = g_slist_prepend(ctx->state, data);
+}
+
+void
+rsvg_state_pop(RsvgHandle * ctx)
+{
+ RsvgState * toremove = g_slist_nth_data(ctx->state, 0);
+ rsvg_state_finalize (toremove);
+ ctx->state = g_slist_remove(ctx->state, toremove);
+ g_mem_chunk_free(ctx->state_allocator, toremove);
+}
+
+void
+rsvg_state_reinherit_top(RsvgHandle * ctx, RsvgState * state, int dominate)
+{
+ double tempaffine[6];
+ gint i;
+ RsvgState * baseon;
+
+ baseon = rsvg_state_parent(ctx);
+
+ for (i = 0; i < 6; i++)
+ {
+ tempaffine[i] = rsvg_state_current(ctx)->affine[i];
+ }
+
+ /* combine state definitions */
+ rsvg_state_clone (rsvg_state_current(ctx), state);
+
+ if (baseon)
+ {
+ /*This is a special domination mode for patterns, the style
+ is simply left as is, wheras the transform is totally overridden*/
+ if (dominate == 2)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ rsvg_state_current(ctx)->affine[i] = tempaffine[i];
+ }
+ }
+ else if (dominate)
+ rsvg_state_dominate(rsvg_state_current(ctx), baseon);
+ else
+ rsvg_state_reinherit(rsvg_state_current(ctx), baseon);
+ }
+}
diff --git a/rsvg-styles.h b/rsvg-styles.h
index a6958288..15378666 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -185,6 +185,11 @@ double rsvg_state_current_font_size (RsvgHandle *ctx);
void rsvg_state_clip_path_assure(RsvgHandle * ctx);
+void rsvg_state_pop(RsvgHandle * ctx);
+void rsvg_state_push(RsvgHandle * ctx);
+
+void rsvg_state_reinherit_top(RsvgHandle * ctx, RsvgState * state, int dominate);
+
G_END_DECLS
#endif /* RSVG_STYLES_H */
diff --git a/rsvg-text.c b/rsvg-text.c
index c7fc8385..7c33807f 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -293,15 +293,7 @@ rsvg_text_handler_start (RsvgSaxHandler *self, const xmlChar *name,
RsvgSaxHandlerText *z = (RsvgSaxHandlerText *)self;
RsvgHandle *ctx = z->ctx;
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state, ctx->n_state_max <<= 1);
- if (ctx->n_state)
- rsvg_state_clone (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
/* this should be the only thing starting inside of text */
if (!strcmp ((char *)name, "tspan"))
@@ -330,9 +322,7 @@ rsvg_text_handler_end (RsvgSaxHandler *self, const xmlChar *name)
}
}
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
void
diff --git a/rsvg.c b/rsvg.c
index 6842c1b0..56fddb32 100644
--- a/rsvg.c
+++ b/rsvg.c
@@ -1058,9 +1058,7 @@ rsvg_desc_handler_end (RsvgSaxHandler *self, const xmlChar *name)
}
}
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
static void
@@ -1135,9 +1133,7 @@ rsvg_title_handler_end (RsvgSaxHandler *self, const xmlChar *name)
}
}
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+ rsvg_state_pop(ctx);
}
static void
@@ -1173,17 +1169,7 @@ rsvg_start_element (void *data, const xmlChar *name,
}
else
{
- /* push the state stack */
- if (ctx->n_state == ctx->n_state_max)
- ctx->state = g_renew (RsvgState, ctx->state, ctx->n_state_max <<= 1);
- if (ctx->n_state)
- {
- rsvg_state_inherit (&ctx->state[ctx->n_state],
- &ctx->state[ctx->n_state - 1]);
- }
- else
- rsvg_state_init (ctx->state);
- ctx->n_state++;
+ rsvg_state_push(ctx);
if (!strcmp ((char *)name, "svg"))
{
@@ -1315,9 +1301,8 @@ rsvg_end_element (void *data, const xmlChar *name)
ctx->in_defs--;
rsvg_pop_def_group(ctx);
}
- /* pop the state stack */
- ctx->n_state--;
- rsvg_state_finalize (&ctx->state[ctx->n_state]);
+
+ rsvg_state_pop(ctx);
}
}
@@ -1475,18 +1460,23 @@ rsvg_handle_close_impl (RsvgHandle *handle,
return TRUE;
}
+static void
+rsvg_state_free_func(gpointer data, gpointer user_data)
+{
+ RsvgHandle * ctx = (RsvgHandle *)user_data;
+ rsvg_state_finalize((RsvgState *)data);
+ g_mem_chunk_free(ctx->state_allocator, data);
+}
+
void
rsvg_handle_free_impl (RsvgHandle *handle)
{
- int i;
-
if (handle->pango_context != NULL)
g_object_unref (handle->pango_context);
rsvg_defs_free (handle->defs);
- for (i = 0; i < handle->n_state; i++)
- rsvg_state_finalize (&handle->state[i]);
- g_free (handle->state);
+ g_slist_foreach(handle->state, rsvg_state_free_func, (gpointer)handle);
+ g_slist_free (handle->state);
g_hash_table_foreach (handle->entities, rsvg_ctx_free_helper, NULL);
g_hash_table_destroy (handle->entities);
@@ -1506,6 +1496,8 @@ rsvg_handle_free_impl (RsvgHandle *handle)
if (handle->base_uri)
g_free (handle->base_uri);
+ g_mem_chunk_destroy(handle->state_allocator);
+
g_free (handle);
}
@@ -1569,9 +1561,7 @@ rsvg_handle_new (void)
void
rsvg_handle_init (RsvgHandle * handle)
{
- handle->n_state = 0;
- handle->n_state_max = 16;
- handle->state = g_new (RsvgState, handle->n_state_max);
+ handle->state = NULL;
handle->defs = rsvg_defs_new ();
handle->handler_nest = 0;
handle->entities = g_hash_table_new (g_str_hash, g_str_equal);
@@ -1586,6 +1576,11 @@ rsvg_handle_init (RsvgHandle * handle)
handle->current_defs_group = NULL;
handle->title = g_string_new (NULL);
handle->desc = g_string_new (NULL);
+
+ /* should this be G_ALLOC_ONLY? */
+ handle->state_allocator = g_mem_chunk_create (RsvgState, 256, G_ALLOC_AND_FREE);
+
+ rsvg_state_push(handle);
}
/**