[librsvg] paint-server: Resolve references when rendering
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] paint-server: Resolve references when rendering
- Date: Thu, 22 Oct 2015 11:12:09 +0000 (UTC)
commit a6466fa562e69bcaaafc466d92681d1103a5ffd3
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]