Commit 6cfaab12 authored by Benjamin Otte's avatar Benjamin Otte

state: Look up clip path lazily

parent d1c91919
......@@ -458,7 +458,7 @@ rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
double backup_tolerance;
need_tmpbuf = ((state->fill != NULL) && (state->stroke != NULL) && state->opacity != 0xff)
|| state->clip_path_ref || state->mask || state->filter
|| state->clip_path || state->mask || state->filter
|| (state->comp_op != CAIRO_OPERATOR_OVER);
if (need_tmpbuf)
......@@ -716,18 +716,6 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
cairo_surface_destroy (surface);
}
static void
rsvg_cairo_push_early_clips (RsvgDrawingCtx * ctx)
{
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
cairo_save (render->cr);
if (rsvg_current_state (ctx)->clip_path_ref)
if (((RsvgClipPath *) rsvg_current_state (ctx)->clip_path_ref)->units == userSpaceOnUse)
rsvg_cairo_clip (ctx, rsvg_current_state (ctx)->clip_path_ref, NULL);
}
static void
rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
{
......@@ -740,9 +728,27 @@ rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
RsvgState *state = rsvg_current_state (ctx);
gboolean lateclip = FALSE;
if (rsvg_current_state (ctx)->clip_path_ref)
if (((RsvgClipPath *) rsvg_current_state (ctx)->clip_path_ref)->units == objectBoundingBox)
lateclip = TRUE;
if (rsvg_current_state (ctx)->clip_path) {
RsvgNode *node;
node = rsvg_defs_lookup (ctx->defs, rsvg_current_state (ctx)->clip_path);
if (node && RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_CLIP_PATH) {
RsvgClipPath *clip_path = (RsvgClipPath *) node;
switch (clip_path->units) {
case userSpaceOnUse:
rsvg_cairo_clip (ctx, clip_path, NULL);
break;
case objectBoundingBox:
lateclip = TRUE;
break;
default:
g_assert_not_reached ();
break;
}
}
}
if (state->opacity == 0xFF
&& !state->filter && !state->mask && !lateclip && (state->comp_op == CAIRO_OPERATOR_OVER)
......@@ -783,7 +789,9 @@ rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
void
rsvg_cairo_push_discrete_layer (RsvgDrawingCtx * ctx)
{
rsvg_cairo_push_early_clips (ctx);
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
cairo_save (render->cr);
rsvg_cairo_push_render_stack (ctx);
}
......@@ -792,14 +800,18 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
{
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
cairo_t *child_cr = render->cr;
gboolean lateclip = FALSE;
RsvgClipPath *lateclip = NULL;
cairo_surface_t *surface = NULL;
RsvgState *state = rsvg_current_state (ctx);
gboolean nest;
if (rsvg_current_state (ctx)->clip_path_ref)
if (((RsvgClipPath *) rsvg_current_state (ctx)->clip_path_ref)->units == objectBoundingBox)
lateclip = TRUE;
if (rsvg_current_state (ctx)->clip_path) {
RsvgNode *node;
node = rsvg_defs_lookup (ctx->defs, rsvg_current_state (ctx)->clip_path);
if (node && RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_CLIP_PATH
&& ((RsvgClipPath *) node)->units == objectBoundingBox)
lateclip = (RsvgClipPath *) node;
}
if (state->opacity == 0xFF
&& !state->filter && !state->mask && !lateclip && (state->comp_op == CAIRO_OPERATOR_OVER)
......@@ -829,7 +841,7 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
nest ? 0 : render->offset_y);
if (lateclip)
rsvg_cairo_clip (ctx, rsvg_current_state (ctx)->clip_path_ref, &render->bbox);
rsvg_cairo_clip (ctx, lateclip, &render->bbox);
cairo_set_operator (render->cr, state->comp_op);
......
......@@ -102,23 +102,6 @@ rsvg_get_url_string (const char *str)
return NULL;
}
RsvgNode *
rsvg_clip_path_parse (const RsvgDefs * defs, const char *str)
{
char *name;
name = rsvg_get_url_string (str);
if (name) {
RsvgNode *val;
val = rsvg_defs_lookup (defs, name);
g_free (name);
if (val && RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_CLIP_PATH)
return val;
}
return NULL;
}
static void
rsvg_clip_path_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
{
......
......@@ -58,8 +58,6 @@ struct _RsvgClipPath {
G_GNUC_INTERNAL
RsvgNode *rsvg_new_clip_path (void);
G_GNUC_INTERNAL
RsvgNode *rsvg_clip_path_parse (const RsvgDefs * defs, const char *str);
G_END_DECLS
#endif
......@@ -149,7 +149,7 @@ rsvg_state_init (RsvgState * state)
state->visible = TRUE;
state->cond_true = TRUE;
state->filter = NULL;
state->clip_path_ref = NULL;
state->clip_path = NULL;
state->startMarker = NULL;
state->middleMarker = NULL;
state->endMarker = NULL;
......@@ -222,6 +222,7 @@ rsvg_state_clone (RsvgState * dst, const RsvgState * src)
*dst = *src;
dst->parent = parent;
dst->mask = g_strdup (src->mask);
dst->clip_path = g_strdup (src->clip_path);
dst->font_family = g_strdup (src->font_family);
dst->lang = g_strdup (src->lang);
rsvg_paint_server_ref (dst->fill);
......@@ -356,7 +357,8 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
}
if (inherituninheritables) {
dst->clip_path_ref = src->clip_path_ref;
g_free (dst->clip_path);
dst->clip_path = g_strdup (src->clip_path);
g_free (dst->mask);
dst->mask = g_strdup (src->mask);
dst->enable_background = src->enable_background;
......@@ -447,6 +449,7 @@ void
rsvg_state_finalize (RsvgState * state)
{
g_free (state->mask);
g_free (state->clip_path);
g_free (state->font_family);
g_free (state->lang);
rsvg_paint_server_unref (state->fill);
......@@ -524,7 +527,8 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
g_free (state->mask);
state->mask = rsvg_get_url_string (value);
} else if (g_str_equal (name, "clip-path")) {
state->clip_path_ref = rsvg_clip_path_parse (ctx->priv->defs, value);
g_free (state->clip_path);
state->clip_path = rsvg_get_url_string (value);
} else if (g_str_equal (name, "overflow")) {
if (!g_str_equal (value, "inherit")) {
state->overflow = rsvg_css_parse_overflow (value, &state->has_overflow);
......
......@@ -81,7 +81,7 @@ struct _RsvgState {
RsvgFilter *filter;
char *mask;
void *clip_path_ref;
char *clip_path;
guint8 adobe_blend; /* 0..11 */
guint8 opacity; /* 0..255 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment