+ exc = dom_element_get_attribute(linear, state->interned_y2, &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ dom_string_unref(grad->gradient_y2);
+ grad->gradient_y2 = attr;
+ attr = NULL;
+ }
+
+ exc = dom_element_get_attribute(linear, state->interned_gradientUnits,
+ &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ grad->gradient_user_space_on_use =
+ dom_string_isequal(attr,
+ state->interned_userSpaceOnUse);
+ dom_string_unref(attr);
+ }
+
+ exc = dom_element_get_attribute(linear,
+ state->interned_gradientTransform,
+ &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ float a = 1, b = 0, c = 0, d = 1, e = 0, f = 0;
+ char *s = strndup(dom_string_data(attr),
+ dom_string_byte_length(attr));
+ if (s == NULL) {
+ dom_string_unref(attr);
+ return svgtiny_OUT_OF_MEMORY;
+ }
+ svgtiny_parse_transform(s, &a, &b, &c, &d, &e, &f);
+ free(s);
+ #ifdef GRADIENT_DEBUG
+ fprintf(stderr, "transform %g %g %g %g %g %g\n",
+ a, b, c, d, e, f);
+ #endif
+ grad->gradient_transform.a = a;
+ grad->gradient_transform.b = b;
+ grad->gradient_transform.c = c;
+ grad->gradient_transform.d = d;
+ grad->gradient_transform.e = e;
+ grad->gradient_transform.f = f;
+ dom_string_unref(attr);
+ }
+
+ exc = dom_element_get_elements_by_tag_name(linear,
+ state->interned_stop,
+ &stops);
+ if (exc == DOM_NO_ERR && stops != NULL) {
+ uint32_t listlen, stopnr;
+ exc = dom_nodelist_get_length(stops, &listlen);
+ if (exc != DOM_NO_ERR) {
+ dom_nodelist_unref(stops);
+ goto no_more_stops;
+ }
+
+ for (stopnr = 0; stopnr < listlen; ++stopnr) {
+ dom_element *stop;
+ float offset = -1;
+ svgtiny_colour color = svgtiny_TRANSPARENT;
+ exc = dom_nodelist_item(stops, stopnr,
+ (dom_node **) (void *) &stop);
+ if (exc != DOM_NO_ERR)
+ continue;
+ exc = dom_element_get_attribute(stop,
+ state->interned_offset,
+ &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ char *s = strndup(dom_string_data(attr),
+ dom_string_byte_length(attr));
+ offset = svgtiny_parse_gradient_offset(s);
+ free(s);
+ dom_string_unref(attr);
+ }
+ exc = dom_element_get_attribute(stop,
+ state->interned_stop_color,
+ &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ svgtiny_parse_color(attr, &color, NULL, state);
+ dom_string_unref(attr);
+ }
+ exc = dom_element_get_attribute(stop,
+ state->interned_style,
+ &attr);
+ if (exc == DOM_NO_ERR && attr != NULL) {
+ char *content = strndup(dom_string_data(attr),
+ dom_string_byte_length(attr));