From 601aefe4eccd84c8fbca4d43bd8fa68fe6a342d9 Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 21 Feb 2007 16:47:49 +0000 Subject: [PATCH] fix postscript hinter's handling of small and ghost stems --- ChangeLog | 5 ++++ src/pshinter/pshalgo.c | 55 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index be4712ba0..5adb4e5e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-02-21 David Turner + + * src/pshinter/pshalgo.c: fixed a bug in the hinting of small + and ghost stems in the Postscript interpreter + 2007-02-20 suzuki toshiya * src/base/ftmac.c (FT_GetFileRef_From_Mac_ATS_Name): Fix memory diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index 10ae7ef57..a01ca2afc 100644 --- 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 {