@ -2504,12 +2504,14 @@
af_latin_compute_stem_width ( AF_GlyphHints hints ,
AF_Dimension dim ,
FT_Pos width ,
FT_Pos base_delta ,
FT_UInt base_flags ,
FT_UInt stem_flags )
{
AF_LatinMetrics metrics = ( AF_LatinMetrics ) hints - > metrics ;
AF_LatinAxis axis = & metrics - > axis [ dim ] ;
FT_Pos dist = width ;
FT_Pos bdelta = 0 ;
FT_Int sign = 0 ;
FT_Int vertical = ( dim = = AF_DIMENSION_VERT ) ;
@ -2524,6 +2526,32 @@
sign = 1 ;
}
/* A stem's end position depends on two values: the start position */
/* and the stem length. The former gets usually rounded to the grid, */
/* while the latter gets rounded also if it exceeds a certain length */
/* (see below in this function). This `double rounding' can lead to */
/* a great difference to the original, unhinted position; this */
/* normally doesn't matter for large PPEM values, but for small sizes */
/* it can easily make outlines collide. For this reason, we adjust */
/* the stem length by a small amount depending on the PPEM value in */
/* case the former and latter rounding both point into the same */
/* direction. */
if ( ( ( width > 0 ) & & ( base_delta > 0 ) ) | |
( ( width < 0 ) & & ( base_delta < 0 ) ) )
{
FT_UInt ppem = metrics - > root . scaler . face - > size - > metrics . x_ppem ;
if ( ppem < 10 )
bdelta = base_delta ;
else if ( ppem < 30 )
bdelta = ( base_delta * ( FT_Pos ) ( 30 - ppem ) ) / 20 ;
if ( bdelta < 0 )
bdelta = - bdelta ;
}
if ( ( vertical & & ! AF_LATIN_HINTS_DO_VERT_SNAP ( hints ) ) | |
( ! vertical & & ! AF_LATIN_HINTS_DO_HORZ_SNAP ( hints ) ) )
{
@ -2581,7 +2609,7 @@
dist + = delta ;
}
else
dist = ( dist + 32 ) & ~ 63 ;
dist = ( dist - bdelta + 32 ) & ~ 63 ;
}
}
else
@ -2670,11 +2698,17 @@
AF_Edge base_edge ,
AF_Edge stem_edge )
{
FT_Pos dist = stem_edge - > opos - base_edge - > opos ;
FT_Pos dist , base_delta ;
FT_Pos fitted_width ;
dist = stem_edge - > opos - base_edge - > opos ;
base_delta = base_edge - > pos - base_edge - > opos ;
FT_Pos fitted_width = af_latin_compute_stem_width ( hints , dim , dist ,
base_edge - > flags ,
stem_edge - > flags ) ;
fitted_width = af_latin_compute_stem_width ( hints , dim ,
dist , base_delta ,
base_edge - > flags ,
stem_edge - > flags ) ;
stem_edge - > pos = base_edge - > pos + fitted_width ;
@ -2878,7 +2912,8 @@
org_len = edge2 - > opos - edge - > opos ;
cur_len = af_latin_compute_stem_width ( hints , dim , org_len ,
cur_len = af_latin_compute_stem_width ( hints , dim ,
org_len , 0 ,
edge - > flags ,
edge2 - > flags ) ;
@ -2947,7 +2982,8 @@
org_len = edge2 - > opos - edge - > opos ;
org_center = org_pos + ( org_len > > 1 ) ;
cur_len = af_latin_compute_stem_width ( hints , dim , org_len ,
cur_len = af_latin_compute_stem_width ( hints , dim ,
org_len , 0 ,
edge - > flags ,
edge2 - > flags ) ;
@ -3007,7 +3043,8 @@
org_len = edge2 - > opos - edge - > opos ;
org_center = org_pos + ( org_len > > 1 ) ;
cur_len = af_latin_compute_stem_width ( hints , dim , org_len ,
cur_len = af_latin_compute_stem_width ( hints , dim ,
org_len , 0 ,
edge - > flags ,
edge2 - > flags ) ;