Commit 894c0228caa88d98a909bd7385f079eee49bdaee

Werner Lemberg 2016-07-15T10:23:11

[autofit] For edges, reject segments wider than 1px (#41334). * src/autofit/afhints.h (AF_SegmentRec): New member `delta'. * src/autofit/aflatin.c (af_latin_hints_compute_segments): Compute `delta'. (af_latin_hints_compute_edges): Reject segments with a delta larger than 0.5px.

diff --git a/ChangeLog b/ChangeLog
index b2400c2..887e611 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2016-07-15  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] For edges, reject segments wider than 1px (#41334).
+
+	* src/autofit/afhints.h (AF_SegmentRec): New member `delta'.
+
+	* src/autofit/aflatin.c (af_latin_hints_compute_segments): Compute
+	`delta'.
+	(af_latin_hints_compute_edges): Reject segments with a delta larger
+	than 0.5px.
+
 2016-07-14  Werner Lemberg  <wl@gnu.org>
 
 	* include/freetype/freetype.h (FT_IS_NAMED_INSTANCE): New macro.
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index 5142e6e..4fdf732 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -260,6 +260,7 @@ FT_BEGIN_HEADER
     FT_Byte     flags;       /* edge/segment flags for this segment */
     FT_Char     dir;         /* segment direction                   */
     FT_Short    pos;         /* position of segment                 */
+    FT_Short    delta;       /* deviation from segment position     */
     FT_Short    min_coord;   /* minimum coordinate of segment       */
     FT_Short    max_coord;   /* maximum coordinate of segment       */
     FT_Short    height;      /* the hinted segment height           */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 7ccf3f6..fd4be99 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -1536,8 +1536,9 @@
               /* points are different: we are just leaving an edge, thus */
               /* record a new segment                                    */
 
-              segment->last = point;
-              segment->pos  = (FT_Short)( ( min_pos + max_pos ) >> 1 );
+              segment->last  = point;
+              segment->pos   = (FT_Short)( ( min_pos + max_pos ) >> 1 );
+              segment->delta = (FT_Short)FT_ABS( ( max_pos - min_pos ) >> 1 );
 
               /* a segment is round if either its first or last point */
               /* is a control point, and the length of the on points  */
@@ -1966,6 +1967,7 @@
     FT_Fixed      scale;
     FT_Pos        edge_distance_threshold;
     FT_Pos        segment_length_threshold;
+    FT_Pos        segment_width_threshold;
 
 
     axis->num_edges = 0;
@@ -1987,9 +1989,15 @@
      *  corresponding threshold in font units.
      */
     if ( dim == AF_DIMENSION_HORZ )
-        segment_length_threshold = FT_DivFix( 64, hints->y_scale );
+      segment_length_threshold = FT_DivFix( 64, hints->y_scale );
     else
-        segment_length_threshold = 0;
+      segment_length_threshold = 0;
+
+    /*
+     *  Similarly, we ignore segments that have a width delta
+     *  larger than 0.5px (i.e., a width larger than 1px).
+     */
+    segment_width_threshold = FT_DivFix( 32, scale );
 
     /*********************************************************************/
     /*                                                                   */
@@ -2022,9 +2030,10 @@
       FT_Int   ee;
 
 
-      /* ignore too short segments and, in this loop, */
-      /* one-point segments without a direction       */
+      /* ignore too short segments, too wide ones, and, in this loop, */
+      /* one-point segments without a direction                       */
       if ( seg->height < segment_length_threshold ||
+           seg->delta > segment_width_threshold   ||
            seg->dir == AF_DIR_NONE                )
         continue;