]> gitweb.michael.orlitzky.com - libsvgtiny.git/blobdiff - src/svgtiny.c
src/svgtiny_css.c: new file with new svgtiny_resolve_url() function
[libsvgtiny.git] / src / svgtiny.c
index ee0c59c1eff64a7fa434d22b25d5d1f9dcf7c11f..8cb1eff2f283adf74b00eb42dc6b1bed4078bcd0 100644 (file)
@@ -17,6 +17,8 @@
 #include <dom/dom.h>
 #include <dom/bindings/xml/xmlparser.h>
 
+#include <libcss/libcss.h>
+
 #include "svgtiny.h"
 #include "svgtiny_internal.h"
 
@@ -38,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,
@@ -610,6 +614,7 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
                const char *buffer, size_t size, const char *url,
                int viewport_width, int viewport_height)
 {
+       css_error css_code;
        dom_document *document;
        dom_exception exc;
        dom_xml_parser *parser;
@@ -695,6 +700,17 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
        state.viewport_width = viewport_width;
        state.viewport_height = viewport_height;
 
+
+       /* Initialize CSS context */
+       if (state.select_ctx == NULL) {
+               css_code = css_select_ctx_create(&state.select_ctx);
+               if (css_code != CSS_OK) {
+                       dom_node_unref(svg);
+                       dom_node_unref(document);
+                       return svgtiny_LIBCSS_ERROR;
+               }
+       }
+
 #define SVGTINY_STRING_ACTION2(s,n)                                    \
        if (dom_string_create_interned((const uint8_t *) #n,            \
                                       strlen(#n), &state.interned_##s) \
@@ -718,17 +734,22 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram,
        state.ctm.d = 1; /*(float) viewport_height / (float) height;*/
        state.ctm.e = 0; /*x;*/
        state.ctm.f = 0; /*y;*/
-       /*state.style = css_base_style;
-       state.style.font_size.value.length.value = option_font_size * 0.1;*/
        state.fill = 0x000000;
        state.stroke = svgtiny_TRANSPARENT;
        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);
+       css_code = css_select_ctx_destroy(state.select_ctx);
+       if (css_code != CSS_OK) {
+               code = svgtiny_LIBCSS_ERROR;
+       }
 
 cleanup:
        svgtiny_cleanup_state_local(&state);
@@ -740,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.
@@ -1687,9 +1770,6 @@ svgtiny_code svgtiny_parse_text(dom_element *text,
 /*     state.ctm.e = px - state.origin_x; */
 /*     state.ctm.f = py - state.origin_y; */
 
-       /*struct css_style style = state.style;
-       style.font_size.value.length.value *= state.ctm.a;*/
-
         exc = dom_node_get_first_child(text, &child);
        if (exc != DOM_NO_ERR) {
                return svgtiny_LIBDOM_ERROR;
@@ -1819,7 +1899,7 @@ static float _svgtiny_parse_length(const char *s, int viewport_size,
        int num_length = strspn(s, "0123456789+-.");
        const char *unit = s + num_length;
        float n = atof((const char *) s);
-       float font_size = 20; /*css_len2px(&state.style.font_size.value.length, 0);*/
+       float font_size = 20;
 
        UNUSED(state);
 
@@ -2013,13 +2093,7 @@ void svgtiny_parse_font_attributes(dom_element *node,
 
        for (attr = node->properties; attr; attr = attr->next) {
                if (strcmp((const char *) attr->name, "font-size") == 0) {
-                       /*if (css_parse_length(
-                                       (const char *) attr->children->content,
-                                       &state->style.font_size.value.length,
-                                       true, true)) {
-                               state->style.font_size.size =
-                                               CSS_FONT_SIZE_LENGTH;
-                       }*/
+                       /* TODO */
                }
         }
 #endif