Commit b6de8d1d3fa66340523e4f0346ae6b8ae425b205

David Turner 2007-01-23T15:51:50

* src/autofit/aflatin.c, src/autofit/aftypes.h, src/autofit/afwarp.h, src/autofit/afwarp.c: fix and enable the warper to improve "light" hinting mode. This is not necessarily a final version, but it seems to work well

diff --git a/ChangeLog b/ChangeLog
index d531e93..786207d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-23  David Turner  <david@freetype.org>
+
+	* src/autofit/aflatin.c, src/autofit/aftypes.h, src/autofit/afwarp.h,
+	src/autofit/afwarp.c: fix and enable the warper to improve "light"
+	hinting mode. This is not necessarily a final version, but it seems
+	to work well
+
 2007-01-21  Werner Lemberg  <wl@gnu.org>
 
 	* ChangeLog: Split off older entries into...
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index fbb9e15..2f35674 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -1396,7 +1396,7 @@
     /* compute flags depending on render mode, etc. */
     mode = metrics->root.scaler.render_mode;
 
-#ifdef AF_USE_WARPER
+#ifdef zzAF_USE_WARPER
     if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
     {
       metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
@@ -2114,7 +2114,12 @@
       goto Exit;
 
     /* analyze glyph outline */
+#ifdef AF_USE_WARPER
+    if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
+         AF_HINTS_DO_HORIZONTAL( hints ) )
+#else
     if ( AF_HINTS_DO_HORIZONTAL( hints ) )
