mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-01 04:28:03 +02:00
[cairo-pattern] Grow color-stops array exponentially
This commit is contained in:
parent
e878f2259b
commit
4514fdca1b
2 changed files with 45 additions and 19 deletions
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue