Commit 709486db7f5684329bdf39156fadf6bdff6d8fdd

Werner Lemberg 2016-03-20T22:20:32

[autofit] Show `near' points in tracing. * src/autofit/afhints.h (AF_FLAG_NEAR): New macro. * src/autofit/afhints.c (af_glyph_hints_dump_points): Implement it. (af_glyph_hints_reload): Handle AF_FLAG_NEAR.

diff --git a/ChangeLog b/ChangeLog
index c31597d..4a2a83f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-03-20  Werner Lemberg  <wl@gnu.org>
+
+	[autofit] Show `near' points in tracing.
+
+	* src/autofit/afhints.h (AF_FLAG_NEAR): New macro.
+
+	* src/autofit/afhints.c (af_glyph_hints_dump_points): Implement it.
+	(af_glyph_hints_reload): Handle AF_FLAG_NEAR.
+
 2016-03-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	[smooth] Minor refactoring and microoptimizations.
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 9ed058f..dadeccb 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -314,7 +314,7 @@
     AF_DUMP(( "Table of points:\n" ));
 
     if ( hints->num_points )
-      AF_DUMP(( "  index  hedge  hseg  vedge  vseg  flags"
+      AF_DUMP(( "  index  hedge  hseg  vedge  vseg  flags "
                 "  xorg  yorg  xscale  yscale   xfit    yfit" ));
     else
       AF_DUMP(( "  (none)\n" ));
@@ -335,7 +335,7 @@
         contour++;
       }
 
-      AF_DUMP(( "  %5d  %5s %5s  %5s %5s  %s "
+      AF_DUMP(( "  %5d  %5s %5s  %5s %5s  %s"
                 " %5d %5d %7.2f %7.2f %7.2f %7.2f\n",
                 point_idx,
                 af_print_idx( buf1,
@@ -344,8 +344,11 @@
                 af_print_idx( buf3,
                               af_get_edge_index( hints, segment_idx_0, 0 ) ),
                 af_print_idx( buf4, segment_idx_0 ),
-                ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? "weak"
-                                                              : " -- ",
+                ( point->flags & AF_FLAG_NEAR )
+                  ? " near "
+                  : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
+                    ? " weak "
+                    : "strong",
 
                 point->fx,
                 point->fy,
@@ -813,18 +816,29 @@
       AF_Point  point;
       AF_Point  point_limit = points + hints->num_points;
 
+      /* value 20 in `near_limit' is heuristic */
+      FT_UInt  units_per_em = hints->metrics->scaler.face->units_per_EM;
+      FT_Int   near_limit   = 20 * units_per_em / 2048;
+
 
       /* compute coordinates & Bezier flags, next and prev */
       {
         FT_Vector*  vec           = outline->points;
         char*       tag           = outline->tags;
-        AF_Point    end           = points + outline->contours[0];
+        FT_Short    endpoint      = outline->contours[0];
+        AF_Point    end           = points + endpoint;
         AF_Point    prev          = end;
         FT_Int      contour_index = 0;
 
 
+        end->fx = (FT_Short)vec[endpoint].x;
+        end->fy = (FT_Short)vec[endpoint].y;
+
         for ( point = points; point < point_limit; point++, vec++, tag++ )
         {
+          FT_Pos  out_x, out_y;
+
+
           point->in_dir  = (FT_Char)AF_DIR_NONE;
           point->out_dir = (FT_Char)AF_DIR_NONE;
 
@@ -845,6 +859,12 @@
             point->flags = AF_FLAG_NONE;
           }
 
+          out_x = point->fx - prev->fx;
+          out_y = point->fy - prev->fy;
+
+          if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
+            prev->flags |= AF_FLAG_NEAR;
+
           point->prev = prev;
           prev->next  = point;
           prev        = point;
@@ -853,8 +873,13 @@
           {
             if ( ++contour_index < outline->n_contours )
             {
-              end  = points + outline->contours[contour_index];
+              endpoint = outline->contours[contour_index];
+
+              end  = points + endpoint;
               prev = end;
+
+              end->fx = (FT_Short)vec[endpoint].x;
+              end->fy = (FT_Short)vec[endpoint].y;
             }
           }
         }
@@ -880,17 +905,15 @@
          *  Compute directions of `in' and `out' vectors.
          *
          *  Note that distances between points that are very near to each
-         *  other are accumulated.  In other words, the auto-hinter
+         *  other are accumulated.  In other words, the auto-hinter either
          *  prepends the small vectors between near points to the first
-         *  non-near vector.  All intermediate points are tagged as
-         *  weak; the directions are adjusted also to be equal to the
-         *  accumulated one.
+         *  non-near vector, or the sum of small vector lengths exceeds a
+         *  threshold, thus `grouping' the small vectors.  All intermediate
+         *  points are tagged as weak; the directions are adjusted also to
+         *  be equal to the accumulated one.
          */
 
-        /* value 20 in `near_limit' is heuristic */
-        FT_UInt  units_per_em = hints->metrics->scaler.face->units_per_EM;
-        FT_Int   near_limit   = 20 * units_per_em / 2048;
-        FT_Int   near_limit2  = 2 * near_limit - 1;
+        FT_Int  near_limit2 = 2 * near_limit - 1;
 
         AF_Point*  contour;
         AF_Point*  contour_limit = hints->contours + hints->num_contours;
@@ -937,7 +960,7 @@
           /* now loop over all points of the contour to get */
           /* `in' and `out' vector directions               */
 
-          curr  = first;
+          curr = first;
 
           /*
            *  We abuse the `u' and `v' fields to store index deltas to the
@@ -960,7 +983,7 @@
 
 
             point = next;
-            next = point->next;
+            next  = point->next;
 
             out_x += next->fx - point->fx;
             out_y += next->fy - point->fy;
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index 4563565..faa5bdb 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -221,6 +221,9 @@ FT_BEGIN_HEADER
   /* candidates for weak interpolation have this flag set */
 #define AF_FLAG_WEAK_INTERPOLATION  ( 1U << 4 )
 
+  /* the distance to the next point is very small */
+#define AF_FLAG_NEAR  ( 1U << 5 )
+
 
   /* edge hint flags */
 #define AF_EDGE_NORMAL  0