From aaf21968deb85b635cb6aa6544df233ea5981346 Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 13 Feb 2013 09:48:21 +0100 Subject: Update to following packages: openssl-1.0.1e freetype-2.4.11 --- freetype/src/autofit/aflatin.c | 354 ++++++++++++++++++++++++++++------------- 1 file changed, 240 insertions(+), 114 deletions(-) (limited to 'freetype/src/autofit/aflatin.c') diff --git a/freetype/src/autofit/aflatin.c b/freetype/src/autofit/aflatin.c index 0fd304532..8ebd49681 100644 --- a/freetype/src/autofit/aflatin.c +++ b/freetype/src/autofit/aflatin.c @@ -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,35 +548,14 @@ 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 ); } @@ -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 ) { @@ -849,7 +915,7 @@ on_edge = 0; segment = NULL; - /* fallthrough */ + /* fall through */ } } @@ -885,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; @@ -1170,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 */ @@ -1368,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 */ @@ -1381,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; @@ -1477,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; @@ -1763,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 )); @@ -1809,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 */ @@ -1845,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; @@ -1857,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 ) @@ -1891,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; } @@ -1948,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 { @@ -2017,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 ); @@ -2047,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; } } @@ -2155,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 )); @@ -2165,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 @@ -2192,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, @@ -2202,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 } @@ -2334,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 ) }; @@ -2345,6 +2470,7 @@ AF_DEFINE_SCRIPT_CLASS( af_latin_script_class, AF_SCRIPT_LATIN, af_latin_uniranges, + 'o', sizeof ( AF_LatinMetricsRec ), -- cgit v1.2.3