Commit d180ac70fca55c75272d9668b9ed1418dc9e22f9

Werner Lemberg 2012-09-18T23:26:37

[autofit] Implement Infinality's `increase glyph heights'. This is an improved version of a similar fix contained in the so-called `Infinality patch', taken from http://www.infinality.net/fedora/linux/zips/freetype-infinality-2.4.10-20120616_01-x86_64.tar.bz2 which addresses various enhancements of the auto-hinter. Without properties to control a module's metadata it wasn't possible to adapt the patches because everything was originally controlled by environment variables which I consider not suitable in general. A patch to control `increase_x_height' follows. * src/autofit/afglobal.h (AF_PROP_INCREASE_X_HEIGHT_MIN, AF_PROP_INCREASE_X_HEIGHT_MAX): New macros. (AF_FaceGlobalsRec): Add `increase_x_height' member. * src/autofit/afglobal.c (af_face_globals_new): Initialize it. * src/autofit/aflatin.c (af_latin_metrics_scale_dim), * src/autofit/aflatin2.c (af_latin2_metrics_scale_dim): Implement handling of `increase_x_height'.

diff --git a/ChangeLog b/ChangeLog
index a4f4a12..bc2ecf4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
 2012-09-18  Werner Lemberg  <wl@gnu.org>
 
+	[autofit] Implement Infinality's `increase glyph heights'.
+
+	This is an improved version of a similar fix contained in the
+	so-called `Infinality patch', taken from
+
+	  http://www.infinality.net/fedora/linux/zips/freetype-infinality-2.4.10-20120616_01-x86_64.tar.bz2
+
+	which addresses various enhancements of the auto-hinter.  Without
+	properties to control a module's metadata it wasn't possible to
+	adapt the patches because everything was originally controlled by
+	environment variables which I consider not suitable in general.
+
+	A patch to control `increase_x_height' follows.
+
+	* src/autofit/afglobal.h (AF_PROP_INCREASE_X_HEIGHT_MIN,
+	AF_PROP_INCREASE_X_HEIGHT_MAX): New macros.
+	(AF_FaceGlobalsRec): Add `increase_x_height' member.
+	* src/autofit/afglobal.c (af_face_globals_new): Initialize it.
+
+	* src/autofit/aflatin.c (af_latin_metrics_scale_dim),
+	* src/autofit/aflatin2.c (af_latin2_metrics_scale_dim): Implement
+	handling of `increase_x_height'.
+
+2012-09-18  Werner Lemberg  <wl@gnu.org>
+
 	[autofit] Add hierarchical property access to some structures.
 
 	* src/autofit/afglobal.h: Include `afmodule.h'.
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 383bb11..27a883a 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -182,6 +182,8 @@
       globals = NULL;
     }
 
+    globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
+
   Exit:
     *aglobals = globals;
     return error;
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index 74b179d..2e24900 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -28,14 +28,10 @@
 FT_BEGIN_HEADER
 
 
-  /************************************************************************/
-  /************************************************************************/
-  /*****                                                              *****/
-  /*****                  F A C E   G L O B A L S                     *****/
-  /*****                                                              *****/
-  /************************************************************************/
-  /************************************************************************/
-
+  /*
+   *  Default values and flags for both autofitter globals (found in
+   *  AF_ModuleRec) and face globals (in AF_FaceGlobalsRec).
+   */
 
   /* index of fallback script in `af_script_classes' */
 #define AF_SCRIPT_FALLBACK  2
@@ -44,6 +40,19 @@ FT_BEGIN_HEADER
   /* if this flag is set, we have an ASCII digit     */
 #define AF_DIGIT            0x80
 
+  /* `increase-x-height' property */
+#define AF_PROP_INCREASE_X_HEIGHT_MIN  6
+#define AF_PROP_INCREASE_X_HEIGHT_MAX  0
+
+
+  /************************************************************************/
+  /************************************************************************/
+  /*****                                                              *****/
+  /*****                  F A C E   G L O B A L S                     *****/
+  /*****                                                              *****/
+  /************************************************************************/
+  /************************************************************************/
+
 
   /*
    *  Note that glyph_scripts[] is used to map each glyph into
@@ -56,6 +65,9 @@ FT_BEGIN_HEADER
     FT_Long           glyph_count;    /* same as face->num_glyphs */
     FT_Byte*          glyph_scripts;
 
+    /* per-face auto-hinter properties */
+    FT_UInt           increase_x_height;
+
     AF_ScriptMetrics  metrics[AF_SCRIPT_MAX];
 
     AF_Module         module;         /* to access global properties */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 539619a..1c5bb45 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -613,9 +613,26 @@
 
       if ( blue )
       {
-        FT_Pos  scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
-        FT_Pos  fitted = ( scaled + 40 ) & ~63;
-
+        FT_Pos   scaled;
+        FT_Pos   threshold;
+        FT_Pos   fitted;
+        FT_UInt  limit;
+        FT_UInt  ppem;
+
+
+        scaled    = FT_MulFix( blue->shoot.org, scaler->y_scale );
+        ppem      = metrics->root.scaler.face->size->metrics.x_ppem;
+        limit     = metrics->root.globals->increase_x_height;
+        threshold = 40;
+
+        /* if the `increase_x_height' property is active, */
+        /* we round up much more often                    */
+        if ( limit                                 &&
+             ppem <= limit                         &&
+             ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
+          threshold = 52;
+
+        fitted = ( scaled + threshold ) & ~63;
 
         if ( scaled != fitted )
         {
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index 1aa312e..26f7490 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -562,8 +562,26 @@
 
       if ( blue )
       {
-        FT_Pos  scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
-        FT_Pos  fitted = ( scaled + 40 ) & ~63;
+        FT_Pos   scaled;
+        FT_Pos   threshold;
+        FT_Pos   fitted;
+        FT_UInt  limit;
+        FT_UInt  ppem;
+
+
+        scaled    = FT_MulFix( blue->shoot.org, scaler->y_scale );
+        ppem      = metrics->root.scaler.face->size->metrics.x_ppem;
+        limit     = metrics->root.globals->increase_x_height;
+        threshold = 40;
+
+        /* if the `increase_x_height' property is active, */
+        /* we round up much more often                    */
+        if ( limit                                 &&
+             ppem <= limit                         &&
+             ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
+          threshold = 52;
+
+        fitted = ( scaled + threshold ) & ~63;
 
 #if 1
         if ( scaled != fitted )