diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 99c429810..6ed0165eb 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -56,26 +56,42 @@ _cairo_polygon_init (cairo_polygon_t *polygon) void _cairo_polygon_fini (cairo_polygon_t *polygon) { - if (polygon->edges_size) { + if (polygon->edges != polygon->edges_embedded) free (polygon->edges); - polygon->edges = NULL; - polygon->edges_size = 0; - polygon->num_edges = 0; - } + + polygon->edges = NULL; + polygon->edges_size = 0; + polygon->num_edges = 0; polygon->has_current_point = FALSE; } +/* make room for at least one more edge */ static cairo_status_t _cairo_polygon_grow (cairo_polygon_t *polygon) { cairo_edge_t *new_edges; int old_size = polygon->edges_size; - int new_size = old_size ? 2 * old_size : 16; + int embedded_size = sizeof (polygon->edges_embedded) / sizeof (polygon->edges_embedded[0]); + int new_size = 2 * MAX (old_size, 16); + + /* we have a local buffer at polygon->edges_embedded. try to fulfill the request + * from there. */ + if (old_size < embedded_size) { + polygon->edges = polygon->edges_embedded; + polygon->edges_size = embedded_size; + return CAIRO_STATUS_SUCCESS; + } assert (polygon->num_edges <= polygon->edges_size); - new_edges = realloc (polygon->edges, new_size * sizeof (cairo_edge_t)); + if (polygon->edges == polygon->edges_embedded) { + new_edges = malloc (new_size * sizeof (cairo_edge_t)); + if (new_edges) + memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t)); + } else { + new_edges = realloc (polygon->edges, new_size * sizeof (cairo_edge_t)); + } if (new_edges == NULL) { return CAIRO_STATUS_NO_MEMORY; diff --git a/src/cairoint.h b/src/cairoint.h index 7a4c9d577..32519509f 100755 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -428,6 +428,7 @@ typedef struct _cairo_polygon { int num_edges; int edges_size; cairo_edge_t *edges; + cairo_edge_t edges_embedded[8]; } cairo_polygon_t; typedef struct _cairo_spline {