Commit 6bd1c6d293abff22e75448da5409580e90d298c1

Werner Lemberg 2003-05-20T05:01:49

* src/pshinter/pshalgo3.c (ps3_hints_apply): Try to optimize y_scale so that the top of non-capital letters is aligned on a pixel boundary whenever possible. * src/autohint/ahhint.c (ah_hint_edges): Make sure that lowercase m's maintain their symmetry.

diff --git a/ChangeLog b/ChangeLog
index 6de6a69..ec9f8ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-05-20  David Chester  <davidchester@qmx.net>
+
+	* src/pshinter/pshalgo3.c (ps3_hints_apply): Try to optimize
+	y_scale so that the top of non-capital letters is aligned on a pixel
+	boundary whenever possible.
+
+	* src/autohint/ahhint.c (ah_hint_edges): Make sure that lowercase
+	m's maintain their symmetry.
+
 2003-05-20  Werner Lemberg  <wl@gnu.org>
 
 	* src/autohint/ahhint.c (ah_hinter_load_glyph): Oops!  David's
diff --git a/src/autohint/ahhint.c b/src/autohint/ahhint.c
index cd8a351..c17baa6 100644
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -428,6 +428,7 @@
     AH_Edge     edge_limit;
     AH_Outline  outline = hinter->glyph;
     FT_Int      dimension;
+    FT_Int      n_edges;
 
 
     edges      = outline->horz_edges;
@@ -687,6 +688,64 @@
         }
       }
 
+      /* make sure that lowercase m's maintain their symmetry */
+
+      /* In general, lowercase m's have six vertical edges if they are sans */
+      /* serif, or twelve if they are avec serif.  This implementation is   */
+      /* based on that assumption, and seems to work very well with most    */
+      /* faces.  However, if for a certain face this assumption is not      */
+      /* true, the m is just rendered like before.  In addition, any stem   */
+      /* correction will only be applied to symmetrical glyphs (even if the */
+      /* glyph is not an m), so the potential for unwanted distortion is    */
+      /* relatively low.                                                    */
+
+      n_edges = edge_limit - edges;
+      if ( !dimension && ( n_edges == 6 || n_edges == 12 ) )
+      {
+        AH_EdgeRec  *edge1, *edge2, *edge3;
+        FT_Pos       dist1, dist2, span, delta;
+
+
+        if ( n_edges == 6 )
+        {
+          edge1 = edges;
+          edge2 = edges + 2;
+          edge3 = edges + 4;
+        }
+        else
+        {
+          edge1 = edges + 1;
+          edge2 = edges + 5;
+          edge3 = edges + 9;
+        }
+
+        dist1 = edge2->opos - edge1->opos;
+        dist2 = edge3->opos - edge2->opos;
+
+        span = dist1 - dist2;
+        if ( span < 0 )
+          span = -span;
+
+        if ( span < 8 )
+        {
+          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
+          edge3->pos -= delta;
+          if ( edge3->link )
+            edge3->link->pos -= delta;
+
+          /* move the serifs along with the stem */
+          if ( n_edges == 12 )
+          {
+            ( edges + 8 )->pos -= delta;
+            ( edges + 11 )->pos -= delta;
+          }
+
+          edge3->flags |= AH_EDGE_DONE;
+          if ( edge3->link )
+            edge3->link->flags |= AH_EDGE_DONE;
+        }
+      }
+
       if ( !has_serifs )
         goto Next_Dimension;
 
diff --git a/src/pshinter/pshalgo3.c b/src/pshinter/pshalgo3.c
index 03f6ce6..cf408a0 100644
--- a/src/pshinter/pshalgo3.c
+++ b/src/pshinter/pshalgo3.c
@@ -1915,6 +1915,33 @@
     if ( error )
       goto Exit;
 
+    /* try to optimize the y_scale so that the top of non-capital letters
+     * is aligned on a pixel boundary whenever possible
+     */
+    {
+      PSH_Dimension  dim_x = &glyph->globals->dimension[0];
+      PSH_Dimension  dim_y = &glyph->globals->dimension[1];
+
+      FT_Fixed x_scale = dim_x->scale_mult;
+      FT_Fixed y_scale = dim_y->scale_mult;
+
+      FT_Fixed scaled;
+      FT_Fixed fitted;
+
+
+      scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );
+      fitted = ( scaled + 32 ) & -64;
+
+      if (scaled != fitted ) {
+        y_scale = FT_MulDiv( y_scale, fitted, scaled );
+
+        if ( fitted < scaled )
+          x_scale -= x_scale / 50;
+
+        psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 );
+      }
+    }
+
     glyph->do_horz_hints = 1;
     glyph->do_vert_hints = 1;