X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fsvgtiny.c;h=74ce7eb1775cb92315ac8d7d521ef1533ab2c4a2;hb=aae96e5998971764de34a5e1755a8b27568e5605;hp=a77e3b46d9f7c0ca382190075f6971af475c4da9;hpb=9d74009dd53f0d4cbb1101c9cffe0fda7f983bf2;p=libsvgtiny.git diff --git a/src/svgtiny.c b/src/svgtiny.c index a77e3b4..74ce7eb 100644 --- a/src/svgtiny.c +++ b/src/svgtiny.c @@ -2071,14 +2071,23 @@ void svgtiny_parse_paint_attributes(dom_element *node, { dom_string *attr; dom_exception exc; + css_error code; + uint8_t fill_opacity_type; + css_fixed fill_opacity; + uint8_t stroke_opacity_type; + css_fixed stroke_opacity; /* 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. */ + * result if it is NULL, and css_stylesheet_destroy() checks + * for that case. */ css_stylesheet *inline_sheet = NULL; + /* Initialize this to NULL for the same reason: so that we can + * safely destroy it later even if we never populated it. */ + css_select_results *styles = 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); @@ -2141,8 +2150,49 @@ void svgtiny_parse_paint_attributes(dom_element *node, dom_string_unref(attr); } - if (inline_sheet != NULL) { + struct dom_element *parent; + dom_element_parent_node(node, &parent); + if (parent == NULL) { + /* This is the root node, skip it. + * + * While initialising its selection state, libcss sets its + * node_data->bloom pointer using css__get_parent_bloom(). + * But if there is no parent, that function returns, + * + * static css_bloom empty_bloom[CSS_BLOOM_SIZE]; + * + * A problem later arises because when libcss FINALISES its + * selection state, it frees node_data->bloom! That obviously + * won't work then node has no parent, i.e. if it's the root + * element. + */ css_stylesheet_destroy(inline_sheet); + return; + } + else { + /* We only needed to know if it was NULL */ + dom_node_unref(parent); + } + + code = svgtiny_select_style(state, node, inline_sheet, &styles); + css_stylesheet_destroy(inline_sheet); + if (code != CSS_OK) { + return; + } + + fill_opacity_type = css_computed_fill_opacity( + styles->styles[CSS_PSEUDO_ELEMENT_NONE], + &fill_opacity); + stroke_opacity_type = css_computed_stroke_opacity( + styles->styles[CSS_PSEUDO_ELEMENT_NONE], + &stroke_opacity); + css_select_results_destroy(styles); + + if (fill_opacity_type == CSS_FILL_OPACITY_SET) { + state->fill_opacity = FIXTOFLT(fill_opacity); + } + if (stroke_opacity_type == CSS_STROKE_OPACITY_SET) { + state->stroke_opacity = FIXTOFLT(stroke_opacity); } } @@ -2397,6 +2447,8 @@ struct svgtiny_shape *svgtiny_add_shape(struct svgtiny_parse_state *state) shape->text = 0; shape->fill = state->fill; shape->stroke = state->stroke; + shape->fill_opacity = state->fill_opacity; + shape->stroke_opacity = state->stroke_opacity; shape->stroke_width = lroundf((float) state->stroke_width * (state->ctm.a + state->ctm.d) / 2.0); if (0 < state->stroke_width && shape->stroke_width == 0)