Commit 1c68e4f2 authored by Benjamin Otte's avatar Benjamin Otte

paint-server: Store URL instead of resolved node

This way, we resolve lazily only upon use and thereby can make use of
our amazing new cycle detection technology.
parent f85f5dea
......@@ -330,19 +330,24 @@ _set_source_rsvg_paint_server (RsvgDrawingCtx * ctx,
RsvgPaintServer * ps,
guint8 opacity, RsvgBbox bbox, guint32 current_colour)
{
RsvgNode *node;
switch (ps->type) {
case RSVG_PAINT_SERVER_LIN_GRAD:
_set_source_rsvg_linear_gradient (ctx, ps->core.lingrad, current_color_rgb, opacity, bbox);
break;
case RSVG_PAINT_SERVER_RAD_GRAD:
_set_source_rsvg_radial_gradient (ctx, ps->core.radgrad, current_color_rgb, opacity, bbox);
case RSVG_PAINT_SERVER_IRI:
node = rsvg_acquire_node (ctx, ps->core.iri);
if (node == NULL)
break;
else if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_LINEAR_GRADIENT)
_set_source_rsvg_linear_gradient (ctx, (RsvgLinearGradient *) node, current_color_rgb, opacity, bbox);
else if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_RADIAL_GRADIENT)
_set_source_rsvg_radial_gradient (ctx, (RsvgRadialGradient *) node, current_color_rgb, opacity, bbox);
else if (RSVG_NODE_TYPE (node) == RSVG_NODE_TYPE_PATTERN)
_set_source_rsvg_pattern (ctx, (RsvgPattern *) node, opacity, bbox);
rsvg_release_node (ctx, node);
break;
case RSVG_PAINT_SERVER_SOLID:
_set_source_rsvg_solid_colour (ctx, ps->core.colour, opacity, current_colour);
break;
case RSVG_PAINT_SERVER_PATTERN:
_set_source_rsvg_pattern (ctx, ps->core.pattern, opacity, bbox);
break;
}
}
......
......@@ -64,44 +64,19 @@ rsvg_paint_server_solid_current_colour (void)
}
static RsvgPaintServer *
rsvg_paint_server_lin_grad (RsvgLinearGradient * gradient)
rsvg_paint_server_iri (char *iri)
{
RsvgPaintServer *result = g_new (RsvgPaintServer, 1);
result->refcnt = 1;
result->type = RSVG_PAINT_SERVER_LIN_GRAD;
result->core.lingrad = gradient;
return result;
}
static RsvgPaintServer *
rsvg_paint_server_rad_grad (RsvgRadialGradient * gradient)
{
RsvgPaintServer *result = g_new (RsvgPaintServer, 1);
result->refcnt = 1;
result->type = RSVG_PAINT_SERVER_RAD_GRAD;
result->core.radgrad = gradient;
return result;
}
static RsvgPaintServer *
rsvg_paint_server_pattern (RsvgPattern * pattern)
{
RsvgPaintServer *result = g_new (RsvgPaintServer, 1);
result->refcnt = 1;
result->type = RSVG_PAINT_SERVER_PATTERN;
result->core.pattern = pattern;
result->type = RSVG_PAINT_SERVER_IRI;
result->core.iri = iri;
return result;
}
/**
* rsvg_paint_server_parse:
* @defs: Defs for looking up gradients.
* @str: The SVG paint specification string to parse.
*
* Parses the paint specification @str, creating a new paint server
......@@ -111,7 +86,7 @@ rsvg_paint_server_pattern (RsvgPattern * pattern)
* on error.
**/
RsvgPaintServer *
rsvg_paint_server_parse (gboolean * inherit, const RsvgDefs * defs, const char *str)
rsvg_paint_server_parse (gboolean * inherit, const char *str)
{
char *name;
guint32 argb;
......@@ -122,20 +97,7 @@ rsvg_paint_server_parse (gboolean * inherit, const RsvgDefs * defs, const char *
name = rsvg_get_url_string (str);
if (name) {
RsvgNode *val;
val = rsvg_defs_lookup (defs, name);
g_free (name);
if (val == NULL)
return NULL;
if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_LINEAR_GRADIENT)
return rsvg_paint_server_lin_grad ((RsvgLinearGradient *) val);
else if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_RADIAL_GRADIENT)
return rsvg_paint_server_rad_grad ((RsvgRadialGradient *) val);
else if (RSVG_NODE_TYPE (val) == RSVG_NODE_TYPE_PATTERN)
return rsvg_paint_server_pattern ((RsvgPattern *) val);
else
return NULL;
return rsvg_paint_server_iri (name);
} else if (!strcmp (str, "inherit")) {
if (inherit != NULL)
*inherit = 0;
......@@ -178,6 +140,8 @@ rsvg_paint_server_unref (RsvgPaintServer * ps)
if (--ps->refcnt == 0) {
if (ps->type == RSVG_PAINT_SERVER_SOLID)
g_free (ps->core.colour);
else if (ps->type == RSVG_PAINT_SERVER_IRI)
g_free (ps->core.iri);
g_free (ps);
}
}
......
......@@ -117,17 +117,13 @@ typedef enum _RsvgPaintServerType RsvgPaintServerType;
typedef union _RsvgPaintServerCore RsvgPaintServerCore;
union _RsvgPaintServerCore {
RsvgLinearGradient *lingrad;
RsvgRadialGradient *radgrad;
RsvgSolidColour *colour;
RsvgPattern *pattern;
char *iri;
};
enum _RsvgPaintServerType {
RSVG_PAINT_SERVER_RAD_GRAD,
RSVG_PAINT_SERVER_LIN_GRAD,
RSVG_PAINT_SERVER_SOLID,
RSVG_PAINT_SERVER_PATTERN
RSVG_PAINT_SERVER_IRI
};
struct _RsvgPaintServer {
......@@ -138,8 +134,7 @@ struct _RsvgPaintServer {
/* Create a new paint server based on a specification string. */
G_GNUC_INTERNAL
RsvgPaintServer *rsvg_paint_server_parse (gboolean * inherit, const RsvgDefs * defs,
const char *str);
RsvgPaintServer *rsvg_paint_server_parse (gboolean * inherit, const char *str);
G_GNUC_INTERNAL
void rsvg_paint_server_ref (RsvgPaintServer * ps);
G_GNUC_INTERNAL
......
......@@ -119,7 +119,7 @@ rsvg_state_init (RsvgState * state)
state->mask = NULL;
state->opacity = 0xff;
state->adobe_blend = 0;
state->fill = rsvg_paint_server_parse (NULL, NULL, "#000");
state->fill = rsvg_paint_server_parse (NULL, "#000");
state->fill_opacity = 0xff;
state->stroke_opacity = 0xff;
state->stroke_width = _rsvg_css_parse_length ("1");
......@@ -616,7 +616,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
} else if (g_str_equal (name, "fill")) {
RsvgPaintServer *fill = state->fill;
state->fill =
rsvg_paint_server_parse (&state->has_fill_server, ctx->priv->defs, value);
rsvg_paint_server_parse (&state->has_fill_server, value);
rsvg_paint_server_unref (fill);
} else if (g_str_equal (name, "fill-opacity")) {
state->fill_opacity = rsvg_css_parse_opacity (value);
......@@ -641,7 +641,7 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
RsvgPaintServer *stroke = state->stroke;
state->stroke =
rsvg_paint_server_parse (&state->has_stroke_server, ctx->priv->defs, value);
rsvg_paint_server_parse (&state->has_stroke_server, value);
rsvg_paint_server_unref (stroke);
} else if (g_str_equal (name, "stroke-width")) {
......
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