[librsvg] marker: Resolve lazily



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]