diff --git a/ChangeLog b/ChangeLog index 6de6a69d6..ec9f8ef48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2003-05-20 David Chester + + * 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 * src/autohint/ahhint.c (ah_hinter_load_glyph): Oops! David's diff --git a/src/autohint/ahhint.c b/src/autohint/ahhint.c index cd8a35197..c17baa611 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 03f6ce67b..cf408a0dd 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;