Commit 0399e121da07be2ba0a86d478d65214d4ebe5d60

Werner Lemberg 2004-03-02T07:01:20

* src/pshinter/pshglob.c (psh_globals_scale_widths): Don't use FT_RoundFix but FT_PIX_ROUND. (psh_blues_snap_stem): Don't use blue_shift but blue_threshold. *src/pshinter/pshalgo.c (PSH_STRONG_THRESHOLD_MAXIMUM): New macro. (psh_glyph_find_string_points): Use PSH_STRONG_THRESHOLD_MAXIMUM. (psh_glyph_find_blue_points): New function. Needed for fonts like p052003l.pfb (URW Palladio L Roman) which have flex curves at the base line within blue zones, but the flex curves aren't covered by hints. (ps_hints_apply): Use psh_glyph_find_blue_points.

diff --git a/ChangeLog b/ChangeLog
index 278981c..7f1539d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-03-01  Werner Lemberg  <wl@gnu.org>
+
+	* src/pshinter/pshglob.c (psh_globals_scale_widths): Don't use
+	FT_RoundFix but FT_PIX_ROUND.
+	(psh_blues_snap_stem): Don't use blue_shift but blue_threshold.
+
+	*src/pshinter/pshalgo.c (PSH_STRONG_THRESHOLD_MAXIMUM): New macro.
+	(psh_glyph_find_string_points): Use PSH_STRONG_THRESHOLD_MAXIMUM. 
+	(psh_glyph_find_blue_points): New function.  Needed for fonts like
+	p052003l.pfb (URW Palladio L Roman) which have flex curves at the
+	base line within blue zones, but the flex curves aren't covered by
+	hints.
+	(ps_hints_apply): Use psh_glyph_find_blue_points.
+
 2004-02-27  Garrick Meeker  <garrick@digitalanarchy.com>
 
 	* builds/unix/configure.ac: Fix compiler flags for
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index a2f61f5..04c5d52 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -511,6 +511,9 @@
             if ( !psh_hint_is_fitted( parent ) )
               psh_hint_align( parent, globals, dimension, glyph );
 
+            /* keep original relation between hints, this is, use the */
+            /* scaled distance between the centers of the hints to    */
+            /* compute the new position                               */
             par_org_center = parent->org_pos + ( parent->org_len >> 1 );
             par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
             cur_org_center = hint->org_pos   + ( hint->org_len   >> 1 );
@@ -1486,7 +1489,10 @@
 
 
   /* the accepted shift for strong points in fractional pixels */
-#define PSH_STRONG_THRESHOLD  50
+#define PSH_STRONG_THRESHOLD  32
+
+  /* the maximum shift value in font units */
+#define PSH_STRONG_THRESHOLD_MAXIMUM  30
 
 
   /* find strong points in a glyph */
@@ -1494,8 +1500,8 @@
   psh_glyph_find_strong_points( PSH_Glyph  glyph,
                                 FT_Int     dimension )
   {
-    /* a point is strong if it is located on a stem                   */
-    /* edge and has an "in" or "out" tangent to the hint's direction  */
+    /* a point is `strong' if it is located on a stem edge and       */
+    /* has an `in' or `out' tangent parallel to the hint's direction */
 
     PSH_Hint_Table  table     = &glyph->hint_tables[dimension];
     PS_Mask         mask      = table->hint_masks->masks;
@@ -1509,8 +1515,10 @@
 
 
     threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale );
+    if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM )
+      threshold = PSH_STRONG_THRESHOLD_MAXIMUM;
 
-    /* process secondary hints to "selected" points */
+    /* process secondary hints to `selected' points */
     if ( num_masks > 1 && glyph->num_points > 0 )
     {
       first = mask->end_point;
@@ -1568,6 +1576,82 @@
   }
 
 
+  /* find points in a glyph which are in a blue zone and have `in' or */
+  /* `out' tangents parallel to the horizontal axis                   */
+  static void
+  psh_glyph_find_blue_points( PSH_Blues  blues,
+                              PSH_Glyph  glyph )
+  {
+    PSH_Blue_Table  table;
+    PSH_Blue_Zone   zone;
+    FT_UInt         glyph_count = glyph->num_points;
+    FT_UInt         blue_count;
+    PSH_Point       point = glyph->points;
+
+
+    for ( ; glyph_count > 0; glyph_count--, point++ )
+    {
+      FT_Pos  y;
+
+
+      /* check tangents */
+      if ( !PSH_DIR_COMPARE( point->dir_in,  PSH_DIR_HORIZONTAL ) &&
+           !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) )
+        continue;
+
+      /* skip strong points */
+      if ( psh_point_is_strong( point ) )
+        continue;
+
+      y = point->org_u;
+
+      /* look up top zones */
+      table      = &blues->normal_top;
+      blue_count = table->count;
+      zone       = table->zones;
+
+      for ( ; blue_count > 0; blue_count--, zone++ )
+      {
+        FT_Pos  delta = y - zone->org_bottom;
+
+
+        if ( delta < -blues->blue_fuzz )
+          break;
+
+        if ( y <= zone->org_top + blues->blue_fuzz )
+          if ( blues->no_overshoots || delta <= blues->blue_threshold )
+          {
+            point->cur_u = zone->cur_bottom;
+            psh_point_set_strong( point );
+            psh_point_set_fitted( point );
+          }
+      }
+
+      /* look up bottom zones */
+      table      = &blues->normal_bottom;
+      blue_count = table->count;
+      zone       = table->zones + blue_count - 1;
+
+      for ( ; blue_count > 0; blue_count--, zone-- )
+      {
+        FT_Pos  delta = zone->org_top - y;
+
+
+        if ( delta < -blues->blue_fuzz )
+          break;
+
+        if ( y >= zone->org_bottom - blues->blue_fuzz )
+          if ( blues->no_overshoots || delta < blues->blue_threshold )
+          {
+            point->cur_u = zone->cur_top;
+            psh_point_set_strong( point );
+            psh_point_set_fitted( point );
+          }
+      }
+    }
+  }
+
+
   /* interpolate strong points with the help of hinted coordinates */
   static void
   psh_glyph_interpolate_strong_points( PSH_Glyph  glyph,
@@ -1978,6 +2062,8 @@
 
       /* find strong points, align them, then interpolate others */
       psh_glyph_find_strong_points( glyph, dimension );
+      if ( dimension == 1 )
+        psh_glyph_find_blue_points( &globals->blues, glyph );
       psh_glyph_interpolate_strong_points( glyph, dimension );
       psh_glyph_interpolate_normal_points( glyph, dimension );
       psh_glyph_interpolate_other_points( glyph, dimension );
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index 812713e..5aff226 100644
--- a/src/pshinter/pshglob.c
+++ b/src/pshinter/pshglob.c
@@ -52,7 +52,7 @@
     if ( count > 0 )
     {
       width->cur = FT_MulFix( width->org, scale );
-      width->fit = FT_RoundFix( width->cur );
+      width->fit = FT_PIX_ROUND( width->cur );
 
       width++;
       count--;
@@ -72,7 +72,7 @@
           w = stand->cur;
 
         width->cur = w;
-        width->fit = FT_RoundFix( w );
+        width->fit = FT_PIX_ROUND( w );
       }
     }
   }
@@ -574,7 +574,7 @@
 
       if ( stem_bot >= zone->org_bottom - blues->blue_fuzz )
       {
-        if ( no_shoots || delta < blues->blue_shift )
+        if ( no_shoots || delta < blues->blue_threshold )
         {
           alignment->align    |= PSH_BLUE_ALIGN_BOT;
           alignment->align_bot = zone->cur_ref;