[librsvg] Apply svg element's style after loading style data.



commit 10e41fccf789c762c5b57be655e3cd8ca24cedb6
Author: Hiroyuki Ikezoe <poincare ikezoe net>
Date:   Wed Apr 14 11:50:05 2010 +0900

    Apply svg element's style after loading style data.
    
    Fix for bug #615701.

 rsvg-base.c      |    3 +++
 rsvg-private.h   |    7 ++-----
 rsvg-structure.c |   24 +++++++++++++++++++-----
 rsvg-structure.h |    2 ++
 rsvg-styles.c    |   20 ++++++++++++--------
 5 files changed, 38 insertions(+), 18 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index fb99d54..8572cfd 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -37,6 +37,7 @@
 #include "rsvg-css.h"
 #include "rsvg-styles.h"
 #include "rsvg-shapes.h"
+#include "rsvg-structure.h"
 #include "rsvg-image.h"
 #include "rsvg-text.h"
 #include "rsvg-filter.h"
@@ -688,6 +689,8 @@ rsvg_end_element (void *data, const xmlChar * name)
             && !strcmp ((const char *) name, ctx->priv->currentnode->type->str))
             rsvg_pop_def_group (ctx);
 
+        if (!strcmp ((const char *)name, "style"))
+            _rsvg_node_svg_apply_atts ((RsvgNodeSvg *)ctx->priv->treebase, ctx);
     }
 }
 
diff --git a/rsvg-private.h b/rsvg-private.h
index e8d47c3..25b952f 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -45,7 +45,7 @@ G_BEGIN_DECLS
 typedef struct RsvgSaxHandler RsvgSaxHandler;
 typedef struct RsvgDrawingCtx RsvgDrawingCtx;
 typedef struct RsvgRender RsvgRender;
-typedef struct _RsvgPropertyBag RsvgPropertyBag;
+typedef GHashTable RsvgPropertyBag;
 typedef struct _RsvgState RsvgState;
 typedef struct _RsvgDefs RsvgDefs;
 typedef struct _RsvgNode RsvgNode;
