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
}
if (exc == DOM_NO_ERR && attr != NULL) {
if (dom_string_data(attr)[0] == (uint8_t) '#') {
char *s = strndup(dom_string_data(attr) + 1,
- dom_string_length(attr) - 1);
+ dom_string_byte_length(attr) - 1);
svgtiny_find_gradient(s, state);
free(s);
}
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_length(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
state->gradient_transform.a = a;
state->gradient_transform.b = b;
state->gradient_transform.c = c;
dom_element *stop;
float offset = -1;
svgtiny_colour color = svgtiny_TRANSPARENT;
- exc = dom_nodelist_item(stops, stopnr, &stop);
+ exc = dom_nodelist_item(stops, stopnr,
+ (dom_node **) (void *) &stop);
if (exc != DOM_NO_ERR)
continue;
exc = dom_element_get_attribute(stop,
&attr);
if (exc == DOM_NO_ERR && attr != NULL) {
char *s = strndup(dom_string_data(attr),
- dom_string_length(attr));
+ dom_string_byte_length(attr));
offset = svgtiny_parse_gradient_offset(s);
free(s);
dom_string_unref(attr);
&attr);
if (exc == DOM_NO_ERR && attr != NULL) {
char *content = strndup(dom_string_data(attr),
- dom_string_length(attr));
+ dom_string_byte_length(attr));
const char *s;
dom_string *value;
if ((s = strstr(content, "stop-color:"))) {
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++;
object_x0, object_y0, object_x1, object_y1);
#endif
- /* compute gradient vector */
- fprintf(stderr, "x1 %*s, y1 %*s, x2 %*s, y2 %*s\n",
- dom_string_length(state->gradient_x1),
- dom_string_data(state->gradient_x1),
- dom_string_length(state->gradient_y1),
- dom_string_data(state->gradient_y1),
- dom_string_length(state->gradient_x2),
- dom_string_data(state->gradient_x2),
- dom_string_length(state->gradient_y2),
- dom_string_data(state->gradient_y2));
-
if (!state->gradient_user_space_on_use) {
gradient_x0 = object_x0 +
svgtiny_parse_length(state->gradient_x1,
/* 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;
/* 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
/* render triangles */
stop_count = state->linear_gradient_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)