mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-14 05:10:34 +01:00
[cairo-gstate] Use a local buffer on the stack for small glyph operations
We duplicate the incoming glyph array for two reasons: 1) applying transformations, and 2) to let the lower level functions have a glyph array they can modify. By using a 2kb array on the stack we can avoid malloc() for requests of less than 100 glyphs. The size of the array can be tuned by setting CAIRO_STACK_BUFFER_SIZE.
This commit is contained in:
parent
da60bc45f2
commit
e7ed9eee76
1 changed files with 23 additions and 7 deletions
|
|
@ -1464,6 +1464,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define STACK_GLYPHS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_glyph_t)))
|
||||
cairo_status_t
|
||||
_cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
||||
const cairo_glyph_t *glyphs,
|
||||
|
|
@ -1472,6 +1473,8 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
cairo_status_t status;
|
||||
cairo_pattern_union_t source_pattern;
|
||||
cairo_glyph_t *transformed_glyphs;
|
||||
cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
|
||||
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
|
|
@ -1484,9 +1487,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
if (num_glyphs <= STACK_GLYPHS_LEN) {
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
} else {
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
|
||||
transformed_glyphs);
|
||||
|
|
@ -1501,7 +1508,9 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
|
|||
gstate->scaled_font);
|
||||
|
||||
_cairo_pattern_fini (&source_pattern.base);
|
||||
free (transformed_glyphs);
|
||||
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
free (transformed_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1513,13 +1522,17 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *transformed_glyphs = NULL;
|
||||
cairo_glyph_t *transformed_glyphs;
|
||||
cairo_glyph_t stack_transformed_glyphs[STACK_GLYPHS_LEN];
|
||||
|
||||
status = _cairo_gstate_ensure_scaled_font (gstate);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (num_glyphs < STACK_GLYPHS_LEN)
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
else
|
||||
transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
|
||||
if (transformed_glyphs == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
@ -1530,9 +1543,12 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
transformed_glyphs, num_glyphs,
|
||||
path);
|
||||
|
||||
free (transformed_glyphs);
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
free (transformed_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
#undef STACK_GLYPHS_LEN
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_set_antialias (cairo_gstate_t *gstate,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue