]> gitweb.michael.orlitzky.com - libsvgtiny.git/blobdiff - src/svgtiny.c
src/svgtiny.c: add impotent svgtiny_preparse_styles() function
[libsvgtiny.git] / src / svgtiny.c
index 3b886fe770502d384e17cf7ffb8e5b4e075a693b..8cb1eff2f283adf74b00eb42dc6b1bed4078bcd0 100644 (file)
@@ -40,6 +40,8 @@
 #define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0)
 #define radToDeg(angleInRadians) ((angleInRadians) * 180.0 / M_PI)
 
+static svgtiny_code svgtiny_preparse_styles(dom_element *svg,
+               struct svgtiny_parse_state state);
 static svgtiny_code svgtiny_parse_svg(dom_element *svg,
                struct svgtiny_parse_state state);
 static svgtiny_code svgtiny_parse_path(dom_element *path,
@@ -737,7 +739,10 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
        state.stroke_width = 1;
 
        /* parse tree */
-       code = svgtiny_parse_svg(svg, state);
+       code = svgtiny_preparse_styles(svg, state);
+       if (code == svgtiny_OK) {
+               code = svgtiny_parse_svg(svg, state);
+       }
 
        dom_node_unref(svg);
        dom_node_unref(document);
@@ -756,6 +761,68 @@ cleanup:
        return code;
 }
 
+/**
+ * Parse all <style> elements within a root <svg> element. This
+ * should be called before svgtiny_parse_svg() because that function
+ * makes a single pass through the document and we'd like all style
+ * information to be available during that pass. Specifically, we'd
+ * like a <style> sheet at the end of the document to affect the
+ * rendering of elements at its beginning.
+ *
+ * The element-parsing inner loop here is essentially the same as
+ * that within svgtiny_parse_svg().
+ */
+svgtiny_code svgtiny_preparse_styles(dom_element *svg,
+               struct svgtiny_parse_state state)
+{
+       dom_element *child;
+       dom_exception exc;
+
+       exc = dom_node_get_first_child(svg, (dom_node **) (void *) &child);
+       if (exc != DOM_NO_ERR) {
+               return svgtiny_LIBDOM_ERROR;
+       }
+       while (child != NULL) {
+               dom_element *next;
+               dom_node_type nodetype;
+               svgtiny_code code = svgtiny_OK;
+
+               exc = dom_node_get_node_type(child, &nodetype);
+               if (exc != DOM_NO_ERR) {
+                       dom_node_unref(child);
+                       return svgtiny_LIBDOM_ERROR;
+               }
+               if (nodetype == DOM_ELEMENT_NODE) {
+                       dom_string *nodename;
+                       exc = dom_node_get_node_name(child, &nodename);
+                       if (exc != DOM_NO_ERR) {
+                               dom_node_unref(child);
+                               return svgtiny_LIBDOM_ERROR;
+                       }
+
+                       if (dom_string_caseless_isequal(state.interned_style,
+                                                       nodename)) {
+                               /* We have a <style> element, parse it */
+                       }
+
+
+                       dom_string_unref(nodename);
+               }
+               if (code != svgtiny_OK) {
+                       dom_node_unref(child);
+                       return code;
+               }
+               exc = dom_node_get_next_sibling(child,
+                                               (dom_node **) (void *) &next);
+               dom_node_unref(child);
+               if (exc != DOM_NO_ERR) {
+                       return svgtiny_LIBDOM_ERROR;
+               }
+               child = next;
+       }
+
+       return svgtiny_OK;
+}
 
 /**
  * Parse a <svg> or <g> element node.