* src/autofit/afhints.c, src/autofit/afhints.h, src/autofit/aflatin.c,

src/autofit/aftypes.h: Misc. auto-hinter improvements
This commit is contained in:
David Turner 2006-11-23 14:49:48 +00:00
parent 91959bf24c
commit 81e725f513
5 changed files with 108 additions and 20 deletions

View File

@ -1,3 +1,8 @@
2006-11-23 David Turner <david@freetype.org>
* src/autofit/afhints.c, src/autofit/afhints.h, src/autofit/aflatin.c,
src/autofit/aftypes.h: Misc. auto-hinter improvements
2006-11-22 Werner Lemberg <wl@gnu.org>
Fix Savannah bug #15553.
@ -9,7 +14,7 @@
2006-11-18 Werner Lemberg <wl@gnu.org>
Because FT_Load_Glyph expects CID values for CID-keyed fonts, the
test for a valid glyph index must be deferred to the font drivers.
test for a valid glyph index must be deferred to the font drivers.
This patch fixes Savannah bug #18301.
* src/base/ftobjs.c (FT_Load_Glyph): Don't check `glyph_index'.

View File

@ -206,19 +206,18 @@
printf ( "Table of %s segments:\n",
dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );
printf ( " [ index | pos | dir | link | serif |"
" numl | first | start ]\n" );
" height | extra ]\n" );
for ( seg = segments; seg < limit; seg++ )
{
printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
printf ( " [ %5d | %4d | %5s | %4d | %5d | %5d | %5d ]\n",
seg - segments,
(int)seg->pos,
af_dir_str( seg->dir ),
AF_INDEX_NUM( seg->link, segments ),
AF_INDEX_NUM( seg->serif, segments ),
(int)seg->num_linked,
seg->first - points,
seg->last - points );
seg->height,
seg->height - (seg->max_coord - seg->min_coord) );
}
printf( "\n" );
}

View File

@ -125,6 +125,7 @@ FT_BEGIN_HEADER
FT_Short pos; /* position of segment */
FT_Short min_coord; /* minimum coordinate of segment */
FT_Short max_coord; /* maximum coordinate of segment */
FT_Short height;
AF_Edge edge; /* the segment's parent edge */
AF_Segment edge_next; /* link to next segment in parent edge */

View File

