void svgtiny_find_gradient(const char *id, struct svgtiny_parse_state *state)
{
dom_element *gradient;
- dom_string *id_str;
+ dom_string *id_str, *name;
dom_exception exc;
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "svgtiny_find_gradient: id \"%s\"\n", id);
+ #endif
state->linear_gradient_stop_count = 0;
if (state->gradient_x1 != NULL)
state->gradient_transform.e = 0;
state->gradient_transform.f = 0;
- exc = dom_string_create_interned((const uint8_t *) id, strlen(id),
- &id_str);
+ exc = dom_string_create_interned((const uint8_t *) id,
+ strlen(id), &id_str);
if (exc != DOM_NO_ERR)
return;
exc = dom_document_get_element_by_id(state->document, id_str,
&gradient);
dom_string_unref(id_str);
- if (exc != DOM_NO_ERR)
- return;
-
- if (gradient == NULL) {
+ if (exc != DOM_NO_ERR || gradient == NULL) {
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "gradient \"%s\" not found\n", id);
+ #endif
return;
}
- exc = dom_node_get_node_name(gradient, &id_str);
+ exc = dom_node_get_node_name(gradient, &name);
if (exc != DOM_NO_ERR) {
dom_node_unref(gradient);
return;
}
- if (dom_string_isequal(id_str, state->interned_linearGradient))
+ if (dom_string_isequal(name, state->interned_linearGradient))
svgtiny_parse_linear_gradient(gradient, state);
- dom_string_unref(id_str);
dom_node_unref(gradient);
+ dom_string_unref(name);
+
+ #ifdef GRADIENT_DEBUG
+ fprintf(stderr, "linear_gradient_stop_count %i\n",
+ state->linear_gradient_stop_count);
+ #endif
}
}
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
state->gradient_transform.a = a;
state->gradient_transform.b = b;
state->gradient_transform.c = c;
dom_string_unref(attr);
}
if (offset != -1 && color != svgtiny_TRANSPARENT) {
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "stop %g %x\n", offset, color);
+ #endif
state->gradient_stop[i].offset = offset;
state->gradient_stop[i].color = color;
i++;
/* invert gradient transform for applying to vertices */
svgtiny_invert_matrix(&state->gradient_transform.a, trans);
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "inverse transform %g %g %g %g %g %g\n",
trans[0], trans[1], trans[2], trans[3],
trans[4], trans[5]);
+ #endif
/* compute points on the path for triangle vertices */
/* r, r0, r1 are distance along gradient vector */
gradient_norm_squared = gradient_dx * gradient_dx +
gradient_dy * gradient_dy;
- pts = svgtiny_list_create(
- sizeof (struct grad_point));
+ pts = svgtiny_list_create(sizeof (struct grad_point));
if (!pts)
return svgtiny_OUT_OF_MEMORY;
for (j = 0; j != n; ) {
gradient_norm_squared;
/* determine steps from change in r */
- steps = ceilf(fabsf(r1 - r0) / 0.05);
+
+ if(isnan(r0) || isnan(r1)) {
+ steps = 1;
+ } else {
+ steps = ceilf(fabsf(r1 - r0) / 0.05);
+ }
+
if (steps == 0)
steps = 1;
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "r0 %g, r1 %g, steps %i\n",
r0, r1, steps);
+ #endif
/* loop through intermediate points */
for (z = 1; z != steps; z++) {
r = ((x_trans - gradient_x0) * gradient_dx +
(y_trans - gradient_y0) * gradient_dy) /
gradient_norm_squared;
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "(%g %g [%g]) ", x, y, r);
+ #endif
point = svgtiny_list_push(pts);
if (!point) {
svgtiny_list_free(pts);
min_pt = svgtiny_list_size(pts) - 1;
}
}
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "\n");
+ #endif
/* next segment start point is this segment end point */
x0 = x1;
y0 = y1;
}
+ #ifdef GRADIENT_DEBUG
fprintf(stderr, "pts size %i, min_pt %i, min_r %.3f\n",
svgtiny_list_size(pts), min_pt, min_r);
+ #endif
+
+ /* There must be at least a single point for the gradient */
+ if (svgtiny_list_size(pts) == 0) {
+ svgtiny_list_free(pts);
+ return svgtiny_OK;
+ }
+
/* render triangles */
stop_count = state->linear_gradient_stop_count;
assert(2 <= stop_count);
/* render triangle vertices with r values for debugging */
#ifdef GRADIENT_DEBUG
- for (unsigned int i = 0; i != pts->size; i++) {
+ for (unsigned int i = 0; i != svgtiny_list_size(pts); i++) {
struct grad_point *point = svgtiny_list_get(pts, i);
struct svgtiny_shape *shape = svgtiny_add_shape(state);
if (!shape)