Commit f9a69132a73bea7a7c1e7726789841acd8235a4b

Wu, Chia-I (吳佳一) 2006-02-11T12:12:02

* include/freetype/config/ftoption.h (AF_CONFIG_OPTION_CJK): #define to enable autofit CJK script support. (#define'd by default) * src/autofit/aflatin.h (AF_LATIN_CONSTANT): New macro. * src/autofit/aflatin.c (af_latin_metrics_init_widths): Make sure that `edge_distance_threshold' is always set. (af_latin_hints_link_segments): Potential divide by 0 bug. Use latin constant in the scoring formula. * src/autofit/afcjk.c: Minor updates due to the above three changes. * docs/TODO, docs/CHANGES: Updated.

diff --git a/ChangeLog b/ChangeLog
index 5d77bb7..8611946 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-02-11  Chia-I Wu  <b90201047@ntu.edu.tw>
+
+	* include/freetype/config/ftoption.h (AF_CONFIG_OPTION_CJK): #define
+	to enable autofit CJK script support. (#define'd by default)
+
+	* src/autofit/aflatin.h (AF_LATIN_CONSTANT): New macro.
+
+	* src/autofit/aflatin.c (af_latin_metrics_init_widths): Make sure that
+	`edge_distance_threshold' is always set.
+	(af_latin_hints_link_segments): Potential divide by 0 bug.
+	Use latin constant in the scoring formula.
+
+	* src/autofit/afcjk.c: Minor updates due to the above three changes.
+
+	* docs/TODO, docs/CHANGES: Updated.
+
 2006-02-09  Chia-I Wu  <b90201047@ntu.edu.tw>
 
 	Introduce experimental autofit CJK module based on akito's autohint
diff --git a/docs/CHANGES b/docs/CHANGES
index 4b35f44..f857684 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -27,9 +27,11 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10
       Also, using the  FT_LOAD_TARGET_LIGHT flags within FT_Load_Glyph
       always forces auto-hinting, as a special exception.
 
-    - Face  metrics  (face->size->metrics) and  glyph  metrics are  no
-      longer rounded.  If  you do not round in  your applications too,
-      you may find glyphs become blurry.
+    - Face  metrics (face->size->metrics)  and  glyph  metrics are  no
+      longer rounded.  If you do not round or round improperly in your
+      applications, you may find glyphs clipped  or blurred.  Usually,
+      you would  like to `ceil'  the ascender, `floor'  the descender,
+      and `round' the advance.
 
     - A  new API  `FT_TrueTypeGX_Validate'  (in FT_GX_VALIDATE_H)  has
       been added to validate TrueType GX/ATT tables (feat, mort, morx,
@@ -128,6 +130,11 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10
       information about charmaps.  It  also supports a new switch `-v'
       to increase verbosity.
 
+    - Better AFM support.  This includes track kerning support.
+
+    - The  auto hinter now employs  a new algorithm, based  on akito's
+      patch, for the CJK script.
+
 ======================================================================
 
 LATEST CHANGES BETWEEN 2.1.10 and 2.1.9
diff --git a/docs/TODO b/docs/TODO
index 530ab5b..3c462ee 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -11,9 +11,7 @@ Here is a list of items that need to be addressed in FreeType 2
 
 * Add CIDCMap support to the CID driver.
 
-* Add track kerning support to the Type1 and PFR driver and the API
-  (The degree of kerning, e.g. light, normal or tight, and
-  the glyph size has to be passed as parameter).
+* Add track kerning support to the PFR driver.
 
 * Add kerning (AFM file) support to the CID driver.
 
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index 2156e7a..dae8fea 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -556,6 +556,22 @@ FT_BEGIN_HEADER
 #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compile autofit module with CJK script support.                       */
+  /*                                                                       */
+#define AF_CONFIG_OPTION_CJK
+
+
  /* */
 
   /*
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 6518bcc..cca58ad 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -22,9 +22,7 @@
    *
    */
 
-#define xxAF_MOD_CJK
-
-#ifdef AF_MOD_CJK
+#ifdef AF_CONFIG_OPTION_CJK
 
 #include "afcjk.h"
 #include "aferrors.h"
@@ -54,16 +52,11 @@
 
     /* TODO are there blues? */
 
-    if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
-    {
-      FT_Pos  threshold = 50 * metrics->units_per_em / 2048;
-
+    if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
+      face->charmap = NULL;
 
-      metrics->axis[0].edge_distance_threshold = threshold / 5;
-      metrics->axis[1].edge_distance_threshold = threshold / 5;
-    }
-    else
-      af_latin_metrics_init_widths( metrics, face, 0x7530 );
+    /* latin's version would suffice */
+    af_latin_metrics_init_widths( metrics, face, 0x7530 );
 
     FT_Set_Charmap( face, oldmap );
 
@@ -170,8 +163,7 @@
     FT_Pos        dist_threshold;
 
 
-    len_threshold = ( (AF_LatinMetrics)hints->metrics )->units_per_em;
-    len_threshold = ( len_threshold * 8 ) / 2048;
+    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
 
     dist_threshold = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
                                                   : hints->y_scale;
@@ -368,12 +360,7 @@
     edge_distance_threshold = FT_MulFix( laxis->edge_distance_threshold,
                                          scale );
     if ( edge_distance_threshold > 64 / 4 )
-    {
-      edge_distance_threshold = 64 / 4;
-
-      edge_distance_threshold = FT_DivFix( edge_distance_threshold,
-                                           scale );
-    }
+      edge_distance_threshold = FT_DivFix( 64 / 4, scale );
     else
       edge_distance_threshold = laxis->edge_distance_threshold;
 
@@ -1484,7 +1471,7 @@
     (AF_Script_ApplyHintsFunc)  af_cjk_hints_apply
   };
 
-#else /* !AF_MOD_CJK */
+#else /* !AF_CONFIG_OPTION_CJK */
 
   static const AF_Script_UniRangeRec  af_cjk_uniranges[] =
   {
@@ -1508,7 +1495,7 @@
     (AF_Script_ApplyHintsFunc)  NULL
   };
 
-#endif /* !AF_MOD_CJK */
+#endif /* !AF_CONFIG_OPTION_CJK */
 
 
 /* END */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 5cd17db..f824ccb 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -82,9 +82,7 @@
         AF_LatinAxis  axis    = &metrics->axis[dim];
         AF_AxisHints  axhints = &hints->axis[dim];
         AF_Segment    seg, limit, link;
-
-        FT_UInt       num_widths              = 0;
-        FT_Pos        edge_distance_threshold = 32000;
+        FT_UInt       num_widths = 0;
 
 
         error = af_latin_hints_compute_segments( hints,
@@ -119,22 +117,24 @@
 
         af_sort_widths( num_widths, axis->widths );
         axis->width_count = num_widths;
+      }
+
+  Exit:
+      for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
+      {
+        AF_LatinAxis  axis = &metrics->axis[dim];
+        FT_Pos        stdw;
 
-        /* we will now try to find the smallest width */
-        if ( num_widths > 0 && axis->widths[0].org < edge_distance_threshold )
-          edge_distance_threshold = axis->widths[0].org;
 
-        /* Now, compute the edge distance threshold as a fraction of the */
-        /* smallest width in the font.  Set it in `hinter->glyph' too!   */
-        if ( edge_distance_threshold == 32000 )
-          edge_distance_threshold = 50 * metrics->units_per_em / 2048;
+        stdw = ( axis->width_count > 0 )
+                 ? axis->widths[0].org
+                 : AF_LATIN_CONSTANT( metrics, 50 );
 
-        /* let's try 20% */
-        axis->edge_distance_threshold = edge_distance_threshold / 5;
+        /* let's try 20% of the smallest width */
+        axis->edge_distance_threshold = stdw / 5;
       }
     }
 
