[librsvg/wip/otte: 3/39] paint-server: Resolve references when rendering



commit 335c51d917b99a949331952089f27e5e353ad050
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 7 02:02:05 2015 +0200

    paint-server: Resolve references when rendering
    
    Do not resolve them while parsing or building the document tree.
    
    The reason for this will become apparent in a few commits.

 rsvg-cairo-draw.c   |    6 ++--
 rsvg-paint-server.c |   88 +++++++++++++++++++++++++++++++++------------------
 rsvg-paint-server.h |   15 +++++---
 3 files changed, 69 insertions(+), 40 deletions(-)
---
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 6c3b2eb..61378a7 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -78,7 +78,7 @@ _set_source_rsvg_linear_gradient (RsvgDrawingCtx * ctx,
     RsvgLinearGradient statlinear;
     statlinear = *linear;
     linear = &statlinear;
-    rsvg_linear_gradient_fix_fallback (linear);
+    rsvg_linear_gradient_fix_fallback (ctx, linear);
 
     if (linear->has_current_color)
         current_color_rgb = linear->current_color;
@@ -122,7 +122,7 @@ _set_source_rsvg_radial_gradient (RsvgDrawingCtx * ctx,
     RsvgRadialGradient statradial;
     statradial = *radial;
     radial = &statradial;
-    rsvg_radial_gradient_fix_fallback (radial);
+    rsvg_radial_gradient_fix_fallback (ctx, radial);
 
     if (radial->has_current_color)
         current_color_rgb = radial->current_color;
@@ -192,7 +192,7 @@ _set_source_rsvg_pattern (RsvgDrawingCtx * ctx,
     int pw, ph;
 
     rsvg_pattern = &local_pattern;
-    rsvg_pattern_fix_fallback (rsvg_pattern);
+    rsvg_pattern_fix_fallback (ctx, rsvg_pattern);
     cr_render = render->cr;
 
     if (rsvg_pattern->obj_bbox)
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 07d8180..6fe17b3 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -270,10 +270,8 @@ rsvg_linear_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
             }
             grad->hasspread = TRUE;
         }
-        if ((value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
-            if (self != rsvg_defs_lookup (ctx->priv->defs, value))
-                rsvg_defs_add_resolver (ctx->priv->defs, &grad->fallback, value);
-       }
+        g_free (grad->fallback);
+        grad->fallback = g_strdup (rsvg_property_bag_lookup (atts, "xlink:href"));
         if ((value = rsvg_property_bag_lookup (atts, "gradientTransform"))) {
             rsvg_parse_transform (&grad->affine, value);
             grad->hastransform = TRUE;
@@ -291,6 +289,13 @@ rsvg_linear_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
     }
 }
 
+static void
+rsvg_linear_gradient_free (RsvgNode * node)
+{
+    RsvgLinearGradient *self = (RsvgLinearGradient *) node;
+    g_free (self->fallback);
+    _rsvg_node_free (node);
+}
 
 RsvgNode *
 rsvg_new_linear_gradient (void)
@@ -305,6 +310,7 @@ rsvg_new_linear_gradient (void)
     grad->fallback = NULL;
     grad->obj_bbox = TRUE;
     grad->spread = CAIRO_EXTEND_PAD;
+    grad->super.free = rsvg_linear_gradient_free;
     grad->super.set_atts = rsvg_linear_gradient_set_atts;
     grad->hasx1 = grad->hasy1 = grad->hasx2 = grad->hasy2 = grad->hasbbox = grad->hasspread =
         grad->hastransform = FALSE;
@@ -344,10 +350,8 @@ rsvg_radial_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
             grad->fy = _rsvg_css_parse_length (value);
             grad->hasfy = TRUE;
         }
-        if ((value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
-            if (self != rsvg_defs_lookup (ctx->priv->defs, value))
-                rsvg_defs_add_resolver (ctx->priv->defs, &grad->fallback, value);
-        }
+        g_free (grad->fallback);
+        grad->fallback = g_strdup (rsvg_property_bag_lookup (atts, "xlink:href"));
         if ((value = rsvg_property_bag_lookup (atts, "gradientTransform"))) {
             rsvg_parse_transform (&grad->affine, value);
             grad->hastransform = TRUE;
@@ -375,6 +379,14 @@ rsvg_radial_gradient_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBa
     }
 }
 
