diff --git a/ChangeLog b/ChangeLog index c31597db2..4a2a83f94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2016-03-20 Werner Lemberg + + [autofit] Show `near' points in tracing. + + * src/autofit/afhints.h (AF_FLAG_NEAR): New macro. + + * src/autofit/afhints.c (af_glyph_hints_dump_points): Implement it. + (af_glyph_hints_reload): Handle AF_FLAG_NEAR. + 2016-03-18 Alexei Podtelezhnikov [smooth] Minor refactoring and microoptimizations. diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 9ed058f64..dadeccb27 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -314,7 +314,7 @@ AF_DUMP(( "Table of points:\n" )); if ( hints->num_points ) - AF_DUMP(( " index hedge hseg vedge vseg flags" + AF_DUMP(( " index hedge hseg vedge vseg flags " " xorg yorg xscale yscale xfit yfit" )); else AF_DUMP(( " (none)\n" )); @@ -335,7 +335,7 @@ contour++; } - AF_DUMP(( " %5d %5s %5s %5s %5s %s " + AF_DUMP(( " %5d %5s %5s %5s %5s %s" " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", point_idx, af_print_idx( buf1, @@ -344,8 +344,11 @@ af_print_idx( buf3, af_get_edge_index( hints, segment_idx_0, 0 ) ), af_print_idx( buf4, segment_idx_0 ), - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? "weak" - : " -- ", + ( point->flags & AF_FLAG_NEAR ) + ? " near " + : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + ? " weak " + : "strong", point->fx, point->fy, @@ -813,18 +816,29 @@ AF_Point point; AF_Point point_limit = points + hints->num_points; + /* value 20 in `near_limit' is heuristic */ + FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; + FT_Int near_limit = 20 * units_per_em / 2048; + /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; char* tag = outline->tags; - AF_Point end = points + outline->contours[0]; + FT_Short endpoint = outline->contours[0]; + AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; + end->fx = (FT_Short)vec[endpoint].x; + end->fy = (FT_Short)vec[endpoint].y; + for ( point = points; point < point_limit; point++, vec++, tag++ ) { + FT_Pos out_x, out_y; + + point->in_dir = (FT_Char)AF_DIR_NONE; point->out_dir = (FT_Char)AF_DIR_NONE; @@ -845,6 +859,12 @@ point->flags = AF_FLAG_NONE; } + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + prev->flags |= AF_FLAG_NEAR; + point->prev = prev; prev->next = point; prev = point; @@ -853,8 +873,13 @@ { if ( ++contour_index < outline->n_contours ) { - end = points + outline->contours[contour_index]; + endpoint = outline->contours[contour_index]; + + end = points + endpoint; prev = end; + + end->fx = (FT_Short)vec[endpoint].x; + end->fy = (FT_Short)vec[endpoint].y; } } } @@ -880,17 +905,15 @@ * Compute directions of `in' and `out' vectors. * * Note that distances between points that are very near to each - * other are accumulated. In other words, the auto-hinter + * other are accumulated. In other words, the auto-hinter either * prepends the small vectors between near points to the first - * non-near vector. All intermediate points are tagged as - * weak; the directions are adjusted also to be equal to the - * accumulated one. + * non-near vector, or the sum of small vector lengths exceeds a + * threshold, thus `grouping' the small vectors. All intermediate + * points are tagged as weak; the directions are adjusted also to + * be equal to the accumulated one. */ - /* value 20 in `near_limit' is heuristic */ - FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; - FT_Int near_limit = 20 * units_per_em / 2048; - FT_Int near_limit2 = 2 * near_limit - 1; + FT_Int near_limit2 = 2 * near_limit - 1; AF_Point* contour; AF_Point* contour_limit = hints->contours + hints->num_contours; @@ -937,7 +960,7 @@ /* now loop over all points of the contour to get */ /* `in' and `out' vector directions */ - curr = first; + curr = first; /* * We abuse the `u' and `v' fields to store index deltas to the @@ -960,7 +983,7 @@ point = next; - next = point->next; + next = point->next; out_x += next->fx - point->fx; out_y += next->fy - point->fy; diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h index 45635652d..faa5bdbd6 100644 --- a/src/autofit/afhints.h +++ b/src/autofit/afhints.h @@ -221,6 +221,9 @@ FT_BEGIN_HEADER /* candidates for weak interpolation have this flag set */ #define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 ) + /* the distance to the next point is very small */ +#define AF_FLAG_NEAR ( 1U << 5 ) + /* edge hint flags */ #define AF_EDGE_NORMAL 0