From 6f16b10019d7699aff4d5bbc64999a5fd1ce7457 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 14 Jan 2015 19:26:49 +0100 Subject: [PATCH] [autofit] Add embedded arrays for points and contours. This avoids at least two malloc calls for typical glyphs. * src/autofit/afhints.h (AF_POINTS_EMBEDDED, AF_CONTOURS_EMBEDDED): New macros. (AF_GlyphHintsRec): Add two arrays for contours and points. * src/autofit/afhints.c (af_glyph_hints_init, af_glyph_hints_done): Updated. (af_glyph_hints_reload): Only allocate data if number of contours or points exceeds given threshold values. --- ChangeLog | 15 +++++++++++++++ src/autofit/afhints.c | 27 +++++++++++++++++++++------ src/autofit/afhints.h | 11 +++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2afb85aa..0ee008e77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2015-01-14 Behdad Esfahbod + + [autofit] Add embedded arrays for points and contours. + + This avoids at least two malloc calls for typical glyphs. + + * src/autofit/afhints.h (AF_POINTS_EMBEDDED, AF_CONTOURS_EMBEDDED): + New macros. + (AF_GlyphHintsRec): Add two arrays for contours and points. + + * src/autofit/afhints.c (af_glyph_hints_init, af_glyph_hints_done): + Updated. + (af_glyph_hints_reload): Only allocate data if number of contours or + points exceeds given threshold values. + 2015-01-14 Behdad Esfahbod [autofit] Allocate hints object on the stack. diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index f3cc50f20..32e445b19 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -488,7 +488,8 @@ af_glyph_hints_init( AF_GlyphHints hints, FT_Memory memory ) { - FT_ZERO( hints ); + /* no need to initialize the embedded items */ + FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) ); hints->memory = memory; } @@ -521,13 +522,15 @@ FT_FREE( axis->edges ); } - FT_FREE( hints->contours ); + if ( hints->contours != hints->embedded.contours ) + FT_FREE( hints->contours ); hints->max_contours = 0; hints->num_contours = 0; - FT_FREE( hints->points ); - hints->num_points = 0; + if ( hints->points != hints->embedded.points ) + FT_FREE( hints->points ); hints->max_points = 0; + hints->num_points = 0; hints->memory = NULL; } @@ -572,8 +575,14 @@ /* first of all, reallocate the contours array if necessary */ new_max = (FT_UInt)outline->n_contours; old_max = hints->max_contours; - if ( new_max > old_max ) + + if ( new_max <= AF_CONTOURS_EMBEDDED ) + hints->contours = hints->embedded.contours; + else if ( new_max > old_max ) { + if ( hints->contours == hints->embedded.contours ) + hints->contours = NULL; + new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) @@ -589,8 +598,14 @@ */ new_max = (FT_UInt)( outline->n_points + 2 ); old_max = hints->max_points; - if ( new_max > old_max ) + + if ( new_max <= AF_POINTS_EMBEDDED ) + hints->points = hints->embedded.points; + else if ( new_max > old_max ) { + if ( hints->points == hints->embedded.points ) + hints->points = NULL; + new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) ) diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h index 92101de7c..01e9d706e 100644 --- a/src/autofit/afhints.h +++ b/src/autofit/afhints.h @@ -324,6 +324,9 @@ FT_BEGIN_HEADER } AF_AxisHintsRec, *AF_AxisHints; +#define AF_POINTS_EMBEDDED 96 /* number of embedded points */ +#define AF_CONTOURS_EMBEDDED 8 /* number of embedded contours */ + typedef struct AF_GlyphHintsRec_ { FT_Memory memory; @@ -352,6 +355,14 @@ FT_BEGIN_HEADER FT_Pos xmin_delta; /* used for warping */ FT_Pos xmax_delta; + /* Two arrays to avoid allocation penalty. */ + /* The `embedded' structure must be the last element! */ + struct + { + AF_Point contours[AF_CONTOURS_EMBEDDED]; + AF_PointRec points[AF_POINTS_EMBEDDED]; + } embedded; + } AF_GlyphHintsRec;