X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fsvgtiny.c;h=a77e3b46d9f7c0ca382190075f6971af475c4da9;hb=996d346ac843319c8c60e1dc9f207cdacc792455;hp=db0d59b02cd72209a51f409d7f62aef338bb64e3;hpb=476045efcd3d938d5ac506eafef3b1551fa8edac;p=libsvgtiny.git diff --git a/src/svgtiny.c b/src/svgtiny.c index db0d59b..a77e3b4 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -697,22 +697,21 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, lwc_string_unref(svg_name_lwc); dom_string_unref(svg_name); - /* get graphic dimensions */ + /* initialize the state struct with zeros */ memset(&state, 0, sizeof(state)); + + /* get graphic dimensions */ state.diagram = diagram; state.document = document; 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; - } + 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) \ @@ -725,6 +724,19 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, #include "svgtiny_strings.h" #undef SVGTINY_STRING_ACTION2 + /* Intern SVG's xmlns separately because it's an lwc_string + * and not a dom_string. We initialize its pointer to NULL + * because the "cleanup:" test to see if it needs to be free'd + * looks for NULL. Returning a LIBDOM_ERROR on failure is not + * perfect but it's the closest of the available options. */ + state.interned_svg_xmlns = NULL; + if (lwc_intern_string("http://www.w3.org/2000/svg", + 26, + &state.interned_svg_xmlns) != lwc_error_ok) { + code = svgtiny_LIBDOM_ERROR; + goto cleanup; + } + svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height); diagram->width = width; diagram->height = height; @@ -762,6 +774,11 @@ cleanup: dom_string_unref(state.interned_##s); #include "svgtiny_strings.h" #undef SVGTINY_STRING_ACTION2 + + if (state.interned_svg_xmlns != NULL) { + lwc_string_unref(state.interned_svg_xmlns); + } + return code; } @@ -2055,6 +2072,13 @@ void svgtiny_parse_paint_attributes(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; + exc = dom_element_get_attribute(node, state->interned_fill, &attr); if (exc == DOM_NO_ERR && attr != NULL) { svgtiny_parse_color(attr, &state->fill, &state->fill_grad, state); @@ -2076,6 +2100,14 @@ void svgtiny_parse_paint_attributes(dom_element *node, exc = dom_element_get_attribute(node, state->interned_style, &attr); if (exc == DOM_NO_ERR && attr != NULL) { + /* 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. */ char *style = strndup(dom_string_data(attr), dom_string_byte_length(attr)); const char *s; @@ -2108,6 +2140,10 @@ void svgtiny_parse_paint_attributes(dom_element *node, free(style); dom_string_unref(attr); } + + if (inline_sheet != NULL) { + css_stylesheet_destroy(inline_sheet); + } }