[autofit] Improve recognition of flat segments. Problem reported by Brad Dunzer <BDunzer@extensis.com>. * 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
diff --git a/ChangeLog b/ChangeLog
index 1ee6c86..1d48e19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2012-08-05 Werner Lemberg <wl@gnu.org>
+ [autofit] Improve recognition of flat segments.
+
+ Problem reported by Brad Dunzer <BDunzer@extensis.com>.
+
+ * 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 <wl@gnu.org>
+
[autofit] Variable renamings.
* src/autofit/aflatin.c (af_latin_metrics_init_blues): Replace
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index d7ea4a6..eb7bfed 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" ));
}