From efd9f1bb8f7c1c65a219129b374f645188d507fd Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 7 Jun 2025 10:49:17 -0400 Subject: [PATCH] src/svgtiny_parse.c: add svgtiny_parse_style_inline() function This function parses the contents of an inline style="..." attribute into a libcss stylesheet, or NULL if anything went wrong. We use the new function in svgtiny_parse_paint_attributes() to parse an inline sheet... and then (for now) do nothing with it. We are able to parse the inline style="..." attributes right now but more scaffolding is needed before we can utilize css_select_style(). --- src/svgtiny_parse.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/svgtiny_parse.c b/src/svgtiny_parse.c index af7b228..566a8c0 100644 --- a/src/svgtiny_parse.c +++ b/src/svgtiny_parse.c @@ -10,6 +10,7 @@ #include #include +#include #include "svgtiny.h" #include "svgtiny_internal.h" @@ -1489,6 +1490,38 @@ svgtiny_parse_viewbox(const char *text, } +/** + * 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. + */ +static 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 an inline style */ @@ -1503,6 +1536,13 @@ svgtiny_parse_inline_style(dom_element *node, dom_string *attr; dom_exception exc; + /* We store the result of svgtiny_parse_style_inline() in + * inline_sheet, and that function returns NULL on error; in + * particular you do not need to css_stylesheet_destroy() the + * result if it is NULL. We initialize inline_sheet to NULL to + * retain the same semantics. */ + css_stylesheet *inline_sheet = NULL; + /* style attribute */ exc = dom_element_get_attribute(node, state->interned_style, &attr); if (exc != DOM_NO_ERR) { @@ -1512,6 +1552,14 @@ svgtiny_parse_inline_style(dom_element *node, /* no style attribute */ return svgtiny_OK; } + /* First parse the style attribute into a libcss stylesheet + in case any of its properties are known to libcss. */ + inline_sheet = svgtiny_parse_style_inline( + (uint8_t *)dom_string_data(attr), + dom_string_byte_length(attr)); + + /* Parse any other properties "by hand" until they can + be supported in libcss. */ cursor = dom_string_data(attr); textend = cursor + dom_string_byte_length(attr); @@ -1529,6 +1577,11 @@ svgtiny_parse_inline_style(dom_element *node, cursor++; /* skip semicolon */ } dom_string_unref(attr); + + if (inline_sheet != NULL) { + css_stylesheet_destroy(inline_sheet); + } + return svgtiny_OK; } -- 2.49.0