]> gitweb.michael.orlitzky.com - libsvgtiny.git/commitdiff
src/svgtiny.c: add impotent svgtiny_preparse_styles() function
authorMichael Orlitzky <michael@orlitzky.com>
Sat, 7 Jun 2025 14:14:00 +0000 (10:14 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 8 Jun 2025 02:18:20 +0000 (22:18 -0400)
We declare and add the svgtiny_preparse_styles() function that will be
used to make a first pass through the SVG document and parse all of
the <style> elements. At the moment it is only half implemented:
once we find a <style> element, we do nothing with it. A separate
function will be used to parse a <style> once we have it.

src/svgtiny.c

index a3080ea098a8698ff7521fc122abd7898872440c..4c126ed4cf6ef6d3e3544a16f4044b624957f825 100644 (file)
@@ -1069,6 +1069,69 @@ parse_element(dom_element *element, struct svgtiny_parse_state *state)
        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().
+ */
+static 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;
+}
+
 
 static svgtiny_code
 initialise_parse_state(struct svgtiny_parse_state *state,
@@ -1341,7 +1404,10 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
                                                      viewport_width,
                                                      viewport_height);
                        if (code == svgtiny_OK) {
-                               code = svgtiny_parse_svg(svg, state);
+                               code = svgtiny_preparse_styles(svg, state);
+                               if (code == svgtiny_OK) {
+                                       code = svgtiny_parse_svg(svg, state);
+                               }
                        }
 
                        finalise_parse_state(&state);