[autofit] Fix segment classification for blue zones.

The old code (essentially unchanged since the very beginning)
incorrectly handled this configuration

               x -o- x
                /   \
               /     \
              /       \
             o         o

as flat and this

                o               o
               /               /
             x|              x|
              |               |
              o---------------o

as round.  (`o' and `x' are on and off points, respectively).

This is a major change which should improve the rendering results
enormously for many TrueType fonts, especially in the range approx.
20-40ppem, fixing the appearance of many overshoots.

* src/autofit/aflatin.c (af_latin_metrics_init_blues): Look at the
first and last points of the segment, not the points right before
and after.
2.6.5
Werner Lemberg 12 years ago
parent 778a7e6a36
commit 05c1421f8d
  1. 33
      ChangeLog
  2. 29
      src/autofit/aflatin.c

@ -1,4 +1,35 @@
2013-07-18 Behdad Esfahbod <behdad@google.com>
2013-07-19 Werner Lemberg <wl@gnu.org>
[autofit] Fix segment classification for blue zones.
The old code (essentially unchanged since the very beginning)
incorrectly handled this configuration
x -o- x
/ \
/ \
/ \
o o
as flat and this
o o
/ /
x| x|
| |
o---------------o
as round. (`o' and `x' are on and off points, respectively).
This is a major change which should improve the rendering results
enormously for many TrueType fonts, especially in the range approx.
20-40ppem, fixing the appearance of many overshoots.
* src/autofit/aflatin.c (af_latin_metrics_init_blues): Look at the
first and last points of the segment, not the points right before
and after.
2013-07-19 Behdad Esfahbod <behdad@google.com>
[sfnt] `sbix' fix-ups.

@ -328,10 +328,14 @@
{
FT_Pos best_x = points[best_point].x;
FT_Int prev, next;
FT_Int best_segment_first, best_segment_last;
FT_Int best_on_point_first, best_on_point_last;
FT_Pos dist;
best_segment_first = best_point;
best_segment_last = best_point;
if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON )
{
best_on_point_first = best_point;
@ -343,8 +347,9 @@
best_on_point_last = -1;
}
/* look for the previous and next points that are not on the */
/* same Y coordinate, then threshold the `closeness'... */
/* look for the previous and next points on the contour */
/* that are not on the same Y coordinate, then threshold */
/* the `closeness'... */
prev = best_point;
next = prev;
@ -362,6 +367,8 @@
if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist )
break;
best_segment_first = prev;
if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON )
{
best_on_point_first = prev;
@ -383,6 +390,8 @@
if ( FT_ABS( points[next].x - best_x ) <= 20 * dist )
break;
best_segment_last = next;
if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON )
{
best_on_point_last = next;
@ -392,8 +401,14 @@
} while ( next != best_point );
/* now set the `round' flag depending on the segment's kind */
/* (value 8 is heuristic) */
/* now set the `round' flag depending on the segment's kind: */
/* */
/* - if the horizontal distance between the first and last */
/* `on' point is larger than upem/8 (value 8 is heuristic) */
/* we have a flat segment */
/* - if either the first or the last point of the segment is */
/* an `off' point, the segment is round, otherwise it is */
/* flat */
if ( best_on_point_first >= 0 &&
best_on_point_last >= 0 &&
(FT_UInt)( FT_ABS( points[best_on_point_last].x -
@ -402,8 +417,10 @@
round = 0;
else
round = FT_BOOL(
FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON ||
FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON );
FT_CURVE_TAG( outline.tags[best_segment_first] ) !=
FT_CURVE_TAG_ON ||
FT_CURVE_TAG( outline.tags[best_segment_last] ) !=
FT_CURVE_TAG_ON );
FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
}

Loading…
Cancel
Save