X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fsvgtiny.c;h=74ce7eb1775cb92315ac8d7d521ef1533ab2c4a2;hb=aae96e5998971764de34a5e1755a8b27568e5605;hp=09adedc66799765c054267ba0c84269fa1e2aa96;hpb=437bbf937bf78d100180407e1e92dd881f170f63;p=libsvgtiny.git diff --git a/src/svgtiny.c b/src/svgtiny.c index 09adedc..74ce7eb 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -42,6 +42,8 @@ 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, @@ -695,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) \ @@ -723,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; @@ -760,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; } @@ -772,27 +791,10 @@ 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(¶ms, &sheet); + code = svgtiny_create_stylesheet(&sheet, false); if (code != CSS_OK) { return svgtiny_LIBCSS_ERROR; } @@ -851,6 +853,37 @@ svgtiny_code svgtiny_parse_style_element(dom_element *style, } +/** + * 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