X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fsvgtiny.c;h=efac78882da2185d0cfea1b13a880f994bc72d83;hb=1e71d0472529b96ac35e2e4425b66e29146a01c1;hp=ec15b35496282dbe823f00a661b22a099e134551;hpb=059c01c90f5d3e64287853293097f56b8ca8ec1d;p=libsvgtiny.git diff --git a/src/svgtiny.c b/src/svgtiny.c index ec15b35..efac788 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -54,54 +54,74 @@ static void svgtiny_parse_transform_attributes(dom_element *node, static svgtiny_code svgtiny_add_path(float *p, unsigned int n, struct svgtiny_parse_state *state); static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, + struct svgtiny_parse_state_gradient *grad, struct svgtiny_parse_state *state); /** - * Set the local externally-stored parts of a parse state. - * Call this in functions that made a new state on the stack. - * Doesn't make own copy of global state, such as the interned string list. + * Call this to ref the strings in a gradient state. */ -static void svgtiny_setup_state_local(struct svgtiny_parse_state *state) +static void svgtiny_grad_string_ref(struct svgtiny_parse_state_gradient *grad) { - if (state->gradient_x1 != NULL) { - dom_string_ref(state->gradient_x1); + if (grad->gradient_x1 != NULL) { + dom_string_ref(grad->gradient_x1); } - if (state->gradient_y1 != NULL) { - dom_string_ref(state->gradient_y1); + if (grad->gradient_y1 != NULL) { + dom_string_ref(grad->gradient_y1); } - if (state->gradient_x2 != NULL) { - dom_string_ref(state->gradient_x2); + if (grad->gradient_x2 != NULL) { + dom_string_ref(grad->gradient_x2); } - if (state->gradient_y2 != NULL) { - dom_string_ref(state->gradient_y2); + if (grad->gradient_y2 != NULL) { + dom_string_ref(grad->gradient_y2); } } /** - * Cleanup the local externally-stored parts of a parse state. - * Call this in functions that made a new state on the stack. - * Doesn't cleanup global state, such as the interned string list. + * Call this to clean up the strings in a gradient state. */ -static void svgtiny_cleanup_state_local(struct svgtiny_parse_state *state) +static void svgtiny_grad_string_cleanup( + struct svgtiny_parse_state_gradient *grad) { - if (state->gradient_x1 != NULL) { - dom_string_unref(state->gradient_x1); - state->gradient_x1 = NULL; + if (grad->gradient_x1 != NULL) { + dom_string_unref(grad->gradient_x1); + grad->gradient_x1 = NULL; } - if (state->gradient_y1 != NULL) { - dom_string_unref(state->gradient_y1); - state->gradient_y1 = NULL; + if (grad->gradient_y1 != NULL) { + dom_string_unref(grad->gradient_y1); + grad->gradient_y1 = NULL; } - if (state->gradient_x2 != NULL) { - dom_string_unref(state->gradient_x2); - state->gradient_x2 = NULL; + if (grad->gradient_x2 != NULL) { + dom_string_unref(grad->gradient_x2); + grad->gradient_x2 = NULL; } - if (state->gradient_y2 != NULL) { - dom_string_unref(state->gradient_y2); - state->gradient_y2 = NULL; + if (grad->gradient_y2 != NULL) { + dom_string_unref(grad->gradient_y2); + grad->gradient_y2 = NULL; } } +/** + * Set the local externally-stored parts of a parse state. + * Call this in functions that made a new state on the stack. + * Doesn't make own copy of global state, such as the interned string list. + */ +static void svgtiny_setup_state_local(struct svgtiny_parse_state *state) +{ + svgtiny_grad_string_ref(&(state->fill_grad)); + svgtiny_grad_string_ref(&(state->stroke_grad)); +} + +/** + * Cleanup the local externally-stored parts of a parse state. + * Call this in functions that made a new state on the stack. + * Doesn't cleanup global state, such as the interned string list. + */ +static void svgtiny_cleanup_state_local(struct svgtiny_parse_state *state) +{ + svgtiny_grad_string_cleanup(&(state->fill_grad)); + svgtiny_grad_string_cleanup(&(state->stroke_grad)); +} + /** * Create a new svgtiny_diagram structure. @@ -248,7 +268,6 @@ svgtiny_code svgtiny_parse(struct svgtiny_diagram *diagram, state.fill = 0x000000; state.stroke = svgtiny_TRANSPARENT; state.stroke_width = 1; - state.linear_gradient_stop_count = 0; /* parse tree */ code = svgtiny_parse_svg(svg, state); @@ -1365,13 +1384,13 @@ void svgtiny_parse_paint_attributes(dom_element *node, exc = dom_element_get_attribute(node, state->interned_fill, &attr); if (exc == DOM_NO_ERR && attr != NULL) { - svgtiny_parse_color(attr, &state->fill, state); + svgtiny_parse_color(attr, &state->fill, &state->fill_grad, state); dom_string_unref(attr); } exc = dom_element_get_attribute(node, state->interned_stroke, &attr); if (exc == DOM_NO_ERR && attr != NULL) { - svgtiny_parse_color(attr, &state->stroke, state); + svgtiny_parse_color(attr, &state->stroke, &state->stroke_grad, state); dom_string_unref(attr); } @@ -1393,7 +1412,7 @@ void svgtiny_parse_paint_attributes(dom_element *node, while (*s == ' ') s++; value = strndup(s, strcspn(s, "; ")); - _svgtiny_parse_color(value, &state->fill, state); + _svgtiny_parse_color(value, &state->fill, &state->fill_grad, state); free(value); } if ((s = strstr(style, "stroke:"))) { @@ -1401,7 +1420,7 @@ void svgtiny_parse_paint_attributes(dom_element *node, while (*s == ' ') s++; value = strndup(s, strcspn(s, "; ")); - _svgtiny_parse_color(value, &state->stroke, state); + _svgtiny_parse_color(value, &state->stroke, &state->stroke_grad, state); free(value); } if ((s = strstr(style, "stroke-width:"))) { @@ -1424,6 +1443,7 @@ void svgtiny_parse_paint_attributes(dom_element *node, */ static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, + struct svgtiny_parse_state_gradient *grad, struct svgtiny_parse_state *state) { unsigned int r, g, b; @@ -1455,19 +1475,21 @@ static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, } else if (5 < len && s[0] == 'u' && s[1] == 'r' && s[2] == 'l' && s[3] == '(') { - if (s[4] == '#') { + if (grad == NULL) { + *c = svgtiny_RGB(0, 0, 0); + } else if (s[4] == '#') { id = strdup(s + 5); if (!id) return; rparen = strchr(id, ')'); if (rparen) *rparen = 0; - svgtiny_find_gradient(id, state); + svgtiny_find_gradient(id, grad, state); free(id); - if (state->linear_gradient_stop_count == 0) + if (grad->linear_gradient_stop_count == 0) *c = svgtiny_TRANSPARENT; - else if (state->linear_gradient_stop_count == 1) - *c = state->gradient_stop[0].color; + else if (grad->linear_gradient_stop_count == 1) + *c = grad->gradient_stop[0].color; else *c = svgtiny_LINEAR_GRADIENT; } @@ -1481,11 +1503,12 @@ static void _svgtiny_parse_color(const char *s, svgtiny_colour *c, } void svgtiny_parse_color(dom_string *s, svgtiny_colour *c, + struct svgtiny_parse_state_gradient *grad, struct svgtiny_parse_state *state) { - char *ss = strndup(dom_string_data(s), dom_string_byte_length(s)); - _svgtiny_parse_color(ss, c, state); - free(ss); + dom_string_ref(s); + _svgtiny_parse_color(dom_string_data(s), c, grad, state); + dom_string_unref(s); } /**