| Index: src/autofit/aflatin.c
|
| diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
|
| index 30145a2b7b27eff1c92caa825758b4a820d73784..ef0157a13ee9229319ec906fce439c9e77586dbb 100644
|
| --- a/src/autofit/aflatin.c
|
| +++ b/src/autofit/aflatin.c
|
| @@ -4,7 +4,7 @@
|
| /* */
|
| /* Auto-fitter hinting routines for latin script (body). */
|
| /* */
|
| -/* Copyright 2003-2011 by */
|
| +/* Copyright 2003-2013 by */
|
| /* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -20,6 +20,7 @@
|
| #include FT_ADVANCES_H
|
| #include FT_INTERNAL_DEBUG_H
|
|
|
| +#include "afglobal.h"
|
| #include "aflatin.h"
|
| #include "aferrors.h"
|
|
|
| @@ -53,30 +54,36 @@
|
|
|
| FT_LOCAL_DEF( void )
|
| af_latin_metrics_init_widths( AF_LatinMetrics metrics,
|
| - FT_Face face,
|
| - FT_ULong charcode )
|
| + FT_Face face )
|
| {
|
| /* scan the array of segments in each direction */
|
| AF_GlyphHintsRec hints[1];
|
|
|
|
|
| + FT_TRACE5(( "standard widths computation\n"
|
| + "===========================\n\n" ));
|
| +
|
| af_glyph_hints_init( hints, face->memory );
|
|
|
| metrics->axis[AF_DIMENSION_HORZ].width_count = 0;
|
| metrics->axis[AF_DIMENSION_VERT].width_count = 0;
|
|
|
| {
|
| - FT_Error error;
|
| - FT_UInt glyph_index;
|
| - int dim;
|
| - AF_LatinMetricsRec dummy[1];
|
| - AF_Scaler scaler = &dummy->root.scaler;
|
| + FT_Error error;
|
| + FT_UInt glyph_index;
|
| + int dim;
|
| + AF_LatinMetricsRec dummy[1];
|
| + AF_Scaler scaler = &dummy->root.scaler;
|
|
|
|
|
| - glyph_index = FT_Get_Char_Index( face, charcode );
|
| + glyph_index = FT_Get_Char_Index( face,
|
| + metrics->root.clazz->standard_char );
|
| if ( glyph_index == 0 )
|
| goto Exit;
|
|
|
| + FT_TRACE5(( "standard character: 0x%X (glyph index %d)\n",
|
| + metrics->root.clazz->standard_char, glyph_index ));
|
| +
|
| error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
| if ( error || face->glyph->outline.n_points <= 0 )
|
| goto Exit;
|
| @@ -138,7 +145,10 @@
|
| }
|
| }
|
|
|
| - af_sort_widths( num_widths, axis->widths );
|
| + /* this also replaces multiple almost identical stem widths */
|
| + /* with a single one (the value 100 is heuristic) */
|
| + af_sort_and_quantize_widths( &num_widths, axis->widths,
|
| + dummy->units_per_em / 100 );
|
| axis->width_count = num_widths;
|
| }
|
|
|
| @@ -157,9 +167,28 @@
|
| axis->edge_distance_threshold = stdw / 5;
|
| axis->standard_width = stdw;
|
| axis->extra_light = 0;
|
| +
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + {
|
| + FT_UInt i;
|
| +
|
| +
|
| + FT_TRACE5(( "%s widths:\n",
|
| + dim == AF_DIMENSION_VERT ? "horizontal"
|
| + : "vertical" ));
|
| +
|
| + FT_TRACE5(( " %d (standard)", axis->standard_width ));
|
| + for ( i = 1; i < axis->width_count; i++ )
|
| + FT_TRACE5(( " %d", axis->widths[i].org ));
|
| +
|
| + FT_TRACE5(( "\n" ));
|
| + }
|
| +#endif
|
| }
|
| }
|
|
|
| + FT_TRACE5(( "\n" ));
|
| +
|
| af_glyph_hints_done( hints );
|
| }
|
|
|
| @@ -195,15 +224,15 @@
|
| AF_LatinBlue blue;
|
| FT_Error error;
|
| AF_LatinAxis axis = &metrics->axis[AF_DIMENSION_VERT];
|
| - FT_GlyphSlot glyph = face->glyph;
|
| + FT_Outline outline;
|
|
|
|
|
| /* we compute the blues simply by loading each character from the */
|
| /* `af_latin_blue_chars[blues]' string, then finding its top-most or */
|
| /* bottom-most points (depending on `AF_IS_TOP_BLUE') */
|
|
|
| - FT_TRACE5(( "blue zones computation\n" ));
|
| - FT_TRACE5(( "------------------------------------------------\n" ));
|
| + FT_TRACE5(( "blue zones computation\n"
|
| + "======================\n\n" ));
|
|
|
| for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
|
| {
|
| @@ -213,7 +242,7 @@
|
| FT_Pos* blue_shoot;
|
|
|
|
|
| - FT_TRACE5(( "blue %3d: ", bb ));
|
| + FT_TRACE5(( "blue zone %d:\n", bb ));
|
|
|
| num_flats = 0;
|
| num_rounds = 0;
|
| @@ -222,28 +251,27 @@
|
| {
|
| FT_UInt glyph_index;
|
| FT_Pos best_y; /* same as points.y */
|
| - FT_Int best_point, best_first, best_last;
|
| + FT_Int best_point, best_contour_first, best_contour_last;
|
| FT_Vector* points;
|
| FT_Bool round = 0;
|
|
|
|
|
| - FT_TRACE5(( "'%c'", *p ));
|
| -
|
| /* load the character in the face -- skip unknown or empty ones */
|
| glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p );
|
| if ( glyph_index == 0 )
|
| continue;
|
|
|
| - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
| - if ( error || glyph->outline.n_points <= 0 )
|
| + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
|
| + outline = face->glyph->outline;
|
| + if ( error || outline.n_points <= 0 )
|
| continue;
|
|
|
| /* now compute min or max point indices and coordinates */
|
| - points = glyph->outline.points;
|
| - best_point = -1;
|
| - best_y = 0; /* make compiler happy */
|
| - best_first = 0; /* ditto */
|
| - best_last = 0; /* ditto */
|
| + points = outline.points;
|
| + best_point = -1;
|
| + best_y = 0; /* make compiler happy */
|
| + best_contour_first = 0; /* ditto */
|
| + best_contour_last = 0; /* ditto */
|
|
|
| {
|
| FT_Int nn;
|
| @@ -251,15 +279,13 @@
|
| FT_Int last = -1;
|
|
|
|
|
| - for ( nn = 0;
|
| - nn < glyph->outline.n_contours;
|
| - first = last + 1, nn++ )
|
| + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
|
| {
|
| FT_Int old_best_point = best_point;
|
| FT_Int pp;
|
|
|
|
|
| - last = glyph->outline.contours[nn];
|
| + last = outline.contours[nn];
|
|
|
| /* Avoid single-point contours since they are never rasterized. */
|
| /* In some fonts, they correspond to mark attachment points */
|
| @@ -288,11 +314,11 @@
|
|
|
| if ( best_point != old_best_point )
|
| {
|
| - best_first = first;
|
| - best_last = last;
|
| + best_contour_first = first;
|
| + best_contour_last = last;
|
| }
|
| }
|
| - FT_TRACE5(( "%5d", best_y ));
|
| + FT_TRACE5(( " %c %ld", *p, best_y ));
|
| }
|
|
|
| /* now check whether the point belongs to a straight or round */
|
| @@ -300,47 +326,86 @@
|
| /* lies, then inspect its previous and next points */
|
| if ( best_point >= 0 )
|
| {
|
| + 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;
|
|
|
| do
|
| {
|
| - if ( prev > best_first )
|
| + if ( prev > best_contour_first )
|
| prev--;
|
| else
|
| - prev = best_last;
|
| + prev = best_contour_last;
|
|
|
| - dist = points[prev].y - best_y;
|
| - if ( dist < -5 || dist > 5 )
|
| - break;
|
| + dist = FT_ABS( points[prev].y - best_y );
|
| + /* accept a small distance or a small angle (both values are */
|
| + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */
|
| + if ( dist > 5 )
|
| + 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
|
| {
|
| - if ( next < best_last )
|
| + if ( next < best_contour_last )
|
| next++;
|
| else
|
| - next = best_first;
|
| + next = best_contour_first;
|
|
|
| - dist = points[next].y - best_y;
|
| - if ( dist < -5 || dist > 5 )
|
| - break;
|
| + dist = FT_ABS( points[next].y - best_y );
|
| + if ( dist > 5 )
|
| + 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( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON ||
|
| - FT_CURVE_TAG( glyph->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(( "%c ", round ? 'r' : 'f' ));
|
| + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
|
| }
|
|
|
| if ( round )
|
| @@ -349,15 +414,13 @@
|
| flats[num_flats++] = best_y;
|
| }
|
|
|
| - FT_TRACE5(( "\n" ));
|
| -
|
| if ( num_flats == 0 && num_rounds == 0 )
|
| {
|
| /*
|
| * we couldn't find a single glyph to compute this blue zone,
|
| * we will simply ignore it then
|
| */
|
| - FT_TRACE5(( "empty\n" ));
|
| + FT_TRACE5(( " empty\n" ));
|
| continue;
|
| }
|
|
|
| @@ -400,8 +463,13 @@
|
|
|
|
|
| if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref )
|
| + {
|
| *blue_ref =
|
| *blue_shoot = ( shoot + ref ) / 2;
|
| +
|
| + FT_TRACE5(( " [overshoot smaller than reference,"
|
| + " taking mean value]\n" ));
|
| + }
|
| }
|
|
|
| blue->flags = 0;
|
| @@ -416,7 +484,9 @@
|
| if ( bb == AF_LATIN_BLUE_SMALL_TOP )
|
| blue->flags |= AF_LATIN_BLUE_ADJUSTMENT;
|
|
|
| - FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot ));
|
| + FT_TRACE5(( " -> reference = %ld\n"
|
| + " overshoot = %ld\n",
|
| + *blue_ref, *blue_shoot ));
|
| }
|
|
|
| FT_TRACE5(( "\n" ));
|
| @@ -478,41 +548,20 @@
|
| af_latin_metrics_init( AF_LatinMetrics metrics,
|
| FT_Face face )
|
| {
|
| - FT_Error error = AF_Err_Ok;
|
| FT_CharMap oldmap = face->charmap;
|
| - FT_UInt ee;
|
| -
|
| - static const FT_Encoding latin_encodings[] =
|
| - {
|
| - FT_ENCODING_UNICODE,
|
| - FT_ENCODING_APPLE_ROMAN,
|
| - FT_ENCODING_ADOBE_STANDARD,
|
| - FT_ENCODING_ADOBE_LATIN_1,
|
| -
|
| - FT_ENCODING_NONE /* end of list */
|
| - };
|
|
|
|
|
| metrics->units_per_em = face->units_per_EM;
|
|
|
| - /* do we have a latin charmap in there? */
|
| - for ( ee = 0; latin_encodings[ee] != FT_ENCODING_NONE; ee++ )
|
| - {
|
| - error = FT_Select_Charmap( face, latin_encodings[ee] );
|
| - if ( !error )
|
| - break;
|
| - }
|
| -
|
| - if ( !error )
|
| + if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
|
| {
|
| - /* For now, compute the standard width and height from the `o'. */
|
| - af_latin_metrics_init_widths( metrics, face, 'o' );
|
| + af_latin_metrics_init_widths( metrics, face );
|
| af_latin_metrics_init_blues( metrics, face );
|
| af_latin_metrics_check_digits( metrics, face );
|
| }
|
|
|
| FT_Set_Charmap( face, oldmap );
|
| - return AF_Err_Ok;
|
| + return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -569,9 +618,26 @@
|
|
|
| if ( blue )
|
| {
|
| - FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
|
| - FT_Pos fitted = ( scaled + 40 ) & ~63;
|
| + FT_Pos scaled;
|
| + FT_Pos threshold;
|
| + FT_Pos fitted;
|
| + FT_UInt limit;
|
| + FT_UInt ppem;
|
| +
|
| +
|
| + scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
|
| + ppem = metrics->root.scaler.face->size->metrics.x_ppem;
|
| + limit = metrics->root.globals->increase_x_height;
|
| + threshold = 40;
|
| +
|
| + /* if the `increase-x-height' property is active, */
|
| + /* we round up much more often */
|
| + if ( limit &&
|
| + ppem <= limit &&
|
| + ppem >= AF_PROP_INCREASE_X_HEIGHT_MIN )
|
| + threshold = 52;
|
|
|
| + fitted = ( scaled + threshold ) & ~63;
|
|
|
| if ( scaled != fitted )
|
| {
|
| @@ -677,7 +743,7 @@
|
|
|
| if ( delta2 < 32 )
|
| delta2 = 0;
|
| - else if ( delta < 48 )
|
| + else if ( delta2 < 48 )
|
| delta2 = 32;
|
| else
|
| delta2 = 64;
|
| @@ -705,6 +771,7 @@
|
| {
|
| metrics->root.scaler.render_mode = scaler->render_mode;
|
| metrics->root.scaler.face = scaler->face;
|
| + metrics->root.scaler.flags = scaler->flags;
|
|
|
| af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
|
| af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
|
| @@ -728,7 +795,7 @@
|
| {
|
| AF_AxisHints axis = &hints->axis[dim];
|
| FT_Memory memory = hints->memory;
|
| - FT_Error error = AF_Err_Ok;
|
| + FT_Error error = FT_Err_Ok;
|
| AF_Segment segment = NULL;
|
| AF_SegmentRec seg0;
|
| AF_Point* contour = hints->contours;
|
| @@ -848,7 +915,7 @@
|
|
|
| on_edge = 0;
|
| segment = NULL;
|
| - /* fallthrough */
|
| + /* fall through */
|
| }
|
| }
|
|
|
| @@ -884,8 +951,8 @@
|
| } /* contours */
|
|
|
|
|
| - /* now slightly increase the height of segments when this makes */
|
| - /* sense -- this is used to better detect and ignore serifs */
|
| + /* now slightly increase the height of segments if this makes */
|
| + /* sense -- this is used to better detect and ignore serifs */
|
| {
|
| AF_Segment segments = axis->segments;
|
| AF_Segment segments_end = segments + axis->num_segments;
|
| @@ -1040,7 +1107,7 @@
|
| AF_Dimension dim )
|
| {
|
| AF_AxisHints axis = &hints->axis[dim];
|
| - FT_Error error = AF_Err_Ok;
|
| + FT_Error error = FT_Err_Ok;
|
| FT_Memory memory = hints->memory;
|
| AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
|
|
|
| @@ -1169,17 +1236,17 @@
|
| }
|
|
|
|
|
| - /*********************************************************************/
|
| - /* */
|
| - /* Good, we will now compute each edge's properties according to */
|
| - /* the segments found on its position. Basically, these are */
|
| - /* */
|
| - /* - the edge's main direction */
|
| - /* - stem edge, serif edge or both (which defaults to stem then) */
|
| - /* - rounded edge, straight or both (which defaults to straight) */
|
| - /* - link for edge */
|
| - /* */
|
| - /*********************************************************************/
|
| + /******************************************************************/
|
| + /* */
|
| + /* Good, we now compute each edge's properties according to the */
|
| + /* segments found on its position. Basically, these are */
|
| + /* */
|
| + /* - the edge's main direction */
|
| + /* - stem edge, serif edge or both (which defaults to stem then) */
|
| + /* - rounded edge, straight or both (which defaults to straight) */
|
| + /* - link for edge */
|
| + /* */
|
| + /******************************************************************/
|
|
|
| /* first of all, set the `edge' field in each segment -- this is */
|
| /* required in order to compute edge links */
|
| @@ -1367,7 +1434,7 @@
|
| /* for each horizontal edge search the blue zone which is closest */
|
| for ( ; edge < edge_limit; edge++ )
|
| {
|
| - FT_Int bb;
|
| + FT_UInt bb;
|
| AF_Width best_blue = NULL;
|
| FT_Pos best_dist; /* initial threshold */
|
|
|
| @@ -1380,7 +1447,7 @@
|
| if ( best_dist > 64 / 2 )
|
| best_dist = 64 / 2;
|
|
|
| - for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
|
| + for ( bb = 0; bb < latin->blue_count; bb++ )
|
| {
|
| AF_LatinBlue blue = latin->blues + bb;
|
| FT_Bool is_top_blue, is_major_dir;
|
| @@ -1476,9 +1543,7 @@
|
|
|
| #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
|
| if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
|
| - {
|
| metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
|
| - }
|
| #endif
|
|
|
| scaler_flags = hints->scaler_flags;
|
| @@ -1518,7 +1583,7 @@
|
| hints->scaler_flags = scaler_flags;
|
| hints->other_flags = other_flags;
|
|
|
| - return AF_Err_Ok;
|
| + return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -1722,7 +1787,7 @@
|
| if ( delta < 0 )
|
| delta = -delta;
|
|
|
| - if (delta >= 16)
|
| + if ( delta >= 16 )
|
| {
|
| dist = org_dist;
|
| if ( dist < 48 )
|
| @@ -1762,7 +1827,7 @@
|
|
|
| stem_edge->pos = base_edge->pos + fitted_width;
|
|
|
| - FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to (%.2f),"
|
| + FT_TRACE5(( " LINK: edge %d (opos=%.2f) linked to %.2f,"
|
| " dist was %.2f, now %.2f\n",
|
| stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
|
| stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
|
| @@ -1808,9 +1873,13 @@
|
| AF_Edge anchor = NULL;
|
| FT_Int has_serifs = 0;
|
|
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + FT_UInt num_actions = 0;
|
| +#endif
|
| +
|
|
|
| - FT_TRACE5(("%s edge hinting\n", dim == AF_DIMENSION_VERT ? "horizontal"
|
| - : "vertical"));
|
| + FT_TRACE5(( "%s edge hinting\n",
|
| + dim == AF_DIMENSION_VERT ? "horizontal" : "vertical" ));
|
|
|
| /* we begin by aligning all stems relative to the blue zone */
|
| /* if needed -- that's only for horizontal edges */
|
| @@ -1844,10 +1913,20 @@
|
| if ( !edge1 )
|
| continue;
|
|
|
| - FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to (%.2f),"
|
| - " was (%.2f)\n",
|
| - edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
|
| - edge1->pos / 64.0 ));
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + if ( !anchor )
|
| + FT_TRACE5(( " BLUE_ANCHOR: edge %d (opos=%.2f) snapped to %.2f,"
|
| + " was %.2f (anchor=edge %d)\n",
|
| + edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
|
| + edge1->pos / 64.0, edge - edges ));
|
| + else
|
| + FT_TRACE5(( " BLUE: edge %d (opos=%.2f) snapped to %.2f,"
|
| + " was %.2f\n",
|
| + edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
|
| + edge1->pos / 64.0 ));
|
| +
|
| + num_actions++;
|
| +#endif
|
|
|
| edge1->pos = blue->fit;
|
| edge1->flags |= AF_EDGE_DONE;
|
| @@ -1856,6 +1935,10 @@
|
| {
|
| af_latin_align_linked_edge( hints, dim, edge1, edge2 );
|
| edge2->flags |= AF_EDGE_DONE;
|
| +
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + num_actions++;
|
| +#endif
|
| }
|
|
|
| if ( !anchor )
|
| @@ -1890,6 +1973,10 @@
|
|
|
| af_latin_align_linked_edge( hints, dim, edge2, edge );
|
| edge->flags |= AF_EDGE_DONE;
|
| +
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + num_actions++;
|
| +#endif
|
| continue;
|
| }
|
|
|
| @@ -1947,16 +2034,20 @@
|
| else
|
| edge->pos = FT_PIX_ROUND( edge->opos );
|
|
|
| + anchor = edge;
|
| + edge->flags |= AF_EDGE_DONE;
|
| +
|
| FT_TRACE5(( " ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)"
|
| - " snapped to (%.2f) (%.2f)\n",
|
| + " snapped to %.2f and %.2f\n",
|
| edge - edges, edge->opos / 64.0,
|
| edge2 - edges, edge2->opos / 64.0,
|
| edge->pos / 64.0, edge2->pos / 64.0 ));
|
| - anchor = edge;
|
| -
|
| - edge->flags |= AF_EDGE_DONE;
|
|
|
| af_latin_align_linked_edge( hints, dim, edge, edge2 );
|
| +
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + num_actions += 2;
|
| +#endif
|
| }
|
| else
|
| {
|
| @@ -1989,7 +2080,7 @@
|
|
|
| cur_pos1 = FT_PIX_ROUND( org_center );
|
|
|
| - if (cur_len <= 64 )
|
| + if ( cur_len <= 64 )
|
| {
|
| u_off = 32;
|
| d_off = 32;
|
| @@ -2016,12 +2107,13 @@
|
| edge->pos = cur_pos1 - cur_len / 2;
|
| edge2->pos = cur_pos1 + cur_len / 2;
|
|
|
| - FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
|
| - " snapped to (%.2f) and (%.2f)\n",
|
| + FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
|
| + " snapped to %.2f and %.2f\n",
|
| edge - edges, edge->opos / 64.0,
|
| edge2 - edges, edge2->opos / 64.0,
|
| edge->pos / 64.0, edge2->pos / 64.0 ));
|
| }
|
| +
|
| else
|
| {
|
| org_pos = anchor->pos + ( edge->opos - anchor->opos );
|
| @@ -2046,20 +2138,29 @@
|
| edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
|
| edge2->pos = edge->pos + cur_len;
|
|
|
| - FT_TRACE5(( " STEM: %d (opos=%.2f) to %d (opos=%.2f)"
|
| - " snapped to (%.2f) and (%.2f)\n",
|
| + FT_TRACE5(( " STEM: edge %d (opos=%.2f) linked to %d (opos=%.2f)"
|
| + " snapped to %.2f and %.2f\n",
|
| edge - edges, edge->opos / 64.0,
|
| edge2 - edges, edge2->opos / 64.0,
|
| edge->pos / 64.0, edge2->pos / 64.0 ));
|
| }
|
|
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + num_actions++;
|
| +#endif
|
| +
|
| edge->flags |= AF_EDGE_DONE;
|
| edge2->flags |= AF_EDGE_DONE;
|
|
|
| if ( edge > edges && edge->pos < edge[-1].pos )
|
| {
|
| - FT_TRACE5(( " BOUND: %d (pos=%.2f) to (%.2f)\n",
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
| edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
|
| +
|
| + num_actions++;
|
| +#endif
|
| +
|
| edge->pos = edge[-1].pos;
|
| }
|
| }
|
| @@ -2154,7 +2255,7 @@
|
| {
|
| af_latin_align_serif_edge( hints, edge->serif, edge );
|
| FT_TRACE5(( " SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)"
|
| - " aligned to (%.2f)\n",
|
| + " aligned to %.2f\n",
|
| edge - edges, edge->opos / 64.0,
|
| edge->serif - edges, edge->serif->opos / 64.0,
|
| edge->pos / 64.0 ));
|
| @@ -2164,7 +2265,7 @@
|
| edge->pos = FT_PIX_ROUND( edge->opos );
|
| anchor = edge;
|
| FT_TRACE5(( " SERIF_ANCHOR: edge %d (opos=%.2f)"
|
| - " snapped to (%.2f)\n",
|
| + " snapped to %.2f\n",
|
| edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
|
| }
|
| else
|
| @@ -2191,7 +2292,7 @@
|
| after->pos - before->pos,
|
| after->opos - before->opos );
|
|
|
| - FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)"
|
| + FT_TRACE5(( " SERIF_LINK1: edge %d (opos=%.2f) snapped to %.2f"
|
| " from %d (opos=%.2f)\n",
|
| edge - edges, edge->opos / 64.0,
|
| edge->pos / 64.0,
|
| @@ -2201,26 +2302,49 @@
|
| {
|
| edge->pos = anchor->pos +
|
| ( ( edge->opos - anchor->opos + 16 ) & ~31 );
|
| -
|
| FT_TRACE5(( " SERIF_LINK2: edge %d (opos=%.2f)"
|
| - " snapped to (%.2f)\n",
|
| + " snapped to %.2f\n",
|
| edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
|
| }
|
| }
|
|
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + num_actions++;
|
| +#endif
|
| edge->flags |= AF_EDGE_DONE;
|
|
|
| if ( edge > edges && edge->pos < edge[-1].pos )
|
| + {
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
| + edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 ));
|
| +
|
| + num_actions++;
|
| +#endif
|
| edge->pos = edge[-1].pos;
|
| + }
|
|
|
| if ( edge + 1 < edge_limit &&
|
| edge[1].flags & AF_EDGE_DONE &&
|
| edge->pos > edge[1].pos )
|
| + {
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
| + edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 ));
|
| +
|
| + num_actions++;
|
| +#endif
|
| +
|
| edge->pos = edge[1].pos;
|
| + }
|
| }
|
| }
|
|
|
| +#ifdef FT_DEBUG_LEVEL_TRACE
|
| + if ( !num_actions )
|
| + FT_TRACE5(( " (none)\n" ));
|
| FT_TRACE5(( "\n" ));
|
| +#endif
|
| }
|
|
|
|
|
| @@ -2333,10 +2457,12 @@
|
| AF_UNIRANGE_REC( 0x2460UL, 0x24FFUL ), /* Enclosed Alphanumerics */
|
| AF_UNIRANGE_REC( 0x2C60UL, 0x2C7FUL ), /* Latin Extended-C */
|
| AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */
|
| + AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */
|
| AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */
|
| AF_UNIRANGE_REC( 0xA720UL, 0xA7FFUL ), /* Latin Extended-D */
|
| AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */
|
| AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */
|
| + AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ), /* Enclosed Alphanumeric Supplement */
|
| AF_UNIRANGE_REC( 0UL, 0UL )
|
| };
|
|
|
| @@ -2344,6 +2470,7 @@
|
| AF_DEFINE_SCRIPT_CLASS( af_latin_script_class,
|
| AF_SCRIPT_LATIN,
|
| af_latin_uniranges,
|
| + 'o',
|
|
|
| sizeof ( AF_LatinMetricsRec ),
|
|
|
|
|