-  Exit:
     af_glyph_hints_done( hints );
   }
 
@@ -855,12 +855,15 @@
     AF_Segment    segments      = axis->segments;
     AF_Segment    segment_limit = segments + axis->num_segments;
     AF_Direction  major_dir     = axis->major_dir;
-    FT_UShort     len_threshold;
+    FT_UShort     len_threshold, len_score;
     AF_Segment    seg1, seg2;
 
 
-    len_threshold = ( (AF_LatinMetrics)hints->metrics )->units_per_em;
-    len_threshold = ( len_threshold * 8 ) / 2048;
+    len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
+    if ( len_threshold == 0 )
+      len_threshold = 1;
+
+    len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 );
 
     /* now compare each segment to the others */
     for ( seg1 = segments; seg1 < segment_limit; seg1++ )
@@ -896,7 +899,7 @@
             len = max - min;
             if ( len >= len_threshold )
             {
-              score = dist + 3000 / len;
+              score = dist + len_score / len;
 
               if ( score < seg1->score )
               {
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index f592836..aa14150 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -31,6 +31,10 @@ FT_BEGIN_HEADER
   af_latin_script_class;
 
 
+/* constants are given with units_per_em == 2048 in mind */
+#define AF_LATIN_CONSTANT( metrics, c ) \
+  ( ( ( c ) * (FT_Long)( (AF_LatinMetrics)metrics )->units_per_em ) / 2048 )
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/