+#endif
     {
       error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
       if ( error )
@@ -2133,23 +2138,24 @@
     /* grid-fit the outline */
     for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
     {
-      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
-           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
-      {
 #ifdef AF_USE_WARPER
-        if ( dim == AF_DIMENSION_HORZ &&
-             metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL )
-        {
-          AF_WarperRec  warper;
-          FT_Fixed      scale;
-          FT_Pos        delta;
+      if ( ( dim == AF_DIMENSION_HORZ && 
+             metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )
+      {
+        AF_WarperRec  warper;
+        FT_Fixed      scale;
+        FT_Pos        delta;
 
 
-          af_warper_compute( &warper, hints, dim, &scale, &delta );
-          af_glyph_hints_scale_dim( hints, dim, scale, delta );
-          continue;
-        }
+        af_warper_compute( &warper, hints, dim, &scale, &delta );
+        af_glyph_hints_scale_dim( hints, dim, scale, delta );
+        continue;
+      }
 #endif
+
+      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
+           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
+      {
         af_latin_hint_edges( hints, (AF_Dimension)dim );
         af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );
         af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index a78585d..d3985cd 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -53,7 +53,7 @@ FT_BEGIN_HEADER
   /*************************************************************************/
   /*************************************************************************/
 
-#define xxAF_USE_WARPER  /* only define to use warp hinting */
+#define AF_USE_WARPER  /* only define to use warp hinting */
 #define xxAF_DEBUG
 
 #ifdef AF_DEBUG
diff --git a/src/autofit/afwarp.c b/src/autofit/afwarp.c
index c8f86c7..9d311de 100644
--- a/src/autofit/afwarp.c
+++ b/src/autofit/afwarp.c
@@ -24,11 +24,11 @@
   static const AF_WarpScore
   af_warper_weights[64] =
   {
-    35, 20, 20, 20, 15, 12, 10,  5,  2,  1,  0,  0,  0,  0,  0,  0,
+    35, 32, 30, 20, 15, 12, 10,  5,  2,  1,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,
 
    -30,-30,-20,-20,-10,-10, -8, -5, -2, -1,  0,  0,  0,  0,  0,  0,
-     0,  0,  0,  0,  0,  0,  0,  1,  2,  5, 10, 12, 15, 20, 20, 20,
+     0,  0,  0,  0,  0,  0,  0,  1,  2,  5, 10, 12, 15, 20, 30, 32,
   };
 #else
   static const AF_WarpScore
@@ -55,10 +55,10 @@
   {
     FT_Int        idx_min, idx_max, idx0;
     FT_UInt       nn;
-    AF_WarpScore  scores[64];
+    AF_WarpScore  scores[65];
 
 
-    for ( nn = 0; nn < 64; nn++ )
+    for ( nn = 0; nn < 65; nn++ )
       scores[nn] = 0;
 
     idx0 = xx1 - warper->t1;
@@ -71,16 +71,16 @@
 
 
       if ( xx1min + w < warper->x2min )
-        xx1min = warper->x2min - ( xx2 - xx1 );
+        xx1min = warper->x2min - w;
 
       xx1max = warper->x1max;
       if ( xx1max + w > warper->x2max )
-        xx1max = warper->x2max - ( xx2 - xx1 );
+        xx1max = warper->x2max - w;
 
       idx_min = xx1min - warper->t1;
       idx_max = xx1max - warper->t1;
 
-      if ( idx_min > idx_max )
+      if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
       {
         AF_LOG(( "invalid indices:\n"
                  "  min=%d max=%d, xx1=%ld xx2=%ld,\n"
@@ -97,7 +97,6 @@
       FT_Pos  len = segments[nn].max_coord - segments[nn].min_coord;
       FT_Pos  y0  = FT_MulFix( segments[nn].pos, scale ) + delta;
       FT_Pos  y   = y0 + ( idx_min - idx0 );
-
       FT_Int  idx;
 
 
@@ -165,7 +164,7 @@
 
     warper->best_scale   = org_scale;
     warper->best_delta   = org_delta;
-    warper->best_score   = 0;
+    warper->best_score   = INT_MIN;
     warper->best_distort = 0;
 
     axis         = &hints->axis[dim];
@@ -178,7 +177,7 @@
     *a_delta = org_delta;
 
     /* get X1 and X2, minimum and maximum in original coordinates */
-    if ( axis->num_segments < 1 )
+    if ( num_segments < 1 )
       return;
 
 #if 1
@@ -238,19 +237,33 @@
     warper->wmin = warper->x2min - warper->x1max;
     warper->wmax = warper->x2max - warper->x1min;
 
-    if ( warper->wmin < warper->w0 - 32 )
-      warper->wmin = warper->w0 - 32;
+#if 1
+    {
+      int  margin = 16;
+
+      if ( warper->w0 <= 128 )
+      {
+         margin = 8;
+         if ( warper->w0 <= 96 )
+           margin = 4;
+      }
 
-    if ( warper->wmax > warper->w0 + 32 )
-      warper->wmax = warper->w0 + 32;
+      if ( warper->wmin < warper->w0 - margin )
+        warper->wmin = warper->w0 - margin;
+
+      if ( warper->wmax > warper->w0 + margin )
+        warper->wmax = warper->w0 + margin;
+    }
 
     if ( warper->wmin < warper->w0 * 3 / 4 )
       warper->wmin = warper->w0 * 3 / 4;
 
     if ( warper->wmax > warper->w0 * 5 / 4 )
       warper->wmax = warper->w0 * 5 / 4;
-
-    /* warper->wmin = warper->wmax = warper->w0; */
+#else
+    /* no scaling, just translation */
+    warper->wmin = warper->wmax = warper->w0;
+#endif
 
     for ( w = warper->wmin; w <= warper->wmax; w++ )
     {
diff --git a/src/autofit/afwarp.h b/src/autofit/afwarp.h
index 6ca1ce7..2c5b4c0 100644
--- a/src/autofit/afwarp.h
+++ b/src/autofit/afwarp.h
@@ -33,7 +33,6 @@ FT_BEGIN_HEADER
 
   typedef struct  AF_WarperRec_
   {
-    FT_Int        X1, X2;
     FT_Pos        x1, x2;
     FT_Pos        t1, t2;
     FT_Pos        x1min, x1max;