[librsvg] marker: Resolve lazily
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] marker: Resolve lazily
- Date: Thu, 22 Oct 2015 11:12:54 +0000 (UTC)
commit 6df53732f8ecfdc99b705b7e9a94442c267145f0
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 7 12:13:21 2015 +0200
marker: Resolve lazily
And that concludes our rework of reference cylce detection. All code
that references other objects via IRIs will now call rsvg_acquire_node()
which itself avoids giving out the same node a second time until
rsvg_release_node() has been called.
This also means that rsvg_defs_lookup() is only used in two places now:
(1) by rsvg_acquire_node()
(2) by public API that allows operating on objects by id.
rsvg-marker.c | 41 +++++++++++++++++------------------------
rsvg-marker.h | 5 -----
rsvg-styles.c | 41 ++++++++++++++++++++++++++++-------------
rsvg-styles.h | 6 +++---
4 files changed, 48 insertions(+), 45 deletions(-)
---
diff --git a/rsvg-marker.c b/rsvg-marker.c
index a26d7bd..2e69076 100644
--- a/rsvg-marker.c
+++ b/rsvg-marker.c
@@ -99,15 +99,23 @@ rsvg_new_marker (void)
return &marker->super;
}
-void
-rsvg_marker_render (RsvgMarker * self, gdouble xpos, gdouble ypos, gdouble orient, gdouble linewidth,
+static void
+rsvg_marker_render (const char * marker_name, gdouble xpos, gdouble ypos, gdouble orient, gdouble linewidth,
RsvgDrawingCtx * ctx)
{
+ RsvgMarker *self;
cairo_matrix_t affine, taffine;
unsigned int i;
gdouble rotation;
RsvgState *state = rsvg_current_state (ctx);
+ self = (RsvgMarker *) rsvg_acquire_node (ctx, marker_name);
+ if (self == NULL || RSVG_NODE_TYPE (&self->super) != RSVG_NODE_TYPE_MARKER)
+ {
+ rsvg_release_node (ctx, &self->super);
+ return;
+ }
+
cairo_matrix_init_translate (&taffine, xpos, ypos);
cairo_matrix_multiply (&affine, &taffine, &state->affine);
@@ -191,23 +199,8 @@ rsvg_marker_render (RsvgMarker * self, gdouble xpos, gdouble ypos, gdouble orien
rsvg_state_pop (ctx);
if (self->vbox.active)
_rsvg_pop_view_box (ctx);
-}
-RsvgNode *
-rsvg_marker_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_MARKER)
- return val;
- }
- return NULL;
+ rsvg_release_node (ctx, (RsvgNode *) self);
}
void
@@ -220,18 +213,18 @@ rsvg_render_markers (RsvgDrawingCtx * ctx,
cairo_path_data_type_t code, nextcode;
RsvgState *state;
- RsvgMarker *startmarker;
- RsvgMarker *middlemarker;
- RsvgMarker *endmarker;
+ const char *startmarker;
+ const char *middlemarker;
+ const char *endmarker;
cairo_path_data_t *data, *nextdata, *end;
cairo_path_data_t nextp;
state = rsvg_current_state (ctx);
linewidth = _rsvg_css_normalize_length (&state->stroke_width, ctx, 'o');
- startmarker = (RsvgMarker *) state->startMarker;
- middlemarker = (RsvgMarker *) state->middleMarker;
- endmarker = (RsvgMarker *) state->endMarker;
+ startmarker = state->startMarker;
+ middlemarker = state->middleMarker;
+ endmarker = state->endMarker;
if (linewidth == 0)
return;
diff --git a/rsvg-marker.h b/rsvg-marker.h
index 0e4081e..e4e6726 100644
--- a/rsvg-marker.h
+++ b/rsvg-marker.h
@@ -45,11 +45,6 @@ struct _RsvgMarker {
G_GNUC_INTERNAL
RsvgNode *rsvg_new_marker (void);
G_GNUC_INTERNAL
-void rsvg_marker_render (RsvgMarker * self, gdouble xpos, gdouble ypos,
- gdouble orient, gdouble linewidth, RsvgDrawingCtx * ctx);
-G_GNUC_INTERNAL
-RsvgNode *rsvg_marker_parse (const RsvgDefs * defs, const char *str);
-G_GNUC_INTERNAL
void rsvg_render_markers (RsvgDrawingCtx *ctx, const cairo_path_t *path);
G_END_DECLS
diff --git a/rsvg-styles.c b/rsvg-styles.c
index b6197a4..96f82c9 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -226,6 +226,9 @@ rsvg_state_clone (RsvgState * dst, const RsvgState * src)
dst->clip_path = g_strdup (src->clip_path);
dst->font_family = g_strdup (src->font_family);
dst->lang = g_strdup (src->lang);
+ dst->startMarker = g_strdup (src->startMarker);
+ dst->middleMarker = g_strdup (src->middleMarker);
+ dst->endMarker = g_strdup (src->endMarker);
rsvg_paint_server_ref (dst->fill);
rsvg_paint_server_ref (dst->stroke);
@@ -315,16 +318,22 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
dst->text_anchor = src->text_anchor;
if (function (dst->has_letter_spacing, src->has_letter_spacing))
dst->letter_spacing = src->letter_spacing;
- if (function (dst->has_startMarker, src->has_startMarker))
- dst->startMarker = src->startMarker;
- if (function (dst->has_middleMarker, src->has_middleMarker))
- dst->middleMarker = src->middleMarker;
- if (function (dst->has_endMarker, src->has_endMarker))
- dst->endMarker = src->endMarker;
- if (function (dst->has_shape_rendering_type, src->has_shape_rendering_type))
- dst->shape_rendering_type = src->shape_rendering_type;
- if (function (dst->has_text_rendering_type, src->has_text_rendering_type))
- dst->text_rendering_type = src->text_rendering_type;
+ if (function (dst->has_startMarker, src->has_startMarker)) {
+ g_free (dst->startMarker);
+ dst->startMarker = g_strdup (src->startMarker);
+ }
+ if (function (dst->has_middleMarker, src->has_middleMarker)) {
+ g_free (dst->middleMarker);
+ dst->middleMarker = g_strdup (src->middleMarker);
+ }
+ if (function (dst->has_endMarker, src->has_endMarker)) {
+ g_free (dst->endMarker);
+ dst->endMarker = g_strdup (src->endMarker);
+ }
+ if (function (dst->has_shape_rendering_type, src->has_shape_rendering_type))
+ dst->shape_rendering_type = src->shape_rendering_type;
+ if (function (dst->has_text_rendering_type, src->has_text_rendering_type))
+ dst->text_rendering_type = src->text_rendering_type;
if (function (dst->has_font_family, src->has_font_family)) {
g_free (dst->font_family); /* font_family is always set to something */
@@ -455,6 +464,9 @@ rsvg_state_finalize (RsvgState * state)
g_free (state->clip_path);
g_free (state->font_family);
g_free (state->lang);
+ g_free (state->startMarker);
+ g_free (state->middleMarker);
+ g_free (state->endMarker);
rsvg_paint_server_unref (state->fill);
rsvg_paint_server_unref (state->stroke);
@@ -773,13 +785,16 @@ rsvg_parse_style_pair (RsvgHandle * ctx,
state->stop_opacity = rsvg_css_parse_opacity (value);
}
} else if (g_str_equal (name, "marker-start")) {
- state->startMarker = rsvg_marker_parse (ctx->priv->defs, value);
+ g_free (state->startMarker);
+ state->startMarker = rsvg_get_url_string (value);
state->has_startMarker = TRUE;
} else if (g_str_equal (name, "marker-mid")) {
- state->middleMarker = rsvg_marker_parse (ctx->priv->defs, value);
+ g_free (state->middleMarker);
+ state->middleMarker = rsvg_get_url_string (value);
state->has_middleMarker = TRUE;
} else if (g_str_equal (name, "marker-end")) {
- state->endMarker = rsvg_marker_parse (ctx->priv->defs, value);
+ g_free (state->endMarker);
+ state->endMarker = rsvg_get_url_string (value);
state->has_endMarker = TRUE;
} else if (g_str_equal (name, "stroke-miterlimit")) {
state->has_miter_limit = TRUE;
diff --git a/rsvg-styles.h b/rsvg-styles.h
index 300cbee..14f38e5 100644
--- a/rsvg-styles.h
+++ b/rsvg-styles.h
@@ -167,9 +167,9 @@ struct _RsvgState {
guchar flood_opacity;
gboolean has_flood_opacity;
- RsvgNode *startMarker;
- RsvgNode *middleMarker;
- RsvgNode *endMarker;
+ char *startMarker;
+ char *middleMarker;
+ char *endMarker;
gboolean has_startMarker;
gboolean has_middleMarker;
gboolean has_endMarker;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]