diff --git a/ChangeLog b/ChangeLog index 278981c7d..7f1539de2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-03-01 Werner Lemberg + + * 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 * builds/unix/configure.ac: Fix compiler flags for diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index a2f61f55b..04c5d52fc 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 812713ea1..5aff22667 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;