shithub: freetype+ttf2subf

Download patch

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.

git/fs: mount .git/fs: mount/attach disallowed
--- 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;