]> gitweb.michael.orlitzky.com - libsvgtiny.git/commitdiff
src/svgtiny.c: add svgtiny_parse_style_element() function and use it
authorMichael Orlitzky <michael@orlitzky.com>
Wed, 4 Oct 2023 12:20:40 +0000 (08:20 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Mon, 20 Nov 2023 01:34:32 +0000 (20:34 -0500)
The new function parses the contents of a <style> element. We add a
call to it in svgtiny_preparse_styles() where previously a placeholder
was left.

src/svgtiny.c

index 8cb1eff2f283adf74b00eb42dc6b1bed4078bcd0..09adedc66799765c054267ba0c84269fa1e2aa96 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_parse_style_element(dom_element *style,
+               struct svgtiny_parse_state state);
 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 +763,94 @@ 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_stylesheet_params params;
+       css_error code;
+       dom_exception exc;
+
+       params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
+       params.level = CSS_LEVEL_DEFAULT;
+       params.charset = NULL;
+       params.url = "";
+       params.title = NULL;
+       params.allow_quirks = false;
+       params.inline_style = false;
+       params.resolve = svgtiny_resolve_url;
+       params.resolve_pw = NULL;
+       params.import = NULL;
+       params.import_pw = NULL;
+       params.color = NULL;
+       params.color_pw = NULL;
+       params.font = NULL;
+       params.font_pw = NULL;
+
+       code = css_stylesheet_create(&params, &sheet);
+       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 all <style> elements within a root <svg> element. This
  * should be called before svgtiny_parse_svg() because that function
@@ -803,6 +893,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);
                        }