From 5b995a8dd849a309038103fc1c96c3040a04f81b Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sun, 5 Aug 2012 11:11:44 +0200 Subject: [PATCH] [autofit] Improve recognition of flat segments. Problem reported by Brad Dunzer . * src/autofit/aflatin.c (af_latin_metrics_init_blues): We have a flat segment if the horizontal distance of best on-points is larger than a given threshold. --- ChangeLog | 10 ++++++++++ src/autofit/aflatin.c | 44 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ee6c8647..1d48e19b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-08-05 Werner Lemberg + + [autofit] Improve recognition of flat segments. + + Problem reported by Brad Dunzer . + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): We have + a flat segment if the horizontal distance of best on-points is + larger than a given threshold. + 2012-08-05 Werner Lemberg [autofit] Variable renamings. diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index d7ea4a635..eb7bfed4f 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -302,11 +302,23 @@ { FT_Pos best_x = points[best_point].x; FT_Int prev, next; + FT_Int best_on_point_first, best_on_point_last; FT_Pos dist; - /* now look for the previous and next points that are not on the */ - /* same Y coordinate. Threshold the `closeness'... */ + if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = best_point; + best_on_point_last = best_point; + } + else + { + best_on_point_first = -1; + best_on_point_last = -1; + } + + /* look for the previous and next points that are not on the */ + /* same Y coordinate, then threshold the `closeness'... */ prev = best_point; next = prev; @@ -324,6 +336,13 @@ if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) break; + if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = prev; + if ( best_on_point_last < 0 ) + best_on_point_last = prev; + } + } while ( prev != best_point ); do @@ -338,12 +357,27 @@ if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) break; + if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + { + best_on_point_last = next; + if ( best_on_point_first < 0 ) + best_on_point_first = next; + } + } while ( next != best_point ); /* now set the `round' flag depending on the segment's kind */ - round = FT_BOOL( - FT_CURVE_TAG( outline.tags[prev] ) != FT_CURVE_TAG_ON || - FT_CURVE_TAG( outline.tags[next] ) != FT_CURVE_TAG_ON ); + /* (value 8 is heuristic) */ + if ( best_on_point_first >= 0 && + best_on_point_last >= 0 && + (FT_UInt)( FT_ABS( points[best_on_point_last].x - + points[best_on_point_first].x ) ) > + metrics->units_per_em / 8 ) + 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_TRACE5(( " (%s)\n", round ? "round" : "flat" )); }