+static void
+rsvg_radial_gradient_free (RsvgNode * node)
+{
+    RsvgRadialGradient *self = (RsvgRadialGradient *) node;
+    g_free (self->fallback);
+    _rsvg_node_free (node);
+}
+
 RsvgNode *
 rsvg_new_radial_gradient (void)
 {
@@ -387,6 +399,7 @@ rsvg_new_radial_gradient (void)
     grad->spread = CAIRO_EXTEND_PAD;
     grad->fallback = NULL;
     grad->cx = grad->cy = grad->r = grad->fx = grad->fy = _rsvg_css_parse_length ("0.5");
+    grad->super.free = rsvg_radial_gradient_free;
     grad->super.set_atts = rsvg_radial_gradient_set_atts;
     grad->hascx = grad->hascy = grad->hasfx = grad->hasfy = grad->hasr = grad->hasbbox =
         grad->hasspread = grad->hastransform = FALSE;
@@ -422,16 +435,8 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts
             pattern->height = _rsvg_css_parse_length (value);
             pattern->hasheight = TRUE;
         }
-        if ((value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
-            if (self != rsvg_defs_lookup (ctx->priv->defs, value)) {
-                /* The (void *) cast is to avoid a GCC warning like:
-                 * "warning: dereferencing type-punned pointer will break strict-aliasing rules"
-                 * which is wrong for this code. (void *) introduces a compatible
-                 * intermediate type in the cast list. */
-                rsvg_defs_add_resolver (ctx->priv->defs, (RsvgNode **) (void *) &pattern->fallback,
-                                        value);
-            }
-        }
+        g_free (pattern->fallback);
+        pattern->fallback = g_strdup (rsvg_property_bag_lookup (atts, "xlink:href"));
         if ((value = rsvg_property_bag_lookup (atts, "patternTransform"))) {
             rsvg_parse_transform (&pattern->affine, value);
             pattern->hastransform = TRUE;
@@ -457,6 +462,14 @@ rsvg_pattern_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts
     }
 }
 
+static void
+rsvg_pattern_free (RsvgNode * node)
+{
+    RsvgPattern *self = (RsvgPattern *) node;
+    g_free (self->fallback);
+    _rsvg_node_free (node);
+}
+
 
 RsvgNode *
 rsvg_new_pattern (void)
@@ -470,6 +483,7 @@ rsvg_new_pattern (void)
     pattern->fallback = NULL;
     pattern->preserve_aspect_ratio = RSVG_ASPECT_RATIO_XMID_YMID;
     pattern->vbox.active = FALSE;
+    pattern->super.free = rsvg_pattern_free;
     pattern->super.set_atts = rsvg_pattern_set_atts;
     pattern->hasx = pattern->hasy = pattern->haswidth = pattern->hasheight = pattern->hasbbox =
         pattern->hascbox = pattern->hasvbox = pattern->hasaspect = pattern->hastransform = FALSE;
@@ -488,7 +502,7 @@ hasstop (GPtrArray * lookin)
     return 0;
 }
 
-typedef gpointer (* GetFallbackFn) (gpointer data);
+typedef const char * (* GetFallbackFn) (gpointer data);
 typedef void (* ApplyFallbackFn) (gpointer data, gpointer fallback_data);
 
 /* Some SVG paint servers can reference a "parent" or "fallback" paint server
@@ -515,7 +529,8 @@ typedef void (* ApplyFallbackFn) (gpointer data, gpointer fallback_data);
  * structure types.
  */
 static void
