]> gitweb.michael.orlitzky.com - libsvgtiny.git/blobdiff - src/svgtiny.c
src/svgtiny.c: add svgtiny_parse_style_inline() function
[libsvgtiny.git] / src / svgtiny.c
index 8cb1eff2f283adf74b00eb42dc6b1bed4078bcd0..db0d59b02cd72209a51f409d7f62aef338bb64e3 100644 (file)
 #define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0)
 #define radToDeg(angleInRadians) ((angleInRadians) * 180.0 / M_PI)
 
+static svgtiny_code svgtiny_parse_style_element(dom_element *style,
+               struct svgtiny_parse_state state);
+static css_stylesheet *svgtiny_parse_style_inline(const uint8_t *data,
+               size_t len);
 static svgtiny_code svgtiny_preparse_styles(dom_element *svg,
                struct svgtiny_parse_state state);
 static svgtiny_code svgtiny_parse_svg(dom_element *svg,
@@ -761,6 +765,108 @@ cleanup:
        return code;
 }
 
+
+/**
+ * Parse a single <style> element, appending the result to the CSS
+ * select context within the given parser state.
+ */
+svgtiny_code svgtiny_parse_style_element(dom_element *style,
+               struct svgtiny_parse_state state)
+{
+       css_stylesheet *sheet;
+       css_error code;
+       dom_exception exc;
+
+       code = svgtiny_create_stylesheet(&sheet, false);
+       if (code != CSS_OK) {
+               return svgtiny_LIBCSS_ERROR;
+       }
+
+       /* Parse the style element's "media" attribute if it has
+          one. We don't do anything with it right now. */
+       dom_string *media_attr;
+       exc = dom_element_get_attribute(style, state.interned_media,
+                                       &media_attr);
+       if (exc != DOM_NO_ERR) {
+               css_stylesheet_destroy(sheet);
+               return svgtiny_LIBDOM_ERROR;
+       }
+
+       if (media_attr) {
+               /* Here's where we'd actually change the media type if
+                  we were going to use it */
+               dom_string_unref(media_attr);
+       }
+
+       dom_string *data;
+       dom_node_get_text_content(style, &data);
+       if (data == NULL) {
+               /* Empty stylesheet? That's fine. */
+               css_stylesheet_destroy(sheet);
+               return svgtiny_OK;
+       }
+
+       code = css_stylesheet_append_data(sheet,
+                                         (uint8_t *)dom_string_data(data),
+                                         dom_string_byte_length(data));
+       if (code != CSS_OK && code != CSS_NEEDDATA) {
+               dom_string_unref(data);
+               css_stylesheet_destroy(sheet);
+               return svgtiny_LIBCSS_ERROR;
+       }
+
+       code = css_stylesheet_data_done(sheet);
+       if (code != CSS_OK) {
+               dom_string_unref(data);
+               css_stylesheet_destroy(sheet);
+               return svgtiny_LIBCSS_ERROR;
+       }
+
+       code = css_select_ctx_append_sheet(state.select_ctx,
+               sheet,
+               CSS_ORIGIN_AUTHOR,
+               NULL);
+       if (code != CSS_OK) {
+               dom_string_unref(data);
+               return svgtiny_LIBCSS_ERROR;
+       }
+
+       dom_string_unref(data);
+       return svgtiny_OK;
+}
+
+
+/**
+ * Parse the contents of an inline style and return (a pointer to) the
+ * corresponding stylesheet for use with css_select_style(). Returns
+ * NULL if anything goes wrong.
+ */
+css_stylesheet *svgtiny_parse_style_inline(const uint8_t *data,
+               size_t len)
+{
+       css_stylesheet *sheet;
+       css_error code;
+
+       code = svgtiny_create_stylesheet(&sheet, true);
+       if (code != CSS_OK) {
+               return NULL;
+       }
+
+       code = css_stylesheet_append_data(sheet, data, len);
+       if (code != CSS_OK && code != CSS_NEEDDATA) {
+               css_stylesheet_destroy(sheet);
+               return NULL;
+       }
+
+       code = css_stylesheet_data_done(sheet);
+       if (code != CSS_OK) {
+               css_stylesheet_destroy(sheet);
+               return NULL;
+       }
+
+       return sheet;
+}
+
 /**
  * Parse all <style> elements within a root <svg> element. This
  * should be called before svgtiny_parse_svg() because that function
@@ -803,6 +909,8 @@ svgtiny_code svgtiny_preparse_styles(dom_element *svg,
                        if (dom_string_caseless_isequal(state.interned_style,
                                                        nodename)) {
                                /* We have a <style> element, parse it */
+                               code = svgtiny_parse_style_element(child,
+                                                               state);
                        }