fix autofit's blue zone computations: it now ignores 1-point contours that
correspond to mark attach coordinates, and not to the real glyph outline
This commit is contained in:
parent
3b242d3619
commit
f58caa09bc
|
@ -3,6 +3,11 @@
|
||||||
* src/truetype/ttinterp.c: last fix for the MD instruction bytecode and
|
* src/truetype/ttinterp.c: last fix for the MD instruction bytecode and
|
||||||
remove the FIX_BYTECODE macros from the sources. Woot, this looks good.
|
remove the FIX_BYTECODE macros from the sources. Woot, this looks good.
|
||||||
|
|
||||||
|
* src/autofit/aflatin.c (af_latin_metrics_init_blues): fix blues computations
|
||||||
|
in order to ignore 1-point contours. These are never rasterized and in certain
|
||||||
|
fonts correspond to mark-attach points that are very far from the glyph's
|
||||||
|
real outline, ruining the computation.
|
||||||
|
|
||||||
2007-03-26 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
2007-03-26 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
||||||
|
|
||||||
* builds/unix/ftconfig.in: disable Carbon framework dependency on
|
* builds/unix/ftconfig.in: disable Carbon framework dependency on
|
||||||
|
|
|
@ -193,10 +193,8 @@
|
||||||
for ( ; p < limit && *p; p++ )
|
for ( ; p < limit && *p; p++ )
|
||||||
{
|
{
|
||||||
FT_UInt glyph_index;
|
FT_UInt glyph_index;
|
||||||
FT_Vector* extremum;
|
FT_Int best_point, best_y, best_first, best_last;
|
||||||
FT_Vector* points;
|
FT_Vector* points;
|
||||||
FT_Vector* point_limit;
|
|
||||||
FT_Vector* point;
|
|
||||||
FT_Bool round;
|
FT_Bool round;
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,85 +211,97 @@
|
||||||
|
|
||||||
/* now compute min or max point indices and coordinates */
|
/* now compute min or max point indices and coordinates */
|
||||||
points = glyph->outline.points;
|
points = glyph->outline.points;
|
||||||
point_limit = points + glyph->outline.n_points;
|
best_point = -1;
|
||||||
point = points;
|
best_y = 0; /* make compiler happy */
|
||||||
extremum = point;
|
best_first = 0; /* ditto */
|
||||||
point++;
|
best_last = 0; /* ditto */
|
||||||
|
|
||||||
if ( AF_LATIN_IS_TOP_BLUE( bb ) )
|
|
||||||
{
|
{
|
||||||
for ( ; point < point_limit; point++ )
|
FT_Int nn;
|
||||||
if ( point->y > extremum->y )
|
FT_Int first = 0;
|
||||||
extremum = point;
|
FT_Int last = -1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for ( ; point < point_limit; point++ )
|
|
||||||
if ( point->y < extremum->y )
|
|
||||||
extremum = point;
|
|
||||||
}
|
|
||||||
|
|
||||||
AF_LOG(( "%5d", (int)extremum->y ));
|
|
||||||
|
for ( nn = 0; nn < glyph->outline.n_contours; first = last+1, nn++ )
|
||||||
|
{
|
||||||
|
FT_Int old_best_point = best_point;
|
||||||
|
FT_Int pp;
|
||||||
|
|
||||||
|
last = glyph->outline.contours[nn];
|
||||||
|
|
||||||
|
/* avoid 1-point contours, they're never rasterized and
|
||||||
|
* in some fonts, they correspond to mark attachement
|
||||||
|
* points that are way outside the glyph's real outline.
|
||||||
|
*/
|
||||||
|
if (last <= first)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( AF_LATIN_IS_TOP_BLUE( bb ) )
|
||||||
|
{
|
||||||
|
for ( pp = first; pp <= last; pp++ )
|
||||||
|
if ( best_point < 0 || points[pp].y > best_y )
|
||||||
|
{
|
||||||
|
best_point = pp;
|
||||||
|
best_y = points[pp].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( pp = first; pp <= last; pp++ )
|
||||||
|
if ( best_point < 0 || points[pp].y < best_y )
|
||||||
|
{
|
||||||
|
best_point = pp;
|
||||||
|
best_y = points[pp].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_point != old_best_point)
|
||||||
|
{
|
||||||
|
best_first = first;
|
||||||
|
best_last = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AF_LOG(( "%5d", best_y ));
|
||||||
|
}
|
||||||
|
|
||||||
/* now, check whether the point belongs to a straight or round */
|
/* now, check whether the point belongs to a straight or round */
|
||||||
/* segment; we first need to find in which contour the extremum */
|
/* segment; we first need to find in which contour the extremum */
|
||||||
/* lies, then see its previous and next points */
|
/* lies, then see its previous and next points */
|
||||||
{
|
{
|
||||||
FT_Int idx = (FT_Int)( extremum - points );
|
FT_Int prev, next;
|
||||||
FT_Int n;
|
|
||||||
FT_Int first, last, prev, next, end;
|
|
||||||
FT_Pos dist;
|
FT_Pos dist;
|
||||||
|
|
||||||
|
|
||||||
last = -1;
|
|
||||||
first = 0;
|
|
||||||
|
|
||||||
for ( n = 0; n < glyph->outline.n_contours; n++ )
|
|
||||||
{
|
|
||||||
end = glyph->outline.contours[n];
|
|
||||||
if ( end >= idx )
|
|
||||||
{
|
|
||||||
last = end;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
first = end + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: should never happen! */
|
|
||||||
if ( last < 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* now look for the previous and next points that are not on the */
|
/* now look for the previous and next points that are not on the */
|
||||||
/* same Y coordinate. Threshold the `closeness'... */
|
/* same Y coordinate. Threshold the `closeness'... */
|
||||||
|
prev = best_point;
|
||||||
prev = idx;
|
|
||||||
next = prev;
|
next = prev;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ( prev > first )
|
if ( prev > best_first )
|
||||||
prev--;
|
prev--;
|
||||||
else
|
else
|
||||||
prev = last;
|
prev = best_last;
|
||||||
|
|
||||||
dist = points[prev].y - extremum->y;
|
dist = points[prev].y - best_y;
|
||||||
if ( dist < -5 || dist > 5 )
|
if ( dist < -5 || dist > 5 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} while ( prev != idx );
|
} while ( prev != best_point );
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ( next < last )
|
if ( next < best_last )
|
||||||
next++;
|
next++;
|
||||||
else
|
else
|
||||||
next = first;
|
next = best_first;
|
||||||
|
|
||||||
dist = points[next].y - extremum->y;
|
dist = points[next].y - best_y;
|
||||||
if ( dist < -5 || dist > 5 )
|
if ( dist < -5 || dist > 5 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} while ( next != idx );
|
} while ( next != best_point );
|
||||||
|
|
||||||
/* now, set the `round' flag depending on the segment's kind */
|
/* now, set the `round' flag depending on the segment's kind */
|
||||||
round = FT_BOOL(
|
round = FT_BOOL(
|
||||||
|
@ -302,9 +312,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( round )
|
if ( round )
|
||||||
rounds[num_rounds++] = extremum->y;
|
rounds[num_rounds++] = best_y;
|
||||||
else
|
else
|
||||||
flats[num_flats++] = extremum->y;
|
flats[num_flats++] = best_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
AF_LOG(( "\n" ));
|
AF_LOG(( "\n" ));
|
||||||
|
|
Loading…
Reference in New Issue