diff options
author | Marinus Schraal <foser@gentoo.org> | 2004-02-15 22:15:19 +0000 |
---|---|---|
committer | Marinus Schraal <foser@gentoo.org> | 2004-02-15 22:15:19 +0000 |
commit | 0f590970f9773c33ed9a3b1a043618ac8e2ae238 (patch) | |
tree | 951be968c454290e114c11ac5c9ca8c4bc9a5148 /media-libs/freetype | |
parent | Fix sg, adduser and vigr symlinks (make them relative not absolute), bug (diff) | |
download | gentoo-2-0f590970f9773c33ed9a3b1a043618ac8e2ae238.tar.gz gentoo-2-0f590970f9773c33ed9a3b1a043618ac8e2ae238.tar.bz2 gentoo-2-0f590970f9773c33ed9a3b1a043618ac8e2ae238.zip |
add cjk patch, mark 2.1.5 x86
Diffstat (limited to 'media-libs/freetype')
-rw-r--r-- | media-libs/freetype/ChangeLog | 9 | ||||
-rw-r--r-- | media-libs/freetype/files/2.1/freetype-2.1.5-autohint-cjkfonts-20031105.patch | 2320 | ||||
-rw-r--r-- | media-libs/freetype/files/digest-freetype-2.1.5-r1 | 1 | ||||
-rw-r--r-- | media-libs/freetype/freetype-2.1.5-r1.ebuild | 62 | ||||
-rw-r--r-- | media-libs/freetype/freetype-2.1.5.ebuild | 7 |
5 files changed, 2394 insertions, 5 deletions
diff --git a/media-libs/freetype/ChangeLog b/media-libs/freetype/ChangeLog index 34402c066478..786da066b47b 100644 --- a/media-libs/freetype/ChangeLog +++ b/media-libs/freetype/ChangeLog @@ -1,6 +1,11 @@ # ChangeLog for media-libs/freetype -# Copyright 2002-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/media-libs/freetype/ChangeLog,v 1.38 2003/11/29 22:00:27 brad_mssw Exp $ +# Copyright 2002-2004 Gentoo Technologies, Inc.; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/media-libs/freetype/ChangeLog,v 1.39 2004/02/15 22:15:19 foser Exp $ + +*freetype-2.1.5-r1 (15 Feb 2004) + + 15 Feb 2004; foser <foser@gentoo.org> freetype-2.1.5-r1.ebuild : + Add cjk USE ing autohint patch requested in #31347 & #36068 29 Nov 2003; Brad House <brad_mssw@gentoo.org> freetype-2.1.5.ebuild: add ~amd64 flag diff --git a/media-libs/freetype/files/2.1/freetype-2.1.5-autohint-cjkfonts-20031105.patch b/media-libs/freetype/files/2.1/freetype-2.1.5-autohint-cjkfonts-20031105.patch new file mode 100644 index 000000000000..3844e6f7a995 --- /dev/null +++ b/media-libs/freetype/files/2.1/freetype-2.1.5-autohint-cjkfonts-20031105.patch @@ -0,0 +1,2320 @@ +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/ahglobal.c freetype-2.1.5/src/autohint/ahglobal.c +--- freetype-2.1.5-orig/src/autohint/ahglobal.c Wed May 28 14:52:05 2003 ++++ freetype-2.1.5/src/autohint/ahglobal.c Wed Sep 24 13:07:51 2003 +@@ -30,7 +30,7 @@ + /* cf. AH_BLUE_XXX constants in ahtypes.h */ + + static +- const char* blue_chars[AH_BLUE_MAX] = ++ const char* blue_chars_latin[AH_BLUE_MAX] = + { + "THEZOCQS", + "HEZLOCUS", +@@ -43,6 +43,35 @@ + }; + + ++ typedef struct AH_BlueTable_ ++ { ++ FT_ULong offset_blue_chars; ++ const char** blue_chars; ++ FT_ULong char_for_widths; ++ ++ } AH_BlueTable; ++ ++ ++ static const AH_BlueTable blue_table[AH_CHAR_TYPE_COUNT] = ++ { ++ { 0, blue_chars_latin, (FT_ULong)'o' }, ++ { 0xFEE0L, blue_chars_latin, 0xFF4FL }, ++ { 0, 0, 0 }, ++ { 0, 0, 0 } ++ }; ++ ++ ++#ifdef AH_DEBUG ++ static const char* blue_names[AH_CHAR_TYPE_COUNT] = ++ { ++ "general latinate chars", ++ "CJK fullwidth latin chars", ++ 0, ++ 0 ++ }; ++#endif ++ ++ + /* simple insertion sort */ + static void + sort_values( FT_Int count, +@@ -71,7 +100,7 @@ + ah_hinter_compute_blues( AH_Hinter hinter ) + { + AH_Blue blue; +- AH_Globals globals = &hinter->globals->design; ++ AH_Globals globals = hinter->globals->designs; + FT_Pos flats [MAX_TEST_CHARACTERS]; + FT_Pos rounds[MAX_TEST_CHARACTERS]; + FT_Int num_flats; +@@ -81,6 +110,9 @@ + FT_GlyphSlot glyph; + FT_Error error; + FT_CharMap charmap; ++ FT_ULong offset; ++ FT_Byte type; ++ const char** blue_chars; + + + face = hinter->face; +@@ -97,8 +129,19 @@ + /* we compute the blues simply by loading each character from the */ + /* 'blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AH_IS_TOP_BLUE') */ ++ type = AH_CHAR_TYPE_LATINATE; + +- AH_LOG(( "blue zones computation\n" )); ++ Compute_Blues: ++ globals->has_blues = FALSE; ++ globals->baseline = 0; ++ ++ offset = blue_table[type].offset_blue_chars; ++ blue_chars = blue_table[type].blue_chars; ++ ++ if ( !blue_chars ) ++ goto Next_Type; ++ ++ AH_LOG(( "blue zones computation for %s\n", blue_names[type] )); + AH_LOG(( "------------------------------------------------\n" )); + + for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) +@@ -131,7 +174,7 @@ + AH_LOG(( "`%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ +- glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); ++ glyph_index = FT_Get_Char_Index( face, offset + (FT_ULong)*p ); + if ( glyph_index == 0 ) + continue; + +@@ -221,10 +264,30 @@ + + } while ( next != idx ); + +- /* 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 ); ++ /* now, set the `round' flag depending on whether there exists */ ++ /* a extremum line segment within the current zone. */ ++ round = TRUE; ++ ++ { ++ FT_Int n = 0, p = prev; ++ FT_Bool is_top = AH_IS_TOP_BLUE( blue ); ++ ++ ++ while ( ( p = ( p >= last )? first : p + 1 ) != next ) ++ { ++ if ( FT_CURVE_TAG( glyph->outline.tags[p] ) == FT_CURVE_TAG_ON ) ++ { ++ if ( ( is_top && points[p].y < extremum->y ) || ++ ( !is_top && points[p].y > extremum->y ) ) ++ break; ++ ++ n++; ++ } ++ } ++ ++ if ( n >= 2 && p == next ) ++ round = FALSE; ++ } + + AH_LOG(( "%c ", round ? 'r' : 'f' )); + } +@@ -281,6 +344,30 @@ + } + + AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); ++ ++ if ( num_flats > 0 || num_rounds > 0 ) ++ globals->has_blues = TRUE; ++ } ++ ++ globals->baseline = globals->blue_refs[AH_BLUE_SMALL_BOTTOM]; ++ ++ if ( globals->baseline > -10000 ) ++ { ++ for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) ++ { ++ if ( globals->blue_refs[blue] > -10000 ) ++ { ++ globals->blue_refs[blue] -= globals->baseline; ++ globals->blue_shoots[blue] -= globals->baseline; ++ } ++ } ++ } ++ ++ Next_Type: ++ if ( ++type < AH_CHAR_TYPE_COUNT ) ++ { ++ globals++; ++ goto Compute_Blues; + } + + /* reset original face charmap */ +@@ -299,13 +386,23 @@ + AH_Outline outline = hinter->glyph; + AH_Segment segments; + AH_Segment limit; +- AH_Globals globals = &hinter->globals->design; ++ AH_Globals globals = hinter->globals->designs; + FT_Pos* widths; + FT_Int dimension; + FT_Int* p_num_widths; + FT_Error error = 0; + FT_Pos edge_distance_threshold = 32000; ++ FT_Byte type; ++ FT_ULong char_for_widths; ++ ++ ++ type = AH_CHAR_TYPE_LATINATE; + ++ Compute_Widths: ++ char_for_widths = blue_table[type].char_for_widths; ++ ++ if ( !char_for_widths ) ++ goto Next_Type; + + globals->num_widths = 0; + globals->num_heights = 0; +@@ -318,18 +415,18 @@ + FT_UInt glyph_index; + + +- glyph_index = FT_Get_Char_Index( hinter->face, 'o' ); ++ glyph_index = FT_Get_Char_Index( hinter->face, char_for_widths ); + if ( glyph_index == 0 ) +- return 0; ++ goto Next_Type; + + error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error ) +- goto Exit; ++ goto Next_Type; + + error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, + hinter->face ); + if ( error ) +- goto Exit; ++ goto Next_Type; + + ah_outline_compute_segments( hinter->glyph ); + ah_outline_link_segments( hinter->glyph ); +@@ -378,6 +475,13 @@ + p_num_widths = &globals->num_widths; + } + ++ Next_Type: ++ if ( type++ < AH_CHAR_TYPE_COUNT ) ++ { ++ globals++; ++ goto Compute_Widths; ++ } ++ + /* Now, compute the edge distance threshold as a fraction of the */ + /* smallest width in the font. Set it in `hinter->glyph' too! */ + if ( edge_distance_threshold == 32000 ) +@@ -386,8 +490,7 @@ + /* let's try 20% */ + hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5; + +- Exit: +- return error; ++ return 0; + } + + +@@ -396,6 +499,192 @@ + { + return ah_hinter_compute_widths( hinter ) || + ah_hinter_compute_blues ( hinter ); ++ } ++ ++ ++ static const AH_CharType ++ ah_types_for_unicode[] = ++ { ++ /* Latin, Greek, Cyrillic */ ++ { AH_CHAR_TYPE_LATINATE, 0x21L, 0x52FL }, ++ ++ /* Hebrew */ ++ { AH_CHAR_TYPE_LATINATE, 0x5D0L, 0x600L }, ++ ++ /* Latin, Greek */ ++ { AH_CHAR_TYPE_LATINATE, 0x1E00L, 0x2000L }, ++ ++ /* CJK fullwidth Latin */ ++ { AH_CHAR_TYPE_LATIN_FULLWIDTH, 0xFF00L, 0xFF60L } ++ }; ++ ++ ++ static const AH_CharTypeTable ++ ah_types_table_unicode = ++ { ++ sizeof( ah_types_for_unicode ) / sizeof( AH_CharType ), ++ (AH_CharType *)ah_types_for_unicode ++ }; ++ ++ ++ FT_LOCAL_DEF( void ) ++ ah_hinter_compute_char_table( AH_Hinter hinter ) ++ { ++ FT_Memory memory = hinter->memory; ++ FT_Face face = hinter->face; ++ AH_CharTypeTable* table = hinter->globals->table; ++ FT_ULong num_glyphs = face->num_glyphs; ++ FT_Byte* types; ++ FT_Error error; ++ FT_CharMap charmap; ++ ++ ++ if ( table ) ++ return; ++ ++ if ( num_glyphs <= 0 ) ++ return; ++ ++ if ( FT_NEW_ARRAY( types, num_glyphs ) ) ++ return; ++ ++ FT_MEM_SET( types, AH_CHAR_TYPE_OTHER, num_glyphs ); ++ ++ charmap = face->charmap; ++ if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) ++ goto Exit; ++ ++ ++ { ++ FT_Bool empty = TRUE; ++ FT_ULong i; ++ ++ ++ for ( i = 0; i < ah_types_table_unicode.size; i++ ) ++ { ++ FT_UInt glyph_index; ++ FT_ULong start = ah_types_table_unicode.types[i].start; ++ FT_ULong last = ah_types_table_unicode.types[i].last; ++ FT_Byte type = ah_types_table_unicode.types[i].type; ++ FT_ULong ucs = FT_Get_Next_Char( face, start - 1, &glyph_index ); ++ ++ ++ while ( ucs && ucs <= last ) ++ { ++ if ( glyph_index < num_glyphs ) ++ { ++ empty = FALSE; ++ types[glyph_index] = type; ++ } ++ ++ ucs = FT_Get_Next_Char( face, ucs, &glyph_index ); ++ } ++ } ++ ++ if ( empty ) ++ goto Exit; ++ } ++ ++ ++ { ++ FT_Byte* cur = types; ++ FT_Byte* last = types + num_glyphs - 1; ++ FT_Byte type = AH_CHAR_TYPE_OTHER; ++ FT_ULong num = 0; ++ FT_ULong alloc_size; ++ ++ ++ while ( ++cur <= last ) ++ { ++ if ( *cur != type ) ++ { ++ type = *cur; ++ ++ if ( type < AH_CHAR_TYPE_OTHER ) ++ num++; ++ } ++ } ++ ++ alloc_size = sizeof( AH_CharTypeTable ) + num * sizeof( AH_CharType ); ++ if ( FT_ALLOC( table, alloc_size ) ) ++ goto Exit; ++ ++ table->size = num; ++ table->types = (AH_CharType *)( table + 1 ); ++ } ++ ++ ++ { ++ FT_Byte* cur = types + 1; ++ FT_Byte* last = types + face->num_glyphs - 1; ++ FT_Byte type = AH_CHAR_TYPE_OTHER; ++ FT_ULong num = 0; ++ FT_ULong i; ++ ++ ++ for ( i = 1; cur <= last; i++, cur++ ) ++ { ++ if ( *cur != type ) ++ { ++ if ( type < AH_CHAR_TYPE_OTHER ) ++ table->types[num - 1].last = i - 1; ++ ++ type = *cur; ++ if ( type < AH_CHAR_TYPE_OTHER ) ++ { ++ table->types[num].type = type; ++ table->types[num++].start = i; ++ } ++ } ++ } ++ ++ if ( type < AH_CHAR_TYPE_OTHER ) ++ table->types[num - 1].last = i - 1; ++ } ++ ++ hinter->globals->table = table; ++ ++ Exit: ++ FT_Set_Charmap( face, charmap ); ++ FT_FREE( types ); ++ } ++ ++ ++ FT_LOCAL_DEF( FT_Byte ) ++ ah_hinter_get_char_type( AH_Hinter hinter, ++ FT_ULong glyph_index ) ++ { ++ AH_CharTypeTable* table = hinter->globals->table; ++ ++ ++ if ( table && table->size > 0 && glyph_index ) ++ { ++ AH_CharType* cur; ++ AH_CharType* types = table->types; ++ FT_ULong min = 0; ++ FT_ULong max = table->size - 1; ++ FT_ULong mid; ++ ++ ++ if ( glyph_index < types[min].start || ++ glyph_index > types[max].last ) ++ return AH_CHAR_TYPE_OTHER; ++ ++ while ( min <= max ) ++ { ++ mid = ( min + max ) / 2; ++ cur = types + mid; ++ ++ if ( glyph_index < cur->start ) ++ max = mid - 1; ++ else if ( glyph_index > cur->last ) ++ min = mid + 1; ++ else ++ return cur->type; ++ } ++ } ++ ++ return AH_CHAR_TYPE_OTHER; + } + + +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/ahglobal.h freetype-2.1.5/src/autohint/ahglobal.h +--- freetype-2.1.5-orig/src/autohint/ahglobal.h Tue Apr 22 16:49:24 2003 ++++ freetype-2.1.5/src/autohint/ahglobal.h Sat Sep 20 05:10:18 2003 +@@ -51,6 +51,14 @@ + ah_hinter_compute_globals( AH_Hinter hinter ); + + ++ FT_LOCAL( void ) ++ ah_hinter_compute_char_table( AH_Hinter hinter ); ++ ++ ++ FT_LOCAL( FT_Byte ) ++ ah_hinter_get_char_type( AH_Hinter hinter, ++ FT_ULong glyph_index ); ++ + FT_END_HEADER + + #endif /* __AHGLOBAL_H__ */ +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/ahglyph.c freetype-2.1.5/src/autohint/ahglyph.c +--- freetype-2.1.5-orig/src/autohint/ahglyph.c Wed May 28 14:52:05 2003 ++++ freetype-2.1.5/src/autohint/ahglyph.c Wed Sep 24 12:26:43 2003 +@@ -22,7 +22,6 @@ + + #include <ft2build.h> + #include "ahglyph.h" +-#include "ahangles.h" + #include "ahglobal.h" + #include "aherrors.h" + +@@ -52,11 +51,11 @@ + printf ( "Table of %s edges:\n", + !dimension ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link |" +- " serif | blue | opos | pos ]\n" ); ++ " serif | blue | opos | pos | diff ]\n" ); + + for ( edge = edges; edge < edge_limit; edge++ ) + { +- printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", ++ printf ( " [ %5d | %4d | %5s | %4d | %6d | %c | %5.2f | %5.2f | %5.2f ]\n", + edge - edges, + (int)edge->fpos, + edge->dir == AH_DIR_UP +@@ -72,7 +71,8 @@ + edge->serif ? ( edge->serif - edges ) : -1, + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, +- edge->pos / 64.0 ); ++ edge->pos / 64.0, ++ ( edge->pos - edge->opos ) / 64.0 ); + } + + edges = outline->vert_edges; +@@ -370,6 +370,12 @@ + char* tag = gloader->current.outline.tags; + + ++#ifdef AH_DEBUG ++ ah_dump_segments( outline ); ++ ah_dump_edges( outline ); ++ printf( "\n" ); ++ #endif ++ + /* we assume that the glyph loader has already been checked for storage */ + for ( ; point < point_limit; point++, vec++, tag++ ) + { +@@ -594,6 +600,7 @@ + + point->out_dir = ah_compute_direction( ovec.x, ovec.y ); + ++#if 0 + #ifndef AH_OPTION_NO_WEAK_INTERPOLATION + if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) ) + { +@@ -624,6 +631,7 @@ + else if ( point->in_dir == -point->out_dir ) + goto Is_Weak_Point; + #endif ++#endif + } + } + } +@@ -709,6 +717,7 @@ + } + + ++#if 0 + /* compute all inflex points in a given glyph */ + static void + ah_outline_compute_inflections( AH_Outline outline ) +@@ -822,6 +831,54 @@ + ; + } + } ++#endif ++ ++ ++ /* compute all strong points in a given glyph */ ++ static void ++ ah_outline_compute_strongs( AH_Outline outline ) ++ { ++ AH_Point* contour = outline->contours; ++ AH_Point* contour_limit = contour + outline->num_contours; ++ ++ ++ /* load original coordinates in (u,v) */ ++ ah_setup_uv( outline, AH_UV_FXY ); ++ ++ for ( ; contour < contour_limit; contour++ ) ++ { ++ FT_Pos dx1, dx2, dy1, dy2; ++ AH_Point point = contour[0]; ++ AH_Point first = point; ++ AH_Point before; ++ AH_Point after; ++ ++ ++ after = point->next; ++ before = point->prev; ++ dx1 = point->u - before->u; ++ dy1 = point->v - before->v; ++ ++ do ++ { ++ dx2 = after->u - point->u; ++ dy2 = after->v - point->v; ++ ++ if ( dx1 == 0 || dx2 == 0 || ( dx1 ^ dx2 ) < 0 ) ++ point->flags |= AH_FLAG_STRONG_X; ++ ++ if ( dy1 == 0 || dy2 == 0 || ( dy1 ^ dy2 ) < 0 ) ++ point->flags |= AH_FLAG_STRONG_Y; ++ ++ before = point; ++ point = after; ++ after = after->next; ++ dx1 = dx2; ++ dy1 = dy2; ++ ++ } while ( point != first ); ++ } ++ } + + + FT_LOCAL_DEF( void ) +@@ -925,11 +982,34 @@ + segment->last = point; + segment->pos = ( min_pos + max_pos ) >> 1; + ++#if 0 + /* a segment is round if either its first or last point */ + /* is a control point */ + if ( ( segment->first->flags | point->flags ) & + AH_FLAG_CONTROL ) + segment->flags |= AH_EDGE_ROUND; ++#else ++ /* a segment is round if it doesn't have successive */ ++ /* on-curve points. */ ++ { ++ AH_Point pt = segment->first; ++ AH_Flags f0 = pt->flags & AH_FLAG_CONTROL; ++ AH_Flags f1; ++ ++ ++ for ( ; pt != point; f0 = f1 ) ++ { ++ pt = pt->next; ++ f1 = pt->flags & AH_FLAG_CONTROL; ++ ++ if ( !f0 && !f1 ) ++ break; ++ ++ if ( pt == point ) ++ segment->flags |= AH_EDGE_ROUND; ++ } ++ } ++#endif + + /* compute segment size */ + min_pos = max_pos = point->v; +@@ -972,7 +1052,10 @@ + segment->first = point; + segment->last = point; + segment->contour = contour; +- segment->score = 32000; ++ segment->score1 = 0x7FFFFFFFL; ++ segment->score2 = 0x7FFFFFFFL; ++ segment->length = 0; ++ segment->sign = 0; + segment->link = NULL; + on_edge = 1; + +@@ -1035,7 +1118,10 @@ + segment->first = min_point; + segment->last = min_point; + segment->pos = min_pos; +- segment->score = 32000; ++ segment->score1 = 0x7FFFFFFFL; ++ segment->score2 = 0x7FFFFFFFL; ++ segment->length = 0; ++ segment->sign = 0; + segment->link = NULL; + + num_segments++; +@@ -1053,7 +1139,10 @@ + segment->first = max_point; + segment->last = max_point; + segment->pos = max_pos; +- segment->score = 32000; ++ segment->score1 = 0x7FFFFFFFL; ++ segment->score2 = 0x7FFFFFFFL; ++ segment->length = 0; ++ segment->sign = 0; + segment->link = NULL; + + num_segments++; +@@ -1080,11 +1169,13 @@ + AH_Segment segment_limit; + AH_Direction major_dir; + int dimension; ++ FT_Pos score_limit; + + + segments = outline->horz_segments; + segment_limit = segments + outline->num_hsegments; + major_dir = outline->horz_major_dir; ++ score_limit = FT_DivFix( 64*3*9, outline->y_scale ); + + for ( dimension = 1; dimension >= 0; dimension-- ) + { +@@ -1203,20 +1294,28 @@ + max = seg2->max_coord; + + len = max - min; +- if ( len >= 8 ) ++ if ( len >= 4 ) + { +- score = dist + 3000 / len; ++ score = 8*dist; + +- if ( score < seg1->score ) ++ if ( score < seg1->score1 && ++ !( score > seg1->score2 && 4*len < seg1->length ) ) + { +- seg1->score = score; +- seg1->link = seg2; ++ seg1->score1 = 9*dist; ++ seg1->score2 = 7*dist; ++ seg1->length = len; ++ seg1->sign = -1; ++ seg1->link = seg2; + } + +- if ( score < seg2->score ) ++ if ( score < seg2->score1 && ++ !( score > seg2->score2 && 4*len < seg2->length ) ) + { +- seg2->score = score; +- seg2->link = seg1; ++ seg2->score1 = 9*dist; ++ seg2->score2 = 7*dist; ++ seg2->length = len; ++ seg2->sign = +1; ++ seg2->link = seg1; + } + } + } +@@ -1225,6 +1324,73 @@ + #endif /* 1 */ + + /* now, compute the `serif' segments */ ++ { ++ AH_Segment seg, link1, link2; ++ FT_Pos pos1, pos2; ++ ++ ++ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) ++ { ++ if ( seg1->sign >= 0 || seg1->score1 >= score_limit ) ++ continue; ++ ++ link1 = seg1->link; ++ if ( link1->link != seg1 ) ++ continue; ++ ++ pos1 = seg1->pos; ++ pos2 = link1->pos; ++ ++ ++ for ( seg2 = segments; seg2 < segment_limit; seg2++ ) ++ { ++ if ( seg2->sign >= 0 || ++ seg2->score1 <= seg1->score1 || seg2->pos > pos1 ) ++ continue; ++ ++ link2 = seg2->link; ++ if ( link2->link != seg2 ) ++ continue; ++ ++ if ( link2->pos < pos2 || ++ seg1->score1*4 <= seg2->score1 ) ++ continue; ++ ++ /* seg2->pos < pos1 < pos2 < seg2->link->pos */ ++ ++ if ( seg1->length < seg2->length*2 ) ++ { ++ seg1->link = link1->link = 0; ++ seg1->sign = link1->sign = 0; ++ } ++ else ++ { ++ for ( seg = segments; seg < segment_limit; seg++ ) ++ { ++ AH_Segment link = seg->link; ++ ++ ++ if ( link == seg2 ) ++ { ++ seg->sign = 0; ++ seg->link = 0; ++ seg->serif = link1; ++ } ++ else if ( link == link2 ) ++ { ++ seg->sign = 0; ++ seg->link = 0; ++ seg->serif = seg1; ++ } ++ } ++ } ++ ++ break; ++ } ++ } ++ } ++ ++ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; +@@ -1234,8 +1400,13 @@ + seg2->num_linked++; + if ( seg2->link != seg1 ) + { +- seg1->link = 0; +- seg1->serif = seg2->link; ++ seg1->link = 0; ++ ++ if ( seg2->score1 < score_limit || ++ seg1->score1 < seg2->score1*4 ) ++ seg1->serif = seg2->link; ++ else ++ seg2->num_linked--; + } + } + } +@@ -1243,6 +1414,7 @@ + segments = outline->vert_segments; + segment_limit = segments + outline->num_vsegments; + major_dir = outline->vert_major_dir; ++ score_limit = FT_DivFix( 64*3*9, outline->x_scale ); + } + } + +@@ -1310,12 +1482,46 @@ + FT_Pos dist; + + ++ if ( edge->dir != seg->dir ) ++ continue; ++ + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold ) + { ++ AH_Segment link = seg->link; ++ ++ ++ /* check if all linked segments of the candidate edge */ ++ /* can make a single edge. */ ++ if ( link ) ++ { ++ AH_Segment seg1 = edge->first; ++ AH_Segment link1; ++ ++ ++ do ++ { ++ link1 = seg1->link; ++ if ( link1 ) ++ { ++ dist = link->pos - link1->pos; ++ if ( dist < 0 ) ++ dist = -dist; ++ ++ dist = FT_MulFix( dist, scale ); ++ if ( dist >= edge_distance_threshold ) ++ break; ++ } ++ ++ } while ( ( seg1 = seg1->edge_next ) != edge->first ); ++ ++ if ( dist >= edge_distance_threshold ) ++ continue; ++ } ++ + found = edge; + break; + } +@@ -1341,6 +1547,7 @@ + edge->fpos = seg->pos; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; ++ edge->dir = seg->dir; + } + else + { +@@ -1391,8 +1598,6 @@ + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ +- FT_Pos ups = 0; /* number of upwards segments */ +- FT_Pos downs = 0; /* number of downwards segments */ + + + seg = edge->first; +@@ -1408,12 +1613,6 @@ + else + is_straight++; + +- /* check for segment direction */ +- if ( seg->dir == up_dir ) +- ups += seg->max_coord-seg->min_coord; +- else +- downs += seg->max_coord-seg->min_coord; +- + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); +@@ -1479,18 +1678,6 @@ + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AH_EDGE_ROUND; + +- /* set the edge's main direction */ +- edge->dir = AH_DIR_NONE; +- +- if ( ups > downs ) +- edge->dir = up_dir; +- +- else if ( ups < downs ) +- edge->dir = -up_dir; +- +- else if ( ups == downs ) +- edge->dir = 0; /* both up and down! */ +- + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ +@@ -1523,7 +1710,7 @@ + ah_outline_compute_segments ( outline ); + ah_outline_link_segments ( outline ); + ah_outline_compute_edges ( outline ); +- ah_outline_compute_inflections( outline ); ++ ah_outline_compute_strongs ( outline ); + } + + +@@ -1542,12 +1729,15 @@ + { + AH_Edge edge = outline->horz_edges; + AH_Edge edge_limit = edge + outline->num_hedges; +- AH_Globals globals = &face_globals->design; ++ AH_Globals globals = &face_globals->designs[face_globals->cur_type]; + FT_Fixed y_scale = outline->y_scale; + + FT_Bool blue_active[AH_BLUE_MAX]; + + ++ if ( !globals->has_blues ) ++ return; ++ + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + { +@@ -1588,6 +1778,18 @@ + FT_Pos best_dist; /* initial threshold */ + + ++ if ( edge->serif ) ++ { ++ FT_Pos dist = edge->serif->pos - edge->pos; ++ ++ ++ if ( dist < 0 ) ++ dist = -dist; ++ ++ if ( dist < 128 ) ++ continue; ++ } ++ + /* compute the initial threshold as a fraction of the EM size */ + best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale ); + +@@ -1686,7 +1888,11 @@ + FT_Pos delta; + + +- delta = globals->scaled.blue_refs - globals->design.blue_refs; ++ if ( !globals->scaled.has_blues ) ++ return; ++ ++ delta = globals->scaled.blue_refs - ++ globals->designs[globals->cur_type].blue_refs; + + for ( ; edge < edge_limit; edge++ ) + { +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/ahhint.c freetype-2.1.5/src/autohint/ahhint.c +--- freetype-2.1.5-orig/src/autohint/ahhint.c Mon Aug 18 08:00:59 2003 ++++ freetype-2.1.5/src/autohint/ahhint.c Wed Nov 5 15:59:55 2003 +@@ -22,9 +22,9 @@ + #include <ft2build.h> + #include "ahhint.h" + #include "ahglyph.h" +-#include "ahangles.h" + #include "aherrors.h" + #include FT_OUTLINE_H ++#include FT_TRUETYPE_TABLES_H + + + #define FACE_GLOBALS( face ) ( (AH_Face_Globals)(face)->autohint.data ) +@@ -112,7 +112,8 @@ + + if ( !hinter->do_stem_adjust ) + { +- /* leave stem widths unchanged */ ++ if ( dist < 48 ) ++ dist += ( 48 - dist )/2 ; + } + else if ( ( vertical && !hinter->do_vert_snapping ) || + ( !vertical && !hinter->do_horz_snapping ) ) +@@ -120,6 +121,7 @@ + /* smooth hinting process: very lightly quantize the stem width */ + /* */ + ++#if 0 + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) +@@ -132,24 +134,35 @@ + } + else if ( dist < 56 ) + dist = 56; ++#endif + + { +- FT_Pos delta = dist - globals->stds[vertical]; ++ FT_Pos delta; + + +- if ( delta < 0 ) +- delta = -delta; +- +- if ( delta < 40 ) ++ if ( ( vertical && globals->num_heights > 0 ) || ++ ( !vertical && globals->num_widths > 0 ) ) + { +- dist = globals->stds[vertical]; +- if ( dist < 48 ) +- dist = 48; ++ delta = dist - globals->stds[vertical]; ++ ++ if ( delta < 0 ) ++ delta = -delta; + +- goto Done_Width; ++ if ( delta < 40 ) ++ { ++ dist = globals->stds[vertical]; ++ if ( dist < 48 ) ++ dist = 48; ++ ++ goto Done_Width; ++ } + } + +- if ( dist < 3 * 64 ) ++ if ( dist < 54 ) ++ { ++ dist += ( 54 - dist )/2 ; ++ } ++ else if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; +@@ -157,17 +170,18 @@ + if ( delta < 10 ) + dist += delta; + +- else if ( delta < 32 ) ++ else if ( delta < 22 ) + dist += 10; + ++ else if ( delta < 42 ) ++ dist += delta; ++ + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } +- else +- dist = ( dist + 32 ) & -64; + } + } + else +@@ -409,6 +423,129 @@ + serif->pos = base->pos + sign * dist; + } + ++ ++ static FT_Pos ++ ah_hint_normal_stem( AH_Hinter hinter, ++ AH_Edge edge, ++ AH_Edge edge2, ++ FT_Pos anchor, ++ FT_Int vertical ) ++ { ++ FT_Pos org_len, cur_len, org_center; ++ FT_Pos cur_pos1, cur_pos2; ++ FT_Pos d_off1, u_off1, d_off2, u_off2, delta; ++ FT_Pos offset; ++ FT_Pos threshold = 64; ++ ++ ++ if ( !hinter->do_stem_adjust ) ++ { ++ if ( ( edge->flags & AH_EDGE_ROUND ) && ++ ( edge2->flags & AH_EDGE_ROUND ) ) ++ { ++ if ( vertical ) ++ threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP; ++ else ++ threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP; ++ } ++ else ++ { ++ if ( vertical ) ++ threshold = 64 - AH_LIGHT_MODE_MAX_HORZ_GAP/3; ++ else ++ threshold = 64 - AH_LIGHT_MODE_MAX_VERT_GAP/3; ++ } ++ } ++ ++ org_len = edge2->opos - edge->opos; ++ cur_len = ah_compute_stem_width( hinter, vertical, org_len, ++ edge->flags, edge2->flags ); ++ org_center = ( edge->opos + edge2->opos ) / 2 + anchor; ++ cur_pos1 = org_center - cur_len / 2; ++ cur_pos2 = cur_pos1 + cur_len; ++ d_off1 = cur_pos1 - ( cur_pos1 & -64 ); ++ d_off2 = cur_pos2 - ( cur_pos2 & -64 ); ++ u_off1 = 64 - d_off1; ++ u_off2 = 64 - d_off2; ++ delta = 0; ++ ++ ++ if ( d_off1 == 0 || d_off2 == 0 ) ++ goto Exit; ++ ++ if ( cur_len <= threshold ) ++ { ++ if ( d_off2 < cur_len ) ++ { ++ if ( u_off1 <= d_off2 ) ++ delta = u_off1; ++ else ++ delta = -d_off2; ++ } ++ ++ goto Exit; ++ } ++ ++ if ( threshold < 64 ) ++ { ++ if ( d_off1 >= threshold || u_off1 >= threshold || ++ d_off2 >= threshold || u_off2 >= threshold ) ++ goto Exit; ++ } ++ ++ offset = cur_len % 64; ++ ++ if ( offset < 32 ) ++ { ++ if ( u_off1 <= offset || d_off2 <= offset ) ++ goto Exit; ++ } ++ else ++ offset = 64 - threshold; ++ ++ d_off1 = threshold - u_off1; ++ u_off1 = u_off1 - offset; ++ u_off2 = threshold - d_off2; ++ d_off2 = d_off2 - offset; ++ ++ if ( d_off1 <= u_off1 ) ++ u_off1 = -d_off1; ++ ++ if ( d_off2 <= u_off2 ) ++ u_off2 = -d_off2; ++ ++ if ( ABS( u_off1 ) <= ABS( u_off2 ) ) ++ delta = u_off1; ++ else ++ delta = u_off2; ++ ++ Exit: ++#if 1 ++ if ( !hinter->do_stem_adjust ) ++ { ++ if ( delta > AH_LIGHT_MODE_MAX_DELTA_ABS ) ++ delta = AH_LIGHT_MODE_MAX_DELTA_ABS; ++ else if ( delta < -AH_LIGHT_MODE_MAX_DELTA_ABS ) ++ delta = -AH_LIGHT_MODE_MAX_DELTA_ABS; ++ } ++#endif ++ ++ cur_pos1 += delta; ++ ++ if ( edge->opos < edge2->opos ) ++ { ++ edge->pos = cur_pos1; ++ edge2->pos = cur_pos1 + cur_len; ++ } ++ else ++ { ++ edge->pos = cur_pos1 + cur_len; ++ edge2->pos = cur_pos1; ++ } ++ ++ return delta; ++ } ++ + + /*************************************************************************/ + /*************************************************************************/ +@@ -438,6 +575,7 @@ + { + AH_Edge edge; + AH_Edge anchor = 0; ++ FT_Pos delta = 0; + int has_serifs = 0; + + +@@ -449,7 +587,7 @@ + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ +- if ( dimension ) ++ if ( dimension && hinter->do_blue_hints ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { +@@ -486,14 +624,10 @@ + ah_align_linked_edge( hinter, edge1, edge2, dimension ); + edge2->flags |= AH_EDGE_DONE; + } +- +- if ( !anchor ) +- anchor = edge; + } + } + +- /* now we will align all stem edges, trying to maintain the */ +- /* relative order of stems in the glyph */ ++ /* now we will align all stem edges. */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AH_EdgeRec* edge2; +@@ -520,6 +654,7 @@ + continue; + } + ++#if 0 + if ( !anchor ) + { + +@@ -686,6 +821,93 @@ + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + } ++#else /* 1 */ ++ ++ if ( !dimension && !anchor ) ++ { ++ if ( hinter->globals->is_fixedpitch && !hinter->composite ) ++ { ++ AH_Edge left = edge; ++ AH_Edge right = edge_limit - 1; ++ AH_EdgeRec left1, left2, right1, right2; ++ FT_Pos target, center1, center2; ++ FT_Pos delta1, delta2, d1, d2; ++ ++ ++ while ( right > left && !right->link ) ++ right--; ++ ++ left1 = *left; ++ left2 = *left->link; ++ right1 = *right->link; ++ right2 = *right; ++ ++ delta = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x )/2; ++ target = left->opos + ( right->opos - left->opos )/2 + delta - 16; ++ ++ delta1 = delta; ++ delta1 += ah_hint_normal_stem( hinter, left, left->link, ++ delta1, 0 ); ++ ++ if ( left->link != right ) ++ ah_hint_normal_stem( hinter, right->link, right, delta1, 0 ); ++ ++ center1 = left->pos + ( right->pos - left->pos )/2; ++ ++ if ( center1 >= target ) ++ delta2 = delta - 32; ++ else ++ delta2 = delta + 32; ++ ++ delta2 += ah_hint_normal_stem( hinter, &left1, &left2, delta2, 0 ); ++ ++ if ( delta1 != delta2 ) ++ { ++ if ( left->link != right ) ++ ah_hint_normal_stem( hinter, &right1, &right2, delta2, 0 ); ++ ++ center2 = left1.pos + ( right2.pos - left1.pos )/2; ++ ++ d1 = center1 - target; ++ d2 = center2 - target; ++ ++ if ( ABS( d2 ) < ABS( d1 ) ) ++ { ++ left->pos = left1.pos; ++ left->link->pos = left2.pos; ++ ++ if ( left->link != right ) ++ { ++ right->link->pos = right1.pos; ++ right->pos = right2.pos; ++ } ++ ++ delta1 = delta2; ++ } ++ } ++ ++ delta = delta1; ++ right->link->flags |= AH_EDGE_DONE; ++ right->flags |= AH_EDGE_DONE; ++ } ++ else ++ { ++ delta = ah_hint_normal_stem( hinter, edge, edge2, 0, 0 ); ++ } ++ ++ anchor = edge; ++ } ++ else ++ { ++ ah_hint_normal_stem( hinter, edge, edge2, ++ delta, dimension ); ++ anchor = edge; ++ } ++ ++ edge->flags |= AH_EDGE_DONE; ++ edge2->flags |= AH_EDGE_DONE; ++ ++#endif /* 1 */ + } + + /* make sure that lowercase m's maintain their symmetry */ +@@ -704,7 +926,8 @@ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; +- if ( !dimension && ( n_edges == 6 || n_edges == 12 ) ) ++ if ( hinter->do_blue_hints && ++ !dimension && ( n_edges == 6 || n_edges == 12 ) ) + { + AH_EdgeRec *edge1, *edge2, *edge3; + FT_Pos dist1, dist2, span, delta; +@@ -730,7 +953,9 @@ + if ( span < 0 ) + span = -span; + +- if ( span < 8 ) ++ if ( edge1->link == edge1 + 1 && ++ edge2->link == edge2 + 1 && ++ edge3->link == edge3 + 1 && span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; +@@ -761,25 +986,48 @@ + continue; + + if ( edge->serif ) +- ah_align_serif_edge( hinter, edge->serif, edge, dimension ); +- else if ( !anchor ) + { +- edge->pos = ( edge->opos + 32 ) & -64; +- anchor = edge; ++ ah_align_serif_edge( hinter, edge->serif, edge, dimension ); ++ edge->flags |= AH_EDGE_DONE; ++ has_serifs--; + } +- else +- edge->pos = anchor->pos + +- ( ( edge->opos-anchor->opos + 32 ) & -64 ); ++ } ++ ++ if ( !has_serifs ) ++ goto Next_Dimension; ++ ++ for ( edge = edges; edge < edge_limit; edge++ ) ++ { ++ AH_Edge before, after; + +- edge->flags |= AH_EDGE_DONE; + +- if ( edge > edges && edge->pos < edge[-1].pos ) +- edge->pos = edge[-1].pos; ++ if ( edge->flags & AH_EDGE_DONE ) ++ continue; ++ ++ before = after = edge; ++ ++ while ( --before >= edges ) ++ if ( before->flags & AH_EDGE_DONE ) ++ break; ++ ++ while ( ++after < edge_limit ) ++ if ( after->flags & AH_EDGE_DONE ) ++ break; ++ ++ if ( before >= edges || after < edge_limit ) ++ { ++ if ( before < edges ) ++ edge->pos = edge->opos + ( after->pos - after->opos ); ++ ++ else if ( after >= edge_limit ) ++ edge->pos = edge->opos + ( before->pos - before->opos ); + +- if ( edge + 1 < edge_limit && +- edge[1].flags & AH_EDGE_DONE && +- edge->pos > edge[1].pos ) +- edge->pos = edge[1].pos; ++ else ++ edge->pos = before->pos + ++ FT_MulDiv( edge->fpos - before->fpos, ++ after->pos - before->pos, ++ after->fpos - before->fpos ); ++ } + } + + Next_Dimension: +@@ -806,10 +1054,12 @@ + AH_Edge edges; + AH_Edge edge_limit; + FT_Int dimension; ++ FT_Bool snapping; + + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; ++ snapping = hinter->do_vert_snapping; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { +@@ -821,7 +1071,8 @@ + { + /* move the points of each segment */ + /* in each edge to the edge's position */ +- AH_Segment seg = edge->first; ++ AH_Segment seg = edge->first; ++ FT_Pos delta = edge->pos - edge->opos; + + + do +@@ -829,23 +1080,47 @@ + AH_Point point = seg->first; + + +- for (;;) ++ if ( snapping ) + { +- if ( dimension ) ++ for (;;) + { +- point->y = edge->pos; +- point->flags |= AH_FLAG_TOUCH_Y; ++ if ( dimension ) ++ { ++ point->y = edge->pos; ++ point->flags |= AH_FLAG_TOUCH_Y; ++ } ++ else ++ { ++ point->x = edge->pos; ++ point->flags |= AH_FLAG_TOUCH_X; ++ } ++ ++ if ( point == seg->last ) ++ break; ++ ++ point = point->next; + } +- else ++ } ++ else ++ { ++ for (;;) + { +- point->x = edge->pos; +- point->flags |= AH_FLAG_TOUCH_X; +- } ++ if ( dimension ) ++ { ++ point->y += delta; ++ point->flags |= AH_FLAG_TOUCH_Y; ++ } ++ else ++ { ++ point->x += delta; ++ point->flags |= AH_FLAG_TOUCH_X; ++ } + +- if ( point == seg->last ) +- break; ++ if ( point == seg->last ) ++ break; + +- point = point->next; ++ point = point->next; ++ } + } + + seg = seg->edge_next; +@@ -855,6 +1130,7 @@ + + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; ++ snapping = hinter->do_horz_snapping; + } + } + +@@ -871,6 +1147,7 @@ + AH_Point points; + AH_Point point_limit; + AH_Flags touch_flag; ++ AH_Flags strong_flag; + + + points = outline->points; +@@ -879,6 +1156,7 @@ + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + touch_flag = AH_FLAG_TOUCH_Y; ++ strong_flag = AH_FLAG_STRONG_Y; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { +@@ -899,8 +1177,7 @@ + #ifndef AH_OPTION_NO_WEAK_INTERPOLATION + /* if this point is candidate to weak interpolation, we will */ + /* interpolate it after all strong points have been processed */ +- if ( ( point->flags & AH_FLAG_WEAK_INTERPOLATION ) && +- !( point->flags & AH_FLAG_INFLECTION ) ) ++ if ( !( point->flags & strong_flag ) ) + continue; + #endif + +@@ -1034,6 +1311,7 @@ + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + touch_flag = AH_FLAG_TOUCH_X; ++ strong_flag = AH_FLAG_STRONG_X; + } + } + +@@ -1234,10 +1512,8 @@ + + + FT_LOCAL_DEF( void ) +- ah_hinter_align_points( AH_Hinter hinter ) ++ ah_hinter_align_normal_points( AH_Hinter hinter ) + { +- ah_hinter_align_edge_points( hinter ); +- + #ifndef AH_OPTION_NO_STRONG_INTERPOLATION + ah_hinter_align_strong_points( hinter ); + #endif +@@ -1263,17 +1539,69 @@ + static void + ah_hinter_scale_globals( AH_Hinter hinter, + FT_Fixed x_scale, +- FT_Fixed y_scale ) ++ FT_Fixed y_scale, ++ FT_Byte type ) + { + FT_Int n; + AH_Face_Globals globals = hinter->globals; +- AH_Globals design = &globals->design; ++ AH_Globals design = &globals->designs[type]; + AH_Globals scaled = &globals->scaled; ++ FT_Pos baseline = design->baseline; ++ + ++ globals->x_scale_linear = x_scale; ++ globals->y_scale_linear = y_scale; ++ globals->cur_type = type; + + /* copy content */ + *scaled = *design; + ++#ifdef FT_CONFIG_CHESTER_BLUE_SCALE ++ ++ /* try to optimize the y_scale so that the top of non-capital letters ++ * is aligned on a pixel boundary whenever possible ++ */ ++ if ( design->has_blues ) ++ { ++ FT_Pos shoot = design->blue_shoots[AH_BLUE_SMALL_TOP]; ++ FT_Pos ref = design->blue_refs[AH_BLUE_SMALL_TOP]; ++ ++ ++ baseline = FT_MulFix( baseline, y_scale ); ++ ++ /* the value of 'shoot' will be -1000 if the font doesn't have */ ++ /* small latin letters; we simply check the sign here... */ ++ if ( shoot > 0 ) ++ { ++ FT_Pos fitted; ++ ++ ++ shoot = FT_MulFix( shoot, y_scale ); ++ ref = FT_MulFix( ref, y_scale ); ++ ++ if ( shoot < 6*64 ) ++ fitted = ( shoot + 44 ) & -64; ++ else if ( shoot < 8*64 ) ++ fitted = ( shoot + 38 ) & -64; ++ else ++ fitted = ( shoot + 32 ) & -64; ++ ++ ++ if ( ref <= fitted && fitted < shoot ) ++ fitted = shoot; ++ else if ( fitted < ref ) ++ shoot = ref; ++ ++ if ( fitted > shoot ) ++ { ++ y_scale = FT_MulDiv( y_scale, fitted, shoot ); ++ baseline -= ( fitted - shoot )/2; ++ } ++ } ++ } ++ ++#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */ ++ + /* scale the standard widths & heights */ + for ( n = 0; n < design->num_widths; n++ ) + scaled->widths[n] = FT_MulFix( design->widths[n], x_scale ); +@@ -1284,10 +1612,20 @@ + scaled->stds[0] = ( design->num_widths > 0 ) ? scaled->widths[0] : 32000; + scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000; + ++ globals->x_scale = x_scale; ++ globals->y_scale = y_scale; ++ ++ if ( !design->has_blues ) ++ return; ++ ++ ++ scaled->baseline = ( baseline + 32 ) & -64; ++ + /* scale the blue zones */ + for ( n = 0; n < AH_BLUE_MAX; n++ ) + { + FT_Pos delta, delta2; ++ FT_Pos ref, shoot, delta3, delta4; + + + delta = design->blue_shoots[n] - design->blue_refs[n]; +@@ -1306,13 +1644,37 @@ + if ( delta < 0 ) + delta2 = -delta2; + +- scaled->blue_refs[n] = +- ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64; +- scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2; +- } ++ if ( n == AH_BLUE_SMALL_BOTTOM ) ++ { ++ scaled->blue_shoots[n] = delta2; ++ scaled->blue_refs[n] = 0; ++ continue; ++ } + +- globals->x_scale = x_scale; +- globals->y_scale = y_scale; ++ shoot = FT_MulFix( design->blue_shoots[n], y_scale ); ++ ref = FT_MulFix( design->blue_refs[n], y_scale ); ++ delta3 = ( ( shoot + 32 ) & -64 ) - shoot; ++ delta4 = ( ( ref + 32 ) & -64 ) - ref; ++ ++ if ( !hinter->do_stem_adjust ) ++ { ++ if ( delta3 > 16 ) delta3 = 16; ++ if ( delta3 < -16 ) delta3 = -16; ++ if ( delta4 > 16 ) delta4 = 16; ++ if ( delta4 < -16 ) delta4 = -16; ++ } ++ ++ shoot += delta3; ++ ref += delta4; ++ ++ if ( ABS( delta3 ) < ABS( delta4 ) ) ++ ref = shoot - delta2; ++ else ++ shoot = ref + delta2; ++ ++ scaled->blue_refs[n] = ref; ++ scaled->blue_shoots[n] = shoot; ++ } + } + + +@@ -1320,7 +1682,7 @@ + ah_hinter_align( AH_Hinter hinter ) + { + ah_hinter_align_edge_points( hinter ); +- ah_hinter_align_points( hinter ); ++ ah_hinter_align_normal_points( hinter ); + } + + +@@ -1401,7 +1763,7 @@ + hinter->globals = face_globals; + + if ( globals ) +- face_globals->design = *globals; ++ face_globals->designs[0] = *globals; + else + ah_hinter_compute_globals( hinter ); + +@@ -1410,6 +1772,27 @@ + ah_hinter_done_face_globals; + face_globals->face = face; + ++ ah_hinter_compute_char_table( hinter ); ++ ++ { ++ TT_OS2* os2 = FT_Get_Sfnt_Table( face, ft_sfnt_os2 ); ++ ++ ++ if ( os2 && os2->version != 0xFFFFU ) ++ face_globals->is_fixedpitch = FT_BOOL( os2->panose[3] == 9 ); ++ else ++ face_globals->is_fixedpitch = FT_BOOL( FT_IS_FIXED_WIDTH( face ) != 0 ); ++ ++ ++ face_globals->has_tt_bytecode_interp = FALSE; ++ ++#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER ++ if ( !strcmp( face->driver->root.clazz->module_name, "truetype" ) || ++ !strcmp( face->driver->root.clazz->module_name, "type42" ) ) ++ face_globals->has_tt_bytecode_interp = TRUE; ++#endif ++ } ++ + Exit: + return error; + } +@@ -1423,6 +1806,8 @@ + FT_Memory memory = face->memory; + + ++ FT_Done_Size( globals->size_EM ); ++ FT_FREE( globals->table ); + FT_FREE( globals ); + } + +@@ -1441,12 +1826,17 @@ + FT_Error error; + AH_Outline outline = hinter->glyph; + AH_Loader gloader = hinter->loader; ++ FT_Pos baseline = 0; ++ FT_Byte type = hinter->globals->cur_type; + + + /* load the glyph */ +- error = FT_Load_Glyph( face, glyph_index, load_flags ); +- if ( error ) +- goto Exit; ++ if ( !hinter->globals->has_tt_bytecode_interp ) ++ { ++ error = FT_Load_Glyph( face, glyph_index, load_flags ); ++ if ( error ) ++ goto Exit; ++ } + + /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */ + hinter->transformed = internal->glyph_transformed; +@@ -1463,6 +1853,11 @@ + FT_Matrix_Invert( &imatrix ); + FT_Vector_Transform( &hinter->trans_delta, &imatrix ); + } ++ else ++ { ++ hinter->trans_delta.x = 0; ++ hinter->trans_delta.y = 0; ++ } + + /* set linear horizontal metrics */ + slot->linearHoriAdvance = slot->metrics.horiAdvance; +@@ -1472,17 +1867,22 @@ + { + case FT_GLYPH_FORMAT_OUTLINE: + ++ if ( hinter->do_blue_hints ) ++ baseline = hinter->globals->designs[type].baseline; ++ + /* translate glyph outline if we need to */ +- if ( hinter->transformed ) ++ if ( hinter->transformed || baseline != 0 ) + { + FT_UInt n = slot->outline.n_points; + FT_Vector* point = slot->outline.points; ++ FT_Pos x_off = hinter->trans_delta.x; ++ FT_Pos y_off = hinter->trans_delta.y - baseline; + + + for ( ; n > 0; point++, n-- ) + { +- point->x += hinter->trans_delta.x; +- point->y += hinter->trans_delta.y; ++ point->x += x_off; ++ point->y += y_off; + } + } + +@@ -1524,7 +1924,7 @@ + /* perform feature detection */ + ah_outline_detect_features( outline ); + +- if ( hinter->do_vert_hints ) ++ if ( hinter->do_blue_hints ) + { + ah_outline_compute_blue_edges( outline, hinter->globals ); + ah_outline_scale_blue_edges( outline, hinter->globals ); +@@ -1539,6 +1939,8 @@ + + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occured during the hinting process */ ++ if ( !hinter->globals->is_fixedpitch && !hinter->composite && ++ type <= AH_CHAR_TYPE_HORIZONTAL ) + { + FT_Pos old_advance, old_rsb, old_lsb, new_lsb; + AH_Edge edge1 = outline->vert_edges; /* leftmost edge */ +@@ -1551,8 +1953,8 @@ + old_lsb = edge1->opos; + new_lsb = edge1->pos; + +- hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; +- hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64; ++ hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; ++ hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 40 ) & -64; + + #if 0 + /* try to fix certain bad advance computations */ +@@ -1705,6 +2107,13 @@ + FT_BBox bbox; + + ++ if ( hinter->do_blue_hints ) ++ { ++ if ( hinter->globals->scaled.baseline != 0 ) ++ FT_Outline_Translate( &gloader->base.outline, ++ 0, hinter->globals->scaled.baseline ); ++ } ++ + /* transform the hinted outline if needed */ + if ( hinter->transformed ) + FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix ); +@@ -1725,14 +2134,7 @@ + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + +- /* for mono-width fonts (like Andale, Courier, etc.) we need */ +- /* to keep the original rounded advance width */ +- if ( !FT_IS_FIXED_WIDTH( slot->face ) ) +- slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x; +- else +- slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, +- x_scale ); +- ++ slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x; + slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64; + + /* now copy outline into glyph slot */ +@@ -1754,6 +2156,236 @@ + } + + ++#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER ++ ++#define AH_MAX_COMPOSITE_RECURSE 5 ++ ++ static FT_Error ++ ah_hinter_load_truetype( AH_Hinter hinter, ++ FT_UInt glyph_index, ++ FT_Int32 load_flags, ++ int depth, ++ short **num_contours, ++ short **num_points, ++ int *num_simple_glyphs, ++ int *size_array ) ++ { ++ FT_Face face = hinter->face; ++ FT_Memory memory = hinter->memory; ++ FT_GlyphSlot slot = face->glyph; ++ FT_Error error = FT_Err_Ok; ++ ++ ++ if ( depth == 0 ) ++ { ++ *num_contours = 0; ++ *num_points = 0; ++ *num_simple_glyphs = 0; ++ *size_array = 0; ++ } ++ ++ error = FT_Load_Glyph( face, glyph_index, load_flags ); ++ ++ if ( error ) ++ return error; ++ ++ switch ( slot->format ) ++ { ++ case FT_GLYPH_FORMAT_OUTLINE: ++ { ++ int size_cur = *size_array; ++ ++ ++ if ( depth == 0 ) ++ return ah_hinter_load( hinter, 0, load_flags, 0 ); ++ ++ if ( slot->outline.n_contours == 0 ) ++ break; ++ ++ if ( *num_simple_glyphs >= size_cur ) ++ { ++ if ( FT_RENEW_ARRAY( *num_contours, size_cur, size_cur + 16 ) || ++ FT_RENEW_ARRAY( *num_points, size_cur, size_cur + 16 ) ) ++ goto Exit; ++ *size_array += 16; ++ } ++ ++ (*num_contours)[ (*num_simple_glyphs) ] = slot->outline.n_contours; ++ (*num_points)[ (*num_simple_glyphs)++ ] = slot->outline.n_points; ++ break; ++ } ++ ++ case FT_GLYPH_FORMAT_COMPOSITE: ++ if ( depth + 1 >= AH_MAX_COMPOSITE_RECURSE ) ++ return AH_Err_Invalid_Composite; ++ ++ if ( slot->num_subglyphs > 0 ) ++ { ++ FT_UInt* indices; ++ int num_subglyphs = slot->num_subglyphs; ++ int i; ++ ++ ++ hinter->composite = TRUE; ++ ++ if ( FT_NEW_ARRAY( indices, num_subglyphs ) ) ++ goto Exit; ++ ++ for ( i = 0; i < num_subglyphs; i++ ) ++ indices[i] = slot->subglyphs[i].index; ++ ++ ++ for ( i = 0; i < num_subglyphs; i++ ) ++ { ++ error = ah_hinter_load_truetype( hinter, ++ indices[i], ++ load_flags, ++ depth + 1, ++ num_contours, ++ num_points, ++ num_simple_glyphs, ++ size_array ); ++ if ( error ) ++ { ++ FT_FREE( indices ); ++ goto Exit; ++ } ++ } ++ ++ FT_FREE( indices ); ++ ++ if ( depth == 0 ) ++ { ++ FT_Size size_EM, size; ++ FT_Vector* points; ++ FT_Vector* limit; ++ int num = *num_simple_glyphs, j; ++ short n_contours, n_points; ++ short *array_c, *array_p; ++ ++ ++ if ( num == 0 ) ++ break; ++ ++ size = face->size; ++ size_EM = hinter->globals->size_EM; ++ ++ if ( !size_EM ) ++ { ++ error = FT_New_Size( face, &hinter->globals->size_EM ); ++ if ( error ) ++ goto Exit; ++ ++ size_EM = hinter->globals->size_EM; ++ FT_Activate_Size( size_EM ); ++ ++ error = FT_Set_Pixel_Sizes( face, ++ face->units_per_EM, ++ face->units_per_EM ); ++ if ( error ) ++ { ++ FT_Activate_Size( size ); ++ goto Exit; ++ } ++ } ++ else ++ FT_Activate_Size( size_EM ); ++ ++ ++ load_flags &= ~FT_LOAD_NO_RECURSE & ++ ~FT_LOAD_NO_SCALE; ++ load_flags |= FT_LOAD_NO_BITMAP | ++ FT_LOAD_NO_AUTOHINT | ++ FT_LOAD_IGNORE_TRANSFORM; ++ ++ error = FT_Load_Glyph( face, glyph_index, load_flags ); ++ ++ FT_Activate_Size( size ); ++ ++ if ( error ) ++ goto Exit; ++ ++ ++ array_c = *num_contours; ++ array_p = *num_points; ++ n_contours = 0; ++ n_points = 0; ++ ++ for ( i = 0; i < num; i++ ) ++ { ++ n_contours += *array_c++; ++ n_points += *array_p++; ++ } ++ ++ if ( slot->outline.n_points != n_points || ++ slot->outline.n_contours != n_contours ) ++ { ++ error = AH_Err_Invalid_Composite; ++ goto Exit; ++ } ++ ++ ++ points = slot->outline.points; ++ limit = points + slot->outline.n_points; ++ ++ while ( points < limit ) ++ { ++ points->x >>= 6; ++ points->y >>= 6; ++ points++; ++ } ++ ++ slot->metrics.horiAdvance >>= 6; ++ slot->metrics.vertAdvance >>= 6; ++ ++ array_c = *num_contours; ++ array_p = *num_points; ++ ++ for ( i = 0; i < num - 1; i++ ) ++ { ++ slot->outline.n_contours = *array_c++; ++ slot->outline.n_points = *array_p++; ++ ++ error = ah_hinter_load( hinter, 0, load_flags, 1 ); ++ if ( error ) ++ goto Exit; ++ ++ n_points = slot->outline.n_points; ++ slot->outline.points += n_points; ++ slot->outline.tags += n_points; ++ slot->outline.contours += slot->outline.n_contours; ++ n_contours -= slot->outline.n_contours; ++ ++ for ( j = 0; j < n_contours; j++ ) ++ slot->outline.contours[j] -= n_points; ++ } ++ ++ slot->outline.n_contours = *array_c; ++ slot->outline.n_points = *array_p; ++ ++ error = ah_hinter_load( hinter, 0, load_flags, 0 ); ++ } ++ } ++ break; ++ ++ default: ++ error = AH_Err_Unimplemented_Feature; ++ } ++ ++ ++ Exit: ++ if ( depth == 0 ) ++ { ++ FT_FREE( *num_contours ); ++ FT_FREE( *num_points ); ++ } ++ ++ return error; ++ } ++ ++#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ ++ ++ + /* load and hint a given glyph */ + FT_LOCAL_DEF( FT_Error ) + ah_hinter_load_glyph( AH_Hinter hinter, +@@ -1768,6 +2400,7 @@ + FT_Fixed y_scale = size->metrics.y_scale; + AH_Face_Globals face_globals = FACE_GLOBALS( face ); + FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE( load_flags ); ++ FT_Byte type; + + + /* first of all, we need to check that we're using the correct face and */ +@@ -1787,46 +2420,6 @@ + + } + +-#ifdef FT_CONFIG_CHESTER_BLUE_SCALE +- +- /* try to optimize the y_scale so that the top of non-capital letters +- * is aligned on a pixel boundary whenever possible +- */ +- { +- AH_Globals design = &face_globals->design; +- FT_Pos shoot = design->blue_shoots[AH_BLUE_SMALL_TOP]; +- +- +- /* the value of 'shoot' will be -1000 if the font doesn't have */ +- /* small latin letters; we simply check the sign here... */ +- if ( shoot > 0 ) +- { +- FT_Pos scaled = FT_MulFix( shoot, y_scale ); +- FT_Pos fitted = ( scaled + 32 ) & -64; +- +- +- if ( scaled != fitted ) +- { +- /* adjust y_scale +- */ +- y_scale = FT_MulDiv( y_scale, fitted, scaled ); +- +- /* adust x_scale +- */ +- if ( fitted < scaled ) +- x_scale -= x_scale / 50; /* x_scale*0.98 with integers */ +- } +- } +- } +- +-#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */ +- +- /* now, we must check the current character pixel size to see if we */ +- /* need to rescale the global metrics */ +- if ( face_globals->x_scale != x_scale || +- face_globals->y_scale != y_scale ) +- ah_hinter_scale_globals( hinter, x_scale, y_scale ); +- + ah_loader_rewind( hinter->loader ); + + /* reset hinting flags according to load flags and current render target */ +@@ -1850,11 +2443,51 @@ + + hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + ++ type = ah_hinter_get_char_type( hinter, glyph_index ); ++ ++ hinter->do_blue_hints = face_globals->designs[type].has_blues; ++ hinter->composite = FALSE; ++ ++ /* now, we must check the current character pixel size to see if we */ ++ /* need to rescale the global metrics */ ++ if ( face_globals->x_scale_linear != x_scale || ++ face_globals->y_scale_linear != y_scale || ++ face_globals->cur_type != type ) ++ ah_hinter_scale_globals( hinter, x_scale, y_scale, type ); ++ + + load_flags |= FT_LOAD_NO_SCALE + | FT_LOAD_IGNORE_TRANSFORM ; + +- error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); ++#ifndef TT_CONFIG_OPTION_BYTECODE_INTERPRETER ++ ++ error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); ++ ++#else ++ ++ if ( face_globals->has_tt_bytecode_interp ) ++ { ++ short* num_contours; ++ short* num_points; ++ int num_simple_glyphs; ++ int size_array; ++ ++ ++ load_flags |= FT_LOAD_NO_RECURSE; ++ ++ error = ah_hinter_load_truetype( hinter, ++ glyph_index, ++ load_flags, ++ 0, ++ &num_contours, ++ &num_points, ++ &num_simple_glyphs, ++ &size_array ); ++ } ++ else ++ error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); ++ ++#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + Exit: + return error; +@@ -1885,7 +2518,7 @@ + goto Fail; + } + +- *globals = FACE_GLOBALS( face )->design; ++ *globals = FACE_GLOBALS( face )->designs[0]; + *global_hints = globals; + *global_len = sizeof( *globals ); + +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/ahtypes.h freetype-2.1.5/src/autohint/ahtypes.h +--- freetype-2.1.5-orig/src/autohint/ahtypes.h Wed May 28 14:52:05 2003 ++++ freetype-2.1.5/src/autohint/ahtypes.h Wed Nov 5 16:00:17 2003 +@@ -138,6 +138,8 @@ + /* weak interpolation */ + #define AH_FLAG_WEAK_INTERPOLATION 256 + #define AH_FLAG_INFLECTION 512 ++#define AH_FLAG_STRONG_X 1024 ++#define AH_FLAG_STRONG_Y 2048 + + typedef FT_Int AH_Flags; + +@@ -264,7 +266,10 @@ + AH_Segment link; /* link segment */ + AH_Segment serif; /* primary segment for serifs */ + FT_Pos num_linked; /* number of linked segments */ +- FT_Pos score; ++ FT_Pos score1; ++ FT_Pos score2; ++ FT_Pos length; ++ FT_Int sign; + + AH_Point first; /* first point in edge segment */ + AH_Point last; /* last point in edge segment */ +@@ -402,6 +407,37 @@ + typedef FT_Int AH_Hinter_Flags; + + ++#define AH_LIGHT_MODE_MAX_HORZ_GAP 9 ++#define AH_LIGHT_MODE_MAX_VERT_GAP 15 ++#define AH_LIGHT_MODE_MAX_DELTA_ABS 14 ++ ++ enum ++ { ++ AH_CHAR_TYPE_LATINATE = 0, ++ AH_CHAR_TYPE_LATIN_FULLWIDTH, ++ AH_CHAR_TYPE_HORIZONTAL, ++ AH_CHAR_TYPE_OTHER, ++ AH_CHAR_TYPE_COUNT ++ }; ++ ++ ++ typedef struct AH_CharType_ ++ { ++ FT_Byte type; ++ FT_ULong start; ++ FT_ULong last; ++ ++ } AH_CharType; ++ ++ ++ typedef struct AH_CharTypeTable_ ++ { ++ FT_ULong size; ++ AH_CharType* types; ++ ++ } AH_CharTypeTable; ++ ++ + /*************************************************************************/ + /* */ + /* <Struct> */ +@@ -440,6 +476,10 @@ + FT_Pos blue_refs [AH_BLUE_MAX]; + FT_Pos blue_shoots[AH_BLUE_MAX]; + ++ FT_Pos baseline; ++ ++ FT_Bool has_blues; ++ + } AH_GlobalsRec, *AH_Globals; + + +@@ -470,12 +510,21 @@ + typedef struct AH_Face_GlobalsRec_ + { + FT_Face face; +- AH_GlobalsRec design; ++ AH_GlobalsRec designs[AH_CHAR_TYPE_COUNT]; + AH_GlobalsRec scaled; + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Bool control_overshoot; + ++ FT_Fixed x_scale_linear; ++ FT_Fixed y_scale_linear; ++ ++ AH_CharTypeTable* table; ++ FT_Byte cur_type; ++ FT_Size size_EM; ++ FT_Bool is_fixedpitch; ++ FT_Bool has_tt_bytecode_interp; ++ + } AH_Face_GlobalsRec, *AH_Face_Globals; + + +@@ -494,6 +543,7 @@ + AH_Loader loader; + FT_Vector pp1; + FT_Vector pp2; ++ FT_Bool composite; + + FT_Bool transformed; + FT_Vector trans_delta; +@@ -504,6 +554,7 @@ + FT_Bool do_horz_snapping; /* disable X stem size snapping */ + FT_Bool do_vert_snapping; /* disable Y stem size snapping */ + FT_Bool do_stem_adjust; /* disable light stem snapping */ ++ FT_Bool do_blue_hints; /* disable blue hinting */ + + } AH_HinterRec, *AH_Hinter; + +diff -u -x Makefile -x ahmodule.h -x ahmodule.c freetype-2.1.5-orig/src/autohint/autohint.c freetype-2.1.5/src/autohint/autohint.c +--- freetype-2.1.5-orig/src/autohint/autohint.c Fri Jun 29 02:48:46 2001 ++++ freetype-2.1.5/src/autohint/autohint.c Sat Sep 20 09:58:12 2003 +@@ -22,7 +22,6 @@ + #define FT_MAKE_OPTION_SINGLE_OBJECT + + #include <ft2build.h> +-#include "ahangles.c" + #include "ahglyph.c" + #include "ahglobal.c" + #include "ahhint.c" +Only in freetype-2.1.5/src/autohint: autohint.o diff --git a/media-libs/freetype/files/digest-freetype-2.1.5-r1 b/media-libs/freetype/files/digest-freetype-2.1.5-r1 new file mode 100644 index 000000000000..2657d5c77518 --- /dev/null +++ b/media-libs/freetype/files/digest-freetype-2.1.5-r1 @@ -0,0 +1 @@ +MD5 54537b518b84d04190a1eccd393a29df freetype-2.1.5.tar.bz2 850767 diff --git a/media-libs/freetype/freetype-2.1.5-r1.ebuild b/media-libs/freetype/freetype-2.1.5-r1.ebuild new file mode 100644 index 000000000000..3ebbf12a1a4d --- /dev/null +++ b/media-libs/freetype/freetype-2.1.5-r1.ebuild @@ -0,0 +1,62 @@ +# Copyright 1999-2003 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/media-libs/freetype/freetype-2.1.5-r1.ebuild,v 1.1 2004/02/15 22:15:19 foser Exp $ + +inherit eutils flag-o-matic + +SPV="`echo ${PV} | cut -d. -f1,2`" + +DESCRIPTION="A high-quality and portable font engine" +HOMEPAGE="http://www.freetype.org/" +SRC_URI="mirror://sourceforge/freetype/${P/_/}.tar.bz2" + +SLOT="2" +LICENSE="FTL | GPL-2" +KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~arm ~ia64 ~amd64 ~ppc64" +IUSE="zlib bindist cjk" + +DEPEND="virtual/glibc + zlib? ( sys-libs/zlib )" + +src_unpack() { + + unpack ${A} + + cd ${S} + # add autohint patch from http://www.kde.gr.jp/~akito/patch/freetype2/2.1.5/ + use cjk && epatch ${FILESDIR}/${SPV}/${P}-autohint-cjkfonts-20031105.patch + +} + +src_compile() { + + local myconf + + use zlib \ + && myconf="${myconf} --with-zlib" \ + || myconf="${myconf} --without-zlib" + + use bindist || append-flags "${CFLAGS} -DTT_CONFIG_OPTION_BYTECODE_INTERPRETER" + + make setup CFG="--host=${CHOST} --prefix=/usr ${myconf}" unix || die + + emake || die + + # Just a check to see if the Bytecode Interpreter was enabled ... + if [ -z "`grep TT_Goto_CodeRange ${S}/objs/.libs/libfreetype.so`" ] + then + ewarn "Bytecode Interpreter is disabled." + fi + +} + +src_install() { + + make prefix=${D}/usr install || die + + dodoc ChangeLog README + dodoc docs/{CHANGES,CUSTOMIZE,DEBUG,*.txt,PATENTS,TODO} + + use doc && dohtml -r docs/* + +} diff --git a/media-libs/freetype/freetype-2.1.5.ebuild b/media-libs/freetype/freetype-2.1.5.ebuild index 147cb5fbb95c..1552e4de9531 100644 --- a/media-libs/freetype/freetype-2.1.5.ebuild +++ b/media-libs/freetype/freetype-2.1.5.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/media-libs/freetype/freetype-2.1.5.ebuild,v 1.3 2003/12/17 04:57:46 brad_mssw Exp $ +# $Header: /var/cvsroot/gentoo-x86/media-libs/freetype/freetype-2.1.5.ebuild,v 1.4 2004/02/15 22:15:19 foser Exp $ inherit eutils flag-o-matic @@ -8,11 +8,12 @@ SPV="`echo ${PV} | cut -d. -f1,2`" DESCRIPTION="A high-quality and portable font engine" HOMEPAGE="http://www.freetype.org/" -SRC_URI="mirror://sourceforge/freetype/${P/_/}.tar.bz2" +SRC_URI="mirror://sourceforge/freetype/${P/_/}.tar.bz2 + doc? ( mirror://sourceforge/${PN}/ftdocs-${PV}.tar.bz2 )" SLOT="2" LICENSE="FTL | GPL-2" -KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~arm ~ia64 ~amd64 ppc64" +KEYWORDS="x86 ~ppc ~sparc ~alpha ~hppa ~arm ~ia64 ~amd64 ppc64" IUSE="zlib bindist" DEPEND="virtual/glibc |