[librsvg/wip/otte: 5/39] state: Look up clip path lazily



commit b9515d8d2fa903307f26cedfb035807496dd8dec
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 7 07:57:39 2015 +0200

    state: Look up clip path lazily

 rsvg-cairo-draw.c |   56 ++++++++++++++++++++++++++++++++--------------------
 rsvg-mask.c       |   17 ----------------
 rsvg-mask.h       |    2 -
 rsvg-styles.c     |   10 ++++++--
 rsvg-styles.h     |    2 +-
 5 files changed, 42 insertions(+), 45 deletions(-)
---
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 187ee4e..816235c 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -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)
@@ -717,18 +717,6 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgMask * self, RsvgDrawingCtx * ctx, R
 }
 
 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)
 {
     /* XXX: Untested, probably needs help wrt filters */
@@ -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);
 
diff --git a/rsvg-mask.c b/rsvg-mask.c
index 959ffa0..44dd100 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -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)
 {
diff --git a/rsvg-mask.h b/rsvg-mask.h
index 48bb7f0..bb6e4e2 100644
--- a/rsvg-mask.h
+++ b/rsvg-mask.h
@@ -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
diff --git a/rsvg-styles.c b/rsvg-styles.c
index 1db34f4..dec8937 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -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);
diff --git a/rsvg-styles.h b/rsvg-styles.h
index 472a6c0..92cc48f 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -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 */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]