[librsvg] Store the parsed path for the polygon



commit 56e801e0cbd0f55d01ec93c27354ee88c6398d3f
Author: Christian Persch <chpe gnome org>
Date:   Sat Sep 17 00:10:00 2011 +0200

    Store the parsed path for the polygon
    
    Instead of building the string and parsing it to a path every time
    we render this node, just store the parsed path instead.

 rsvg-shapes.c |   78 ++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 50 insertions(+), 28 deletions(-)
---
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index e626e9a..c13b90c 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -102,12 +102,15 @@ rsvg_new_path (void)
 
 struct _RsvgNodePoly {
     RsvgNode super;
-    gdouble *pointlist;
-    guint pointlist_len;
+    cairo_path_t *path;
 };
 
 typedef struct _RsvgNodePoly RsvgNodePoly;
 
+static cairo_path_t *
+_rsvg_node_poly_build_path (const char *value,
+                            gboolean close_path);
+
 static void
 _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
 {
@@ -118,7 +121,10 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
         /* support for svg < 1.0 which used verts */
         if ((value = rsvg_property_bag_lookup (atts, "verts"))
             || (value = rsvg_property_bag_lookup (atts, "points"))) {
-            poly->pointlist = rsvg_css_parse_number_list (value, &poly->pointlist_len);
+            if (poly->path)
+                rsvg_cairo_path_destroy (poly->path);
+            poly->path = _rsvg_node_poly_build_path (value,
+                                                     RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYGON);
         }
         if ((value = rsvg_property_bag_lookup (atts, "class")))
             klazz = value;
@@ -134,57 +140,74 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
 
 }
 
-static void
-_rsvg_node_poly_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
+static cairo_path_t *
+_rsvg_node_poly_build_path (const char *value,
+                            gboolean close_path)
 {
-    RsvgNodePoly *poly = (RsvgNodePoly *) self;
-    gsize i;
+    double *pointlist;
+    guint pointlist_len, i;
     GString *d;
     cairo_path_t *path;
     char buf[G_ASCII_DTOSTR_BUF_SIZE];
 
-    /* represent as a "moveto, lineto*, close" path */
-    if (poly->pointlist_len < 2)
-        return;
+    pointlist = rsvg_css_parse_number_list (value, &pointlist_len);
+    if (pointlist == NULL)
+        return NULL;
+
+    if (pointlist_len < 2) {
+        g_free (pointlist);
+        return NULL;
+    }
 
     d = g_string_new (NULL);
 
     /*      "M %f %f " */
     g_string_append (d, " M ");
-    g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), poly->pointlist[0]));
+    g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), pointlist[0]));
     g_string_append_c (d, ' ');
-    g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), poly->pointlist[1]));
+    g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), pointlist[1]));
 
     /* "L %f %f " */
-    for (i = 2; i < poly->pointlist_len; i += 2) {
+    for (i = 2; i < pointlist_len; i += 2) {
         g_string_append (d, " L ");
-        g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), poly->pointlist[i]));
+        g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), pointlist[i]));
         g_string_append_c (d, ' ');
-        g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), poly->pointlist[i + 1]));
+        g_string_append (d, g_ascii_dtostr (buf, sizeof (buf), pointlist[i + 1]));
     }
 
-    if (RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYGON)
+    if (close_path)
         g_string_append (d, " Z");
 
-    rsvg_state_reinherit_top (ctx, self->state, dominate);
-
     path = rsvg_parse_path (d->str);
-    rsvg_render_path (ctx, path);
-    rsvg_cairo_path_destroy (path);
 
     g_string_free (d, TRUE);
+    g_free (pointlist);
+
+    return path;
 }
 
 static void
-_rsvg_node_poly_free (RsvgNode * self)
+_rsvg_node_poly_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
 {
-    RsvgNodePoly *z = (RsvgNodePoly *) self;
-    if (z->pointlist)
-        g_free (z->pointlist);
-    _rsvg_node_finalize (&z->super);
-    g_free (z);
+    RsvgNodePoly *poly = (RsvgNodePoly *) self;
+
+    if (poly->path == NULL)
+        return;
+
+    rsvg_state_reinherit_top (ctx, self->state, dominate);
+
+    rsvg_render_path (ctx, poly->path);
 }
 
+static void
+_rsvg_node_poly_free (RsvgNode * self)
+{
+    RsvgNodePoly *poly = (RsvgNodePoly *) self;
+    if (poly->path)
+        rsvg_cairo_path_destroy (poly->path);
+    _rsvg_node_finalize (&poly->super);
+    g_free (poly);
+}
 
 static RsvgNode *
 rsvg_new_any_poly (RsvgNodeType type)
@@ -195,8 +218,7 @@ rsvg_new_any_poly (RsvgNodeType type)
     poly->super.free = _rsvg_node_poly_free;
     poly->super.draw = _rsvg_node_poly_draw;
     poly->super.set_atts = _rsvg_node_poly_set_atts;
-    poly->pointlist = NULL;
-    poly->pointlist_len = 0;
+    poly->path = NULL;
     return &poly->super;
 }
 



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