[cairo-pattern] Grow color-stops array exponentially

This commit is contained in:
Behdad Esfahbod 2007-03-13 20:49:52 -04:00
parent e878f2259b
commit 4514fdca1b
2 changed files with 45 additions and 19 deletions

View file

@ -119,9 +119,11 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
if (other->n_stops)
{
pattern->stops = malloc (other->n_stops *
pattern->stops = malloc (other->stops_size *
sizeof (pixman_gradient_stop_t));
if (pattern->stops == NULL) {
pattern->stops_size = 0;
pattern->n_stops = 0;
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
@ -221,8 +223,9 @@ _cairo_pattern_init_gradient (cairo_gradient_pattern_t *pattern,
{
_cairo_pattern_init (&pattern->base, type);
pattern->stops = NULL;
pattern->n_stops = 0;
pattern->n_stops = 0;
pattern->stops_size = 0;
pattern->stops = NULL;
}
void
@ -648,6 +651,28 @@ cairo_pattern_set_user_data (cairo_pattern_t *pattern,
key, user_data, destroy);
}
/* make room for at least one more color stop */
static cairo_status_t
_cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
{
pixman_gradient_stop_t *new_stops;
int old_size = pattern->stops_size;
int new_size = old_size ? 2 * old_size : 8;
assert (pattern->n_stops <= pattern->stops_size);
new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
if (new_stops == NULL) {
return CAIRO_STATUS_NO_MEMORY;
}
pattern->stops = new_stops;
pattern->stops_size = new_size;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
double offset,
@ -656,38 +681,38 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
double blue,
double alpha)
{
pixman_gradient_stop_t *new_stops;
pixman_gradient_stop_t *stops;
cairo_fixed_t x;
unsigned int i;
new_stops = realloc (pattern->stops, (pattern->n_stops + 1) *
sizeof (pixman_gradient_stop_t));
if (new_stops == NULL)
{
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
if (pattern->n_stops >= pattern->stops_size) {
cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
if (status) {
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
}
pattern->stops = new_stops;
stops = pattern->stops;
x = _cairo_fixed_from_double (offset);
for (i = 0; i < pattern->n_stops; i++)
{
if (x < new_stops[i].x)
if (x < stops[i].x)
{
memmove (&new_stops[i + 1], &new_stops[i],
memmove (&stops[i + 1], &stops[i],
sizeof (pixman_gradient_stop_t) * (pattern->n_stops - i));
break;
}
}
new_stops[i].x = x;
stops[i].x = x;
new_stops[i].color.red = _cairo_color_double_to_short (red);
new_stops[i].color.green = _cairo_color_double_to_short (green);
new_stops[i].color.blue = _cairo_color_double_to_short (blue);
new_stops[i].color.alpha = _cairo_color_double_to_short (alpha);
stops[i].color.red = _cairo_color_double_to_short (red);
stops[i].color.green = _cairo_color_double_to_short (green);
stops[i].color.blue = _cairo_color_double_to_short (blue);
stops[i].color.alpha = _cairo_color_double_to_short (alpha);
pattern->n_stops++;
}

View file

@ -1178,8 +1178,9 @@ typedef struct _cairo_surface_pattern {
typedef struct _cairo_gradient_pattern {
cairo_pattern_t base;
unsigned int n_stops;
unsigned int stops_size;
pixman_gradient_stop_t *stops;
unsigned int n_stops;
} cairo_gradient_pattern_t;
typedef struct _cairo_linear_pattern {