Commit 2a9c4552f6b80838e2024486620ce220c0405398

Werner Lemberg 2012-07-03T11:54:12

[autofit] Quantize stem widths. * src/autofit/afangles.c (af_sort_widths): Rename to... (af_sort_and_quantize_widths): This. Add code to avoid stem widths which are almost identical. * src/autofit/aftypes.h, src/autofit/aflatin.c, src/autofit/afcjk.c: Updated.

diff --git a/ChangeLog b/ChangeLog
index 0e06873..dbe75d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2012-07-03  Werner Lemberg  <wl@gnu.org>
 
+	[autofit] Quantize stem widths.
+
+	* src/autofit/afangles.c (af_sort_widths): Rename to...
+	(af_sort_and_quantize_widths): This.
+	Add code to avoid stem widths which are almost identical.
+	* src/autofit/aftypes.h, src/autofit/aflatin.c, src/autofit/afcjk.c:
+	Updated.
+
+2012-07-03  Werner Lemberg  <wl@gnu.org>
+
 	[autofit] Minor speed-up.
 
 	* src/autofit/afangles (af_sort_pos, af_sort_widths): Don't swap
diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c
index 653d3f6..b44a5ba 100644
--- a/src/autofit/afangles.c
+++ b/src/autofit/afangles.c
@@ -267,14 +267,22 @@
 
 
   FT_LOCAL_DEF( void )
-  af_sort_widths( FT_UInt   count,
-                  AF_Width  table )
+  af_sort_and_quantize_widths( FT_UInt*  count,
+                               AF_Width  table,
+                               FT_Pos    threshold )
   {
     FT_UInt      i, j;
+    FT_UInt      cur_idx;
+    FT_Pos       cur_val;
+    FT_Pos       sum;
     AF_WidthRec  swap;
 
 
-    for ( i = 1; i < count; i++ )
+    if ( *count == 1 )
+      return;
+
+    /* sort */
+    for ( i = 1; i < *count; i++ )
     {
       for ( j = i; j > 0; j-- )
       {
@@ -286,6 +294,51 @@
         table[j - 1] = swap;
       }
     }
+
+    cur_idx = 0;
+    cur_val = table[cur_idx].org;
+
+    /* compute and use mean values for clusters not larger than  */
+    /* `threshold'; this is very primitive and might not yield   */
+    /* the best result, but normally, using reference character  */
+    /* `o', `*count' is 2, so the code below is fully sufficient */
+    for ( i = 1; i < *count; i++ )
+    {
+      if ( table[i].org - cur_val > threshold ||
+           i == *count - 1                    )
+      {
+        sum = 0;
+
+        /* fix loop for end of array */
+        if ( table[i].org - cur_val <= threshold &&
+             i == *count - 1                     )
+          i++;
+
+        for ( j = cur_idx; j < i; j++ )
+        {
+          sum         += table[j].org;
+          table[j].org = 0;
+        }
+        table[cur_idx].org = sum / j;
+
+        if ( i < *count - 1 )
+        {
+          cur_idx = i + 1;
+          cur_val = table[cur_idx].org;
+        }
+      }
+    }
+
+    cur_idx = 1;
+
+    /* compress array to remove zero values */
+    for ( i = 1; i < *count; i++ )
+    {
+      if ( table[i].org )
+        table[cur_idx++] = table[i];
+    }
+
+    *count = cur_idx;
   }
 
 
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 8e407c8..5b47a7f 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -150,7 +150,10 @@
           }
         }
 
-        af_sort_widths( num_widths, axis->widths );
+        /* this also replaces multiple almost identical stem widths */
+        /* with a single one (the value 100 is heuristic) */
+        af_sort_and_quantize_widths( &num_widths, axis->widths,
+                                     dummy->units_per_em / 100 );
         axis->width_count = num_widths;
       }
 
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 0fd3045..6ef0dba 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -138,7 +138,10 @@
           }
         }
 
-        af_sort_widths( num_widths, axis->widths );
+        /* this also replaces multiple almost identical stem widths */
+        /* with a single one (the value 100 is heuristic) */
+        af_sort_and_quantize_widths( &num_widths, axis->widths,
+                                     dummy->units_per_em / 100 );
         axis->width_count = num_widths;
       }
 
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 21e442c..fd2bbdc 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter types (specification only).                              */
 /*                                                                         */
-/*  Copyright 2003-2009, 2011 by                                           */
+/*  Copyright 2003-2009, 2011-2012 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -87,8 +87,9 @@ extern void*  _af_debug_hints;
                FT_Pos*  table );
 
   FT_LOCAL( void )
-  af_sort_widths( FT_UInt   count,
-                  AF_Width  widths );
+  af_sort_and_quantize_widths( FT_UInt*  count,
+                               AF_Width  widths,
+                               FT_Pos    threshold );
 
 
   /*************************************************************************/