@ -471,7 +471,7 @@
if ( blue )
{
FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
FT_Pos fitted = FT_PIX_ROUND( scaled );
FT_Pos fitted = (scaled + 40) & ~63;
if ( scaled != fitted )
@ -723,6 +723,7 @@
segment->min_coord = (FT_Short)min_pos;
segment->max_coord = (FT_Short)max_pos;
segment->height = segment->max_coord - segment->min_coord;
on_edge = 0;
segment = NULL;
@ -770,6 +771,51 @@
} /* contours */
/* now slightly increase the height of segments when 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;
for ( segment = segments; segment < segments_end; segment++ )
{
AF_Point first = segment->first;
AF_Point last = segment->last;
FT_Pos first_v = first->v;
FT_Pos last_v = last->v;
if ( first == last )
continue;
if ( first_v < last_v )
{
AF_Point p;
p = first->prev;
if ( p->v < first_v )
segment->height += (first_v - p->v) >> 1;
p = last->next;
if ( p->v > last_v )
segment->height += (p->v - last_v) >> 1;
}
else
{
AF_Point p;
p = first->prev;
if ( p->v > first_v )
segment->height += (p->v - first_v) >> 1;
p = last->next;
if ( p->v < last_v )
segment->height += (last_v - p->v) >> 1;
}
}
}
#ifdef AF_HINT_METRICS
/* we need to ensure that there are edges on the left-most and */
/* right-most points of the glyph in order to hint the metrics; */
@ -862,7 +908,7 @@
if ( len_threshold == 0 )
len_threshold = 1;
len_score = AF_LATIN_CONSTANT( hints->metrics, 3000 );
len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
/* now compare each segment to the others */
for ( seg1 = segments; seg1 < segment_limit; seg1++ )
@ -961,12 +1007,12 @@
: AF_DIR_RIGHT;
/*
* We ignore all segments that are less than 1.5 pixels in length,
* We ignore all segments that are less than 1 pixels in length,
* to avoid many problems with serif fonts. We compute the
* corresponding threshold in font units.
*/
if ( dim == AF_DIMENSION_HORZ )
segment_length_threshold = FT_DivFix( 64, hints->y_scale );
segment_length_threshold = FT_DivFix( 96, hints->y_scale );
else
segment_length_threshold = 0;
@ -1000,7 +1046,7 @@
FT_Int ee;
if ( seg->max_coord - seg->min_coord < segment_length_threshold )
if ( seg->height < segment_length_threshold )
continue;
/* look for an edge corresponding to the segment */
@ -1742,7 +1788,7 @@
/* now align the stem */
/* this should not happen, but it's better to be safe */
if ( edge2->blue_edge || edge2 < edge )
if ( edge2->blue_edge )
{
AF_LOG(( "ASSERTION FAILED for edge %d\n", edge2-edges ));
@ -1790,14 +1836,14 @@
cur_pos1 += d_off;
edge->pos = cur_pos1 - cur_len / 2;
edge2->pos = cur_pos1 + cur_len / 2;
edge2->pos = edge->pos + cur_len;
}
else
edge->pos = FT_PIX_ROUND( edge->opos );
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
AF_LOG(( "ANCHOR: edge %d (opos=%.2f) and %d (opos=%.2f) snapped to (%.2f) (%.2f)\n",
edge-edges, edge->opos / 64., edge2-edges, edge2->opos/64.,
edge->pos / 64., edge2->pos / 64. ));
anchor = edge;
edge->flags |= AF_EDGE_DONE;
@ -1859,7 +1905,6 @@
edge2-edges, edge2->opos / 64.0,
edge->pos / 64.0, edge2->pos / 64.0 ));
}
else
{
org_pos = anchor->pos + ( edge->opos - anchor->opos );
@ -1973,20 +2018,58 @@
*/
for ( edge = edges; edge < edge_limit; edge++ )
{
FT_Pos delta;
if ( edge->flags & AF_EDGE_DONE )
continue;
delta = 1000;
if ( edge->serif )
{
delta = edge->serif->opos - edge->opos;
if ( delta < 0 )
delta = -delta;
}
if ( delta < 64+16 )
{
af_latin_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., edge->serif - edges, edge->serif->opos/64., edge->pos/64.0 ));
}
else if ( !anchor )
{
AF_LOG(( "SERIF_ANCHOR: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos/64., edge->pos/64. ));
edge->pos = FT_PIX_ROUND( edge->opos );
anchor = edge;
}
else
edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos );
{
AF_Edge before, after;
for ( before = edge-1; before >= edges; before-- )
if ( before->flags & AF_EDGE_DONE )
break;
for ( after = edge+1; after < edge_limit; after++ )
if ( after->flags & AF_EDGE_DONE )
break;
if ( before >= edges && before < edge &&
after < edge_limit && after > edge )
{
edge->pos = before->pos + FT_MulDiv( edge->opos - before->opos,
after->pos - before->pos,
after->opos - before->opos );
}
else
edge->pos = anchor->pos +
FT_PIX_ROUND( edge->opos - anchor->opos );
AF_LOG(( "SERIF_LINK: edge %d (opos=%.2f) snapped to (%.2f)\n",
edge-edges, edge->opos/64., edge->pos/64. ));
}
edge->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )

View File

@ -54,7 +54,7 @@ FT_BEGIN_HEADER
/*************************************************************************/
#define xxAF_USE_WARPER /* only define to use warp hinting */
#define AF_DEBUG
#define xxAF_DEBUG
#ifdef AF_DEBUG