|
|
|
@ -27,6 +27,17 @@ |
|
|
|
|
#include "afwarp.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
|
|
|
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
|
|
|
|
/* messages during execution. */ |
|
|
|
|
/* */ |
|
|
|
|
#undef FT_COMPONENT |
|
|
|
|
#define FT_COMPONENT trace_aflatin2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Error ) |
|
|
|
|
af_latin2_hints_compute_segments( AF_GlyphHints hints, |
|
|
|
|
AF_Dimension dim ); |
|
|
|
@ -187,8 +198,8 @@ |
|
|
|
|
/* 'af_latin2_blue_chars[blues]' string, then compute its top-most or */ |
|
|
|
|
/* bottom-most points (depending on `AF_IS_TOP_BLUE') */ |
|
|
|
|
|
|
|
|
|
AF_LOG(( "blue zones computation\n" )); |
|
|
|
|
AF_LOG(( "------------------------------------------------\n" )); |
|
|
|
|
FT_TRACE5(( "blue zones computation\n" )); |
|
|
|
|
FT_TRACE5(( "------------------------------------------------\n" )); |
|
|
|
|
|
|
|
|
|
for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) |
|
|
|
|
{ |
|
|
|
@ -198,7 +209,7 @@ |
|
|
|
|
FT_Pos* blue_shoot; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AF_LOG(( "blue %3d: ", bb )); |
|
|
|
|
FT_TRACE5(( "blue %3d: ", bb )); |
|
|
|
|
|
|
|
|
|
num_flats = 0; |
|
|
|
|
num_rounds = 0; |
|
|
|
@ -211,7 +222,7 @@ |
|
|
|
|
FT_Bool round; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AF_LOG(( "'%c'", *p )); |
|
|
|
|
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 ); |
|
|
|
@ -274,7 +285,7 @@ |
|
|
|
|
best_last = last; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
AF_LOG(( "%5d", best_y )); |
|
|
|
|
FT_TRACE5(( "%5d", best_y )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* now check whether the point belongs to a straight or round */ |
|
|
|
@ -322,7 +333,7 @@ |
|
|
|
|
FT_CURVE_TAG( glyph->outline.tags[start] ) != FT_CURVE_TAG_ON || |
|
|
|
|
FT_CURVE_TAG( glyph->outline.tags[ end ] ) != FT_CURVE_TAG_ON ); |
|
|
|
|
|
|
|
|
|
AF_LOG(( "%c ", round ? 'r' : 'f' )); |
|
|
|
|
FT_TRACE5(( "%c ", round ? 'r' : 'f' )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( round ) |
|
|
|
@ -331,7 +342,7 @@ |
|
|
|
|
flats[num_flats++] = best_y; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AF_LOG(( "\n" )); |
|
|
|
|
FT_TRACE5(( "\n" )); |
|
|
|
|
|
|
|
|
|
if ( num_flats == 0 && num_rounds == 0 ) |
|
|
|
|
{ |
|
|
|
@ -339,7 +350,7 @@ |
|
|
|
|
* we couldn't find a single glyph to compute this blue zone, |
|
|
|
|
* we will simply ignore it then |
|
|
|
|
*/ |
|
|
|
|
AF_LOG(( "empty\n" )); |
|
|
|
|
FT_TRACE5(( "empty\n" )); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -397,7 +408,7 @@ |
|
|
|
|
if ( bb == AF_LATIN_BLUE_SMALL_TOP ) |
|
|
|
|
blue->flags |= AF_LATIN_BLUE_ADJUSTMENT; |
|
|
|
|
|
|
|
|
|
AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); |
|
|
|
|
FT_TRACE5(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
@ -549,8 +560,10 @@ |
|
|
|
|
if ( scaled != fitted ) |
|
|
|
|
{ |
|
|
|
|
scale = FT_MulDiv( scale, fitted, scaled ); |
|
|
|
|
AF_LOG(( "== scaled x-top = %.2g fitted = %.2g, scaling = %.4g\n", |
|
|
|
|
scaled / 64.0, fitted / 64.0, ( fitted * 1.0 ) / scaled )); |
|
|
|
|
FT_TRACE5(( "== scaled x-top = %.2g" |
|
|
|
|
" fitted = %.2g, scaling = %.4g\n", |
|
|
|
|
scaled / 64.0, fitted / 64.0, |
|
|
|
|
( fitted * 1.0 ) / scaled )); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
@ -626,11 +639,11 @@ |
|
|
|
|
blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); |
|
|
|
|
blue->shoot.fit = blue->ref.fit + delta2; |
|
|
|
|
|
|
|
|
|
AF_LOG(( ">> activating blue zone %d:" |
|
|
|
|
" ref.cur=%.2g ref.fit=%.2g" |
|
|
|
|
" shoot.cur=%.2g shoot.fit=%.2g\n", |
|
|
|
|
nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0, |
|
|
|
|
blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); |
|
|
|
|
FT_TRACE5(( ">> activating blue zone %d:" |
|
|
|
|
" ref.cur=%.2g ref.fit=%.2g" |
|
|
|
|
" shoot.cur=%.2g shoot.fit=%.2g\n", |
|
|
|
|
nn, blue->ref.cur / 64.0, blue->ref.fit / 64.0, |
|
|
|
|
blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 )); |
|
|
|
|
|
|
|
|
|
blue->flags |= AF_LATIN_BLUE_ACTIVE; |
|
|
|
|
} |
|
|
|
@ -1762,10 +1775,10 @@ |
|
|
|
|
|
|
|
|
|
stem_edge->pos = base_edge->pos + fitted_width; |
|
|
|
|
|
|
|
|
|
AF_LOG(( "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 )); |
|
|
|
|
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 )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1805,8 +1818,8 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AF_LOG(( "==== hinting %s edges =====\n", |
|
|
|
|
dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); |
|
|
|
|
FT_TRACE5(( "==== hinting %s edges =====\n", |
|
|
|
|
dim == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); |
|
|
|
|
|
|
|
|
|
/* we begin by aligning all stems relative to the blue zone */ |
|
|
|
|
/* if needed -- that's only for horizontal edges */ |
|
|
|
@ -1840,10 +1853,10 @@ |
|
|
|
|
if ( !edge1 ) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
AF_LOG(( "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 )); |
|
|
|
|
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 )); |
|
|
|
|
|
|
|
|
|
edge1->pos = blue->fit; |
|
|
|
|
edge1->flags |= AF_EDGE_DONE; |
|
|
|
@ -1888,7 +1901,7 @@ |
|
|
|
|
/* this should not happen, but it's better to be safe */ |
|
|
|
|
if ( edge2->blue_edge ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges )); |
|
|
|
|
FT_TRACE5(( "ASSERTION FAILED for edge %d\n", edge2-edges )); |
|
|
|
|
|
|
|
|
|
af_latin2_align_linked_edge( hints, dim, edge2, edge ); |
|
|
|
|
edge->flags |= AF_EDGE_DONE; |
|
|
|
@ -1939,11 +1952,11 @@ |
|
|
|
|
else |
|
|
|
|
edge->pos = FT_PIX_ROUND( edge->opos ); |
|
|
|
|
|
|
|
|
|
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) " |
|
|
|
|
"snapped to (%.2f) (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, |
|
|
|
|
edge2-edges, edge2->opos / 64.0, |
|
|
|
|
edge->pos / 64.0, edge2->pos / 64.0 )); |
|
|
|
|
FT_TRACE5(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f)" |
|
|
|
|
" snapped to (%.2f) (%.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; |
|
|
|
@ -1955,7 +1968,7 @@ |
|
|
|
|
anchor_drift = ( (anchor->pos - anchor->opos) + |
|
|
|
|
(edge2->pos - edge2->opos)) >> 1; |
|
|
|
|
|
|
|
|
|
AF_LOG(( "DRIFT: %.2f\n", anchor_drift/64.0 )); |
|
|
|
|
FT_TRACE5(( "DRIFT: %.2f\n", anchor_drift/64.0 )); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -1975,13 +1988,13 @@ |
|
|
|
|
org_left = org_pos + ((org_len - cur_len) >> 1); |
|
|
|
|
org_right = org_pos + ((org_len + cur_len) >> 1); |
|
|
|
|
|
|
|
|
|
AF_LOG(( "ALIGN: left=%.2f right=%.2f ", |
|
|
|
|
org_left / 64.0, org_right / 64.0 )); |
|
|
|
|
FT_TRACE5(( "ALIGN: left=%.2f right=%.2f ", |
|
|
|
|
org_left / 64.0, org_right / 64.0 )); |
|
|
|
|
cur_center = org_center; |
|
|
|
|
|
|
|
|
|
if ( edge2->flags & AF_EDGE_DONE ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "\n" )); |
|
|
|
|
FT_TRACE5(( "\n" )); |
|
|
|
|
edge->pos = edge2->pos - cur_len; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -1996,14 +2009,14 @@ |
|
|
|
|
/* note: don't even try to fit tiny stems */ |
|
|
|
|
if ( cur_len < 32 ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "tiny stem\n" )); |
|
|
|
|
FT_TRACE5(( "tiny stem\n" )); |
|
|
|
|
goto AlignStem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* if the span is within a single pixel, don't touch it */ |
|
|
|
|
if ( FT_PIX_FLOOR(org_left) == FT_PIX_CEIL(org_right) ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "single pixel stem\n" )); |
|
|
|
|
FT_TRACE5(( "single pixel stem\n" )); |
|
|
|
|
goto AlignStem; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2026,14 +2039,14 @@ |
|
|
|
|
delta = FT_ABS(fit - org); |
|
|
|
|
displacements[count] = fit - org; |
|
|
|
|
scores[count++] = delta; |
|
|
|
|
AF_LOG(( "dispA=%.2f (%d) ", (fit - org)/64.0, delta )); |
|
|
|
|
FT_TRACE5(( "dispA=%.2f (%d) ", (fit - org) / 64.0, delta )); |
|
|
|
|
|
|
|
|
|
org = frac_right; |
|
|
|
|
fit = (org <= 32) ? 16 : 48; |
|
|
|
|
delta = FT_ABS(fit - org); |
|
|
|
|
displacements[count] = fit - org; |
|
|
|
|
scores[count++] = delta; |
|
|
|
|
AF_LOG(( "dispB=%.2f (%d) ", (fit - org)/64.0, delta )); |
|
|
|
|
FT_TRACE5(( "dispB=%.2f (%d) ", (fit - org) / 64.0, delta )); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2043,7 +2056,7 @@ |
|
|
|
|
delta = FT_ABS(fit - org); |
|
|
|
|
displacements[count] = fit - org; |
|
|
|
|
scores[count++] = delta; |
|
|
|
|
AF_LOG(( "dispC=%.2f (%d) ", (fit - org)/64.0, delta )); |
|
|
|
|
FT_TRACE5(( "dispC=%.2f (%d) ", (fit - org) / 64.0, delta )); |
|
|
|
|
|
|
|
|
|
/* snapping the right edge to the grid */ |
|
|
|
|
org = org_right; |
|
|
|
@ -2051,7 +2064,7 @@ |
|
|
|
|
delta = FT_ABS(fit - org); |
|
|
|
|
displacements[count] = fit - org; |
|
|
|
|
scores[count++] = delta; |
|
|
|
|
AF_LOG(( "dispD=%.2f (%d) ", (fit - org)/64.0, delta )); |
|
|
|
|
FT_TRACE5(( "dispD=%.2f (%d) ", (fit - org) / 64.0, delta )); |
|
|
|
|
|
|
|
|
|
/* now find the best displacement */ |
|
|
|
|
{ |
|
|
|
@ -2070,27 +2083,28 @@ |
|
|
|
|
|
|
|
|
|
cur_center = org_center + best_disp; |
|
|
|
|
} |
|
|
|
|
AF_LOG(( "\n" )); |
|
|
|
|
FT_TRACE5(( "\n" )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AlignStem: |
|
|
|
|
edge->pos = cur_center - (cur_len >> 1); |
|
|
|
|
edge2->pos = edge->pos + cur_len; |
|
|
|
|
|
|
|
|
|
AF_LOG(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)" |
|
|
|
|
" snapped to (%.2f) and (%.2f), org_len=%.2f cur_len=%.2f\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, |
|
|
|
|
edge2-edges, edge2->opos / 64.0, |
|
|
|
|
edge->pos / 64.0, edge2->pos / 64.0, |
|
|
|
|
org_len / 64.0, cur_len / 64.0 )); |
|
|
|
|
FT_TRACE5(( "STEM1: %d (opos=%.2f) to %d (opos=%.2f)" |
|
|
|
|
" snapped to (%.2f) and (%.2f)," |
|
|
|
|
" org_len=%.2f cur_len=%.2f\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, |
|
|
|
|
edge2-edges, edge2->opos / 64.0, |
|
|
|
|
edge->pos / 64.0, edge2->pos / 64.0, |
|
|
|
|
org_len / 64.0, cur_len / 64.0 )); |
|
|
|
|
|
|
|
|
|
edge->flags |= AF_EDGE_DONE; |
|
|
|
|
edge2->flags |= AF_EDGE_DONE; |
|
|
|
|
|
|
|
|
|
if ( edge > edges && edge->pos < edge[-1].pos ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "BOUND: %d (pos=%.2f) to (%.2f)\n", |
|
|
|
|
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); |
|
|
|
|
FT_TRACE5(( "BOUND: %d (pos=%.2f) to (%.2f)\n", |
|
|
|
|
edge-edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); |
|
|
|
|
edge->pos = edge[-1].pos; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -2190,16 +2204,17 @@ |
|
|
|
|
if ( delta < 64 + 16 ) |
|
|
|
|
{ |
|
|
|
|
af_latin2_align_serif_edge( hints, edge->serif, edge ); |
|
|
|
|
AF_LOG(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f) " |
|
|
|
|
"aligned to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, |
|
|
|
|
edge->serif - edges, edge->serif->opos / 64.0, |
|
|
|
|
edge->pos / 64.0 )); |
|
|
|
|
FT_TRACE5(( "SERIF: edge %d (opos=%.2f) serif to %d (opos=%.2f)" |
|
|
|
|
" aligned to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, |
|
|
|
|
edge->serif - edges, edge->serif->opos / 64.0, |
|
|
|
|
edge->pos / 64.0 )); |
|
|
|
|
} |
|
|
|
|
else if ( !anchor ) |
|
|
|
|
{ |
|
|
|
|
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); |
|
|
|
|
FT_TRACE5(( "SERIF_ANCHOR: edge %d (opos=%.2f)" |
|
|
|
|
" snapped to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); |
|
|
|
|
edge->pos = FT_PIX_ROUND( edge->opos ); |
|
|
|
|
anchor = edge; |
|
|
|
|
} |
|
|
|
@ -2226,18 +2241,19 @@ |
|
|
|
|
FT_MulDiv( edge->opos - before->opos, |
|
|
|
|
after->pos - before->pos, |
|
|
|
|
after->opos - before->opos ); |
|
|
|
|
AF_LOG(( "SERIF_LINK1: edge %d (opos=%.2f) snapped to (%.2f)" |
|
|
|
|
" from %d (opos=%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, edge->pos / 64.0, |
|
|
|
|
before - edges, before->opos / 64.0 )); |
|
|
|
|
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, |
|
|
|
|
before - edges, before->opos / 64.0 )); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
edge->pos = anchor->pos + |
|
|
|
|
( ( edge->opos - anchor->opos + 16 ) & ~31 ); |
|
|
|
|
|
|
|
|
|
AF_LOG(( "SERIF_LINK2: edge %d (opos=%.2f) snapped to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); |
|
|
|
|
FT_TRACE5(( "SERIF_LINK2: edge %d (opos=%.2f)" |
|
|
|
|
" snapped to (%.2f)\n", |
|
|
|
|
edge-edges, edge->opos / 64.0, edge->pos / 64.0 )); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|