[autofit] Avoid excessive stem length rounding (#25392).
* src/autofit/aflatin.c (af_latin_compute_stem_width): Add argument to pass difference between hinted and unhinted position of base point; use this to adjust the stem width depending on the PPEM so that it doesn't become too large under certain circumstances. Update all callers using value 0 for this argument except... (af_latin_align_linked_edge): Pass position delta of base point to `af_latin_compute_stem_width'.
This commit is contained in:
parent
1fd2bc8c37
commit
caa48b0db1
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
2016-03-05 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[autofit] Avoid excessive stem length rounding (#25392).
|
||||
|
||||
* src/autofit/aflatin.c (af_latin_compute_stem_width): Add argument
|
||||
to pass difference between hinted and unhinted position of base
|
||||
point; use this to adjust the stem width depending on the PPEM so
|
||||
that it doesn't become too large under certain circumstances.
|
||||
Update all callers using value 0 for this argument except...
|
||||
(af_latin_align_linked_edge): Pass position delta of base point to
|
||||
`af_latin_compute_stem_width'.
|
||||
|
||||
2016-03-05 J Raynor <jxraynor@gmail.com>
|
||||
|
||||
Make FreeType compile on AIX out of the box.
|
||||
|
@ -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;
|
||||
|
||||
FT_Pos fitted_width = af_latin_compute_stem_width( hints, dim, dist,
|
||||
base_edge->flags,
|
||||
stem_edge->flags );
|
||||
|
||||
dist = stem_edge->opos - base_edge->opos;
|
||||
base_delta = base_edge->pos - base_edge->opos;
|
||||
|
||||
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 );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user