X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fsvgtiny.c;h=74ce7eb1775cb92315ac8d7d521ef1533ab2c4a2;hb=aae96e5998971764de34a5e1755a8b27568e5605;hp=2ca5a58664f46077a5ce4358b91f16b28b06eb8c;hpb=751f149981f754a5531ddd1f18a5be4445ae05be;p=libsvgtiny.git diff --git a/src/svgtiny.c b/src/svgtiny.c index 2ca5a58..74ce7eb 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -17,6 +17,8 @@ #include #include +#include + #include "svgtiny.h" #include "svgtiny_internal.h" @@ -38,6 +40,12 @@ #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, struct svgtiny_parse_state state); static svgtiny_code svgtiny_parse_path(dom_element *path, @@ -610,6 +618,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; @@ -688,13 +697,23 @@ 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 */ + 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) \ @@ -705,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; @@ -723,10 +755,17 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, 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); @@ -735,10 +774,181 @@ 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; } +/** + * Parse a single