summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarinus Schraal <foser@gentoo.org>2004-02-15 22:15:19 +0000
committerMarinus Schraal <foser@gentoo.org>2004-02-15 22:15:19 +0000
commit0f590970f9773c33ed9a3b1a043618ac8e2ae238 (patch)
tree951be968c454290e114c11ac5c9ca8c4bc9a5148 /media-libs/freetype
parentFix sg, adduser and vigr symlinks (make them relative not absolute), bug (diff)
downloadgentoo-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/ChangeLog9
-rw-r--r--media-libs/freetype/files/2.1/freetype-2.1.5-autohint-cjkfonts-20031105.patch2320
-rw-r--r--media-libs/freetype/files/digest-freetype-2.1.5-r11
-rw-r--r--media-libs/freetype/freetype-2.1.5-r1.ebuild62
-rw-r--r--media-libs/freetype/freetype-2.1.5.ebuild7
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