Commit 72891ffc authored by Caleb Michael Moore's avatar Caleb Michael Moore

heaps o' small bufixes

parent 5156516c
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
......
......@@ -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
/*************************************************************/
......@@ -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;
......@@ -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)
{
......@@ -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"));
}
/*************************************************************/
......@@ -4022,24 +4046,13 @@ rsvg_filter_primitive_image_render_in (RsvgFilterPrimitive * self,
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;
......
......@@ -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);
}
......@@ -62,24 +63,11 @@ rsvg_mask_render (RsvgMask *self, GdkPixbuf *tos, GdkPixbuf *nos, RsvgHandle *ct
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;
......@@ -148,32 +136,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)
......@@ -252,14 +227,19 @@ rsvg_start_mask (RsvgHandle *ctx, RsvgPropertyBag *atts)
id = value;
}
rsvg_parse_style_pairs (ctx, rsvg_state_current(ctx), 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 +288,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);
}
......@@ -321,9 +302,7 @@ 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 +316,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 +335,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;
......@@ -413,6 +381,8 @@ rsvg_start_clip_path (RsvgHandle *ctx, RsvgPropertyBag *atts)
clip_path->super.super.parent = (RsvgDefsDrawable *)ctx->current_defs_group;
ctx->current_defs_group = &clip_path->super;
rsvg_state_clone (&clip_path->super.super.state, rsvg_state_current (ctx));
/* set up the defval stuff */
clip_path->super.super.super.type = RSVG_DEF_CLIP_PATH;
......
......@@ -570,12 +570,7 @@ rsvg_paint_server_pattern_render (RsvgPaintServer *self, ArtRender *ar,
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 +587,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;
......
......@@ -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;
......
......@@ -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_reinherit_top(ctx, &self->state, dominate);
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]);
}
/* 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,37 +610,17 @@ 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);
......@@ -741,6 +629,8 @@ rsvg_defs_drawable_use_draw (RsvgDefsDrawable * self, RsvgHandle *ctx,
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 +1722,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 +1930,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 +1949,24 @@ 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;
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 +2131,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 +2141,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 *
......
......@@ -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,59 @@ rsvg_state_clip_path_assure(RsvgHandle * ctx)
else
state->clippath = tmppath;
}
void
rsvg_state_push(RsvgHandle * ctx)
{
RsvgState * data;
RsvgState * baseon = g_slist_nth_data(ctx->state, 0);
data = g_new(RsvgState, 1);
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);
}
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);