shithub: freetype+ttf2subf

Download patch

ref: 601aefe4eccd84c8fbca4d43bd8fa68fe6a342d9
parent: b68e025c1b888a1d06e3617d768d616d5469f754
author: David Turner <[email protected]>
date: Wed Feb 21 11:47:49 EST 2007

fix postscript hinter's handling of small and ghost stems

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-02-21  David Turner  <[email protected]>
+
+	* src/pshinter/pshalgo.c: fixed a bug in the hinting of small
+	and ghost stems in the Postscript interpreter
+
 2007-02-20  suzuki toshiya  <[email protected]>
 
 	* src/base/ftmac.c (FT_GetFileRef_From_Mac_ATS_Name): Fix memory
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -543,13 +543,54 @@
               /* the stem is less than one pixel; we will center it
                * around the nearest pixel center
                */
-#if 1
-              pos = FT_PIX_FLOOR( pos + ( len >> 1 ) );
-#else
-             /* this seems to be a bug! */
-              pos = pos + FT_PIX_FLOOR( len >> 1 );
-#endif
-              len = 64;
+              if (len >= 32) 
+              {
+                 /* this is a special case where we also widen the stem
+                  * and align it to the pixel grid.
+                  *
+                  *   stem_center          = pos + (len/2)
+                  *   nearest_pixel_center = FT_ROUND(stem_center-32)+32
+                  *   new_pos              = nearest_pixel_center-32
+                  *                        = FT_ROUND(stem_center-32)
+                  *                        = FT_FLOOR(stem_center-32+32)
+                  *                        = FT_FLOOR(stem_center)
+                  *   new_len              = 64
+                  */
+                  pos = FT_PIX_FLOOR( pos + (len >> 1) );
+                  len = 64;
+              }
+              else if (len > 0)
+              {
+                 /* this is a very small stem, we simply align it to the
+                  * pixel grid, trying to find the minimal displacement
+                  *
+                  * left               = pos
+                  * right              = pos + len
+                  * left_nearest_edge  = ROUND(pos)
+                  * right_nearest_edge = ROUND(right)
+                  * 
+                  * if ( ABS(left_nearest_edge - left) <= ABS(right_nearest_edge - right)
+                  *    new_pos = left
+                  * else
+                  *    new_pos = right
+                  */
+                  FT_Pos  left_nearest  = FT_PIX_ROUND(pos);
+                  FT_Pos  right_nearest = FT_PIX_ROUND(pos+len);
+                  FT_Pos  left_disp     = left_nearest - pos;
+                  FT_Pos  right_disp    = right_nearest - (pos+len);
+
+                  if (left_disp  < 0) left_disp  = -left_disp;
+                  if (right_disp < 0) right_disp = -right_disp;
+                  if (left_disp <= right_disp)
+                      pos = left_nearest;
+                  else
+                      pos = right_nearest;
+              }
+              else
+              {
+                  /* this is a ghost stem, we're going to simply round it */
+                  pos = FT_PIX_ROUND( pos );
+              }
             }
             else
             {