Commit a345c0e1d5fd368a0d2a53c2283b3ccd5262ee8f

suzuki toshiya 2011-04-21T10:58:33

[autofit] Blur CJK stems if too many to preserve their gaps

diff --git a/ChangeLog b/ChangeLog
index 6adc549..24d0e5f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2011-04-21  rainy6144  <rainy6144@gmail.com>
+
+	[autofit] Blur CJK stems if too many to preserve their gaps.
+	When there are too many stems to preserve their gaps in the
+	rasterization of CJK Ideographs at a low resolution, blur the
+	stems instead of showing clumped stems.  See
+	http://lists.gnu.org/archive/html/freetype-devel/2011-02/msg00011.html
+	http://lists.gnu.org/archive/html/freetype-devel/2011-04/msg00046.html
+	for detail.
+
+	* src/autofit/afcjk.c (af_cjk_hint_edges): Store the position of
+	the previous stem by `has_last_stem' and `last_stem_pos', and skip
+	a stem if the current and previous stem are too near to preserve
+	the gap.
+
 2011-04-18  Werner Lemberg  <wl@gnu.org>
 
 	Integrate autofitter debugging stuff.
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index af4597c..c15d343 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -1025,6 +1025,8 @@
     AF_Edge       anchor   = 0;
     FT_Pos        delta    = 0;
     FT_Int        skipped  = 0;
+    FT_Bool       has_last_stem = FALSE;
+    FT_Pos        last_stem_pos = 0;
 
 
     /* now we align all stem edges. */
@@ -1044,12 +1046,34 @@
         continue;
       }
 
+      /* Some CJK characters have so many stems that
+       * the hinter is likely to merge two adjacent ones.
+       * To solve this problem, if either edge of a stem
+       * is too close to the previous one, we avoid
+       * aligning the two edges, but rather interpolate
+       * their locations at the end of this function in
+       * order to preserve the space between the stems.
+       */
+      if ( has_last_stem                       &&
+           ( edge->pos  < last_stem_pos + 64 ||
+             edge2->pos < last_stem_pos + 64 ) )
+      {
+        skipped++;
+        continue;
+      }
+
       /* now align the stem */
 
       if ( edge2 < edge )
       {
         af_cjk_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
+        /* We rarely reaches here it seems;
+         * usually the two edges belonging
+         * to one stem are marked as DONE together
+         */
+        has_last_stem = TRUE;
+        last_stem_pos = edge->pos;
         continue;
       }
 
@@ -1142,6 +1166,8 @@
       anchor = edge;
       edge->flags  |= AF_EDGE_DONE;
       edge2->flags |= AF_EDGE_DONE;
+      has_last_stem = TRUE;
+      last_stem_pos = edge2->pos;
     }
 
     /* make sure that lowercase m's maintain their symmetry */