@@ -249,10 +249,6 @@ struct RsvgSizeCallbackData {
 
 void _rsvg_size_callback (int *width, int *height, gpointer data);
 
-struct _RsvgPropertyBag {
-    GHashTable *props;
-};
-
 struct _RsvgNode {
     RsvgState *state;
     RsvgNode *parent;
@@ -271,6 +267,7 @@ struct _RsvgNodeChars {
 typedef void (*RsvgPropertyBagEnumFunc) (const char *key, const char *value, gpointer user_data);
 
 RsvgPropertyBag	    *rsvg_property_bag_new	(const char **atts);
+RsvgPropertyBag	    *rsvg_property_bag_ref	(RsvgPropertyBag * bag);
 void		     rsvg_property_bag_free	(RsvgPropertyBag * bag);
 G_CONST_RETURN char *rsvg_property_bag_lookup	(RsvgPropertyBag * bag, const char *key);
 guint		     rsvg_property_bag_size	(RsvgPropertyBag * bag);
diff --git a/rsvg-structure.c b/rsvg-structure.c
index 3d8c9af..cab21e0 100644
--- a/rsvg-structure.c
+++ b/rsvg-structure.c
@@ -334,7 +334,7 @@ rsvg_node_svg_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
 static void
 rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
 {
-    const char *id = NULL, *klazz = NULL, *value;
+    const char *value;
     RsvgNodeSvg *svg = (RsvgNodeSvg *) self;
 
     if (rsvg_property_bag_size (atts)) {
@@ -355,13 +355,27 @@ rsvg_node_svg_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * att
             svg->x = _rsvg_css_parse_length (value);
         if (self->parent && (value = rsvg_property_bag_lookup (atts, "y")))
             svg->y = _rsvg_css_parse_length (value);
-        if ((value = rsvg_property_bag_lookup (atts, "class")))
-            klazz = value;
         if ((value = rsvg_property_bag_lookup (atts, "id"))) {
-            id = value;
             rsvg_defs_register_name (ctx->priv->defs, value, &svg->super);
         }
-        rsvg_parse_style_attrs (ctx, self->state, "svg", klazz, id, atts);
+        /*
+         * style element is not loaded yet here, so we need to store those attribues
+         * to be applied later.
+         */
+        svg->atts = rsvg_property_bag_ref(atts);
+    }
+}
+
+void
+_rsvg_node_svg_apply_atts (RsvgNodeSvg * self, RsvgHandle * ctx)
+{
+    const char *id = NULL, *klazz = NULL, *value;
+    if (rsvg_property_bag_size (self->atts)) {
+        if ((value = rsvg_property_bag_lookup (self->atts, "class")))
+            klazz = value;
+        if ((value = rsvg_property_bag_lookup (self->atts, "id")))
+            id = value;
+        rsvg_parse_style_attrs (ctx, ((RsvgNode *)self)->state, "svg", klazz, id, self->atts);
     }
 }
 
diff --git a/rsvg-structure.h b/rsvg-structure.h
index ac372e0..f10772d 100644
--- a/rsvg-structure.h
+++ b/rsvg-structure.h
@@ -68,6 +68,7 @@ struct _RsvgNodeSvg {
     gint preserve_aspect_ratio;
     RsvgLength x, y, w, h;
     RsvgViewBox vbox;
+    RsvgPropertyBag *atts;
     GdkPixbuf *img;
 };
 
@@ -79,6 +80,7 @@ void _rsvg_node_draw_children	(RsvgNode * self, RsvgDrawingCtx * ctx, int domina
 void _rsvg_node_finalize	(RsvgNode * self);
 void _rsvg_node_free		(RsvgNode * self);
 void _rsvg_node_init		(RsvgNode * self);
+void _rsvg_node_svg_apply_atts	(RsvgNodeSvg * self, RsvgHandle * ctx);
 
 G_END_DECLS
 
diff --git a/rsvg-styles.c b/rsvg-styles.c
index 7125216..61d3a1f 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -1387,41 +1387,45 @@ rsvg_property_bag_new (const char **atts)
     RsvgPropertyBag *bag;
     int i;
 
-    bag = g_new (RsvgPropertyBag, 1);
-    bag->props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+    bag = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
     if (atts != NULL) {
         for (i = 0; atts[i] != NULL; i += 2)
-            g_hash_table_insert (bag->props, (gpointer) atts[i], (gpointer) atts[i + 1]);
+            g_hash_table_insert (bag, (gpointer) g_strdup(atts[i]), (gpointer) g_strdup(atts[i + 1]));
     }
 
     return bag;
 }
 
+RsvgPropertyBag *
+rsvg_property_bag_ref (RsvgPropertyBag * bag)
+{
+    return g_hash_table_ref (bag);
+}
+
 void
 rsvg_property_bag_free (RsvgPropertyBag * bag)
 {
-    g_hash_table_destroy (bag->props);
-    g_free (bag);
+    g_hash_table_unref (bag);
 }
 
 G_CONST_RETURN char *
 rsvg_property_bag_lookup (RsvgPropertyBag * bag, const char *key)
 {
-    return (const char *) g_hash_table_lookup (bag->props, (gconstpointer) key);
+    return (const char *) g_hash_table_lookup (bag, (gconstpointer) key);
 }
 
 guint
 rsvg_property_bag_size (RsvgPropertyBag * bag)
 {
-    return g_hash_table_size (bag->props);
+    return g_hash_table_size (bag);
 }
 
 void
 rsvg_property_bag_enumerate (RsvgPropertyBag * bag, RsvgPropertyBagEnumFunc func,
                              gpointer user_data)
 {
-    g_hash_table_foreach (bag->props, (GHFunc) func, user_data);
+    g_hash_table_foreach (bag, (GHFunc) func, user_data);
 }
 
 void



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