ref: 81e725f5133557bcfafa1ec55fe6cebb9c559902
parent: 91959bf24c3ecf9c46cec9916e787e5e3457fafd
author: David Turner <[email protected]>
date: Thu Nov 23 09:49:48 EST 2006
* src/autofit/afhints.c, src/autofit/afhints.h, src/autofit/aflatin.c, src/autofit/aftypes.h: Misc. auto-hinter improvements
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-23 David Turner <[email protected]>
+
+ * 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 <[email protected]>
Fix Savannah bug #15553.
@@ -9,7 +14,7 @@
2006-11-18 Werner Lemberg <[email protected]>
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'.
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -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" );
}
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -125,6 +125,7 @@
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 */
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -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 )
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -54,7 +54,7 @@
/*************************************************************************/
#define xxAF_USE_WARPER /* only define to use warp hinting */
-#define AF_DEBUG
+#define xxAF_DEBUG
#ifdef AF_DEBUG