ref: 6f16b10019d7699aff4d5bbc64999a5fd1ce7457
parent: c27336567bf9ec18734506f68fc03e328c479bc9
author: Behdad Esfahbod <[email protected]>
date: Wed Jan 14 14:26:49 EST 2015
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2015-01-14 Behdad Esfahbod <[email protected]>
+ [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 <[email protected]>
+
[autofit] Allocate hints object on the stack.
This avoids one malloc per load.
--- 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 ) )
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -324,6 +324,9 @@
} 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;
@@ -351,6 +354,14 @@
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;