-resolve_fallbacks (gpointer data,
+resolve_fallbacks (RsvgDrawingCtx *ctx,
+                   gpointer data,
                    GetFallbackFn get_fallback,
                    ApplyFallbackFn apply_fallback)
 {
@@ -528,28 +543,36 @@ resolve_fallbacks (gpointer data,
 
     while (hare) {
         gpointer fallback;
+        const char *fallback_id;
 
-        fallback = get_fallback (hare);
+        fallback_id = get_fallback (hare);
+        if (fallback_id == NULL)
+          break;
+        fallback = rsvg_defs_lookup (ctx->defs, fallback_id);
         if (fallback)
             apply_fallback (data, fallback);
 
         hare = fallback;
 
         if (hare) {
-            fallback = get_fallback (hare);
+            fallback_id = get_fallback (hare);
+            if (fallback_id == NULL)
+              break;
+            fallback = rsvg_defs_lookup (ctx->defs, fallback_id);
             if (fallback)
                 apply_fallback (data, fallback);
 
             hare = fallback;
         }
 
-        tortoise = get_fallback (tortoise);
+        fallback_id = get_fallback (tortoise);
+        tortoise = rsvg_defs_lookup (ctx->defs, fallback_id);
         if (tortoise == hare)
             break;
     }
 }
 
-static gpointer
+static const char *
 gradient_get_fallback (gpointer data)
 {
     RsvgNode *node;
@@ -634,9 +657,10 @@ linear_gradient_apply_fallback (gpointer data, gpointer fallback_data)
 }
 
 void
-rsvg_linear_gradient_fix_fallback (RsvgLinearGradient * grad)
+rsvg_linear_gradient_fix_fallback (RsvgDrawingCtx *ctx, RsvgLinearGradient * grad)
 {
-    resolve_fallbacks (grad,
+    resolve_fallbacks (ctx,
+                       grad,
                        gradient_get_fallback,
                        linear_gradient_apply_fallback);
 }
@@ -714,14 +738,15 @@ radial_gradient_apply_fallback (gpointer data, gpointer fallback_data)
 }
 
 void
-rsvg_radial_gradient_fix_fallback (RsvgRadialGradient * grad)
+rsvg_radial_gradient_fix_fallback (RsvgDrawingCtx *ctx, RsvgRadialGradient * grad)
 {
-    resolve_fallbacks (grad,
+    resolve_fallbacks (ctx,
+                       grad,
                        gradient_get_fallback,
                        radial_gradient_apply_fallback);
 }
 
-static gpointer
+static const char *
 pattern_get_fallback (gpointer data)
 {
     RsvgNode *node = data;
@@ -794,9 +819,10 @@ pattern_apply_fallback (gpointer data, gpointer fallback_data)
 }
 
 void
-rsvg_pattern_fix_fallback (RsvgPattern * pattern)
+rsvg_pattern_fix_fallback (RsvgDrawingCtx *ctx, RsvgPattern * pattern)
 {
-    resolve_fallbacks (pattern,
+    resolve_fallbacks (ctx,
+                       pattern,
                        pattern_get_fallback,
                        pattern_apply_fallback);
 }
diff --git a/rsvg-paint-server.h b/rsvg-paint-server.h
index 65a7060..e6c884c 100644
--- a/rsvg-paint-server.h
+++ b/rsvg-paint-server.h
@@ -65,7 +65,7 @@ struct _RsvgLinearGradient {
     int hasbbox:1;
     int hasspread:1;
     int hastransform:1;
-    RsvgNode *fallback;
+    char *fallback;
 };
 
 struct _RsvgRadialGradient {
@@ -84,7 +84,7 @@ struct _RsvgRadialGradient {
     int hasspread:1;
     int hasbbox:1;
     int hastransform:1;
-    RsvgNode *fallback;
+    char *fallback;
 };
 
 struct _RsvgPattern {
@@ -104,7 +104,7 @@ struct _RsvgPattern {
     int hascbox:1;
     int hasbbox:1;
     int hastransform:1;
-    RsvgPattern *fallback;
+    char *fallback;
 };
 
 struct _RsvgSolidColour {
@@ -159,11 +159,14 @@ RsvgNode *rsvg_new_stop           (void);
 G_GNUC_INTERNAL
 RsvgNode *rsvg_new_pattern      (void);
 G_GNUC_INTERNAL
-void rsvg_pattern_fix_fallback          (RsvgPattern * pattern);
+void rsvg_pattern_fix_fallback          (RsvgDrawingCtx * ctx,
+                                         RsvgPattern * pattern);
 G_GNUC_INTERNAL
-void rsvg_linear_gradient_fix_fallback (RsvgLinearGradient * grad);
+void rsvg_linear_gradient_fix_fallback (RsvgDrawingCtx * ctx,
+                                         RsvgLinearGradient * grad);
 G_GNUC_INTERNAL
-void rsvg_radial_gradient_fix_fallback (RsvgRadialGradient * grad);
+void rsvg_radial_gradient_fix_fallback (RsvgDrawingCtx * ctx,
+                                         RsvgRadialGradient * grad);
 
 G_END_DECLS
 


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