--- XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.c.orig 2005-10-14 17:16:01.000000000 +0200 +++ XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.c 2006-07-19 08:16:57.502772250 +0200 @@ -50,10 +50,7 @@ #include FT_TYPE1_TABLES_H #include FT_XFREE86_H #include FT_BBOX_H -#include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_STREAM_H /* * If you want to use FT_Outline_Get_CBox instead of * FT_Outline_Get_BBox, define here. @@ -119,6 +116,25 @@ }; +/* read 2-byte value from a SFNT table */ +static FT_UShort +sfnt_get_ushort( FT_Face face, + FT_ULong table_tag, + FT_ULong table_offset ) +{ + FT_Byte buff[2]; + FT_ULong len = sizeof(buff); + FT_UShort result = 0; + + if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) ); + result = (FT_UShort)( (buff[0] << 8) | buff[1] ); + + return result; +} + +#define sfnt_get_short(f,t,o) ((FT_Short)sfnt_get_ushort((f),(t),(o))) + + static int ftypeInitP = 0; /* is the engine initialised? */ static FT_Library ftypeLibrary; @@ -207,6 +223,10 @@ if(maxp && maxp->maxContours == 0) face->bitmap = 1; } + + face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face, + TTAG_hhea, 34 ); + /* Insert face in hashtable and return it */ face->next = faceTable[bucket]; faceTable[bucket] = face; @@ -458,6 +478,34 @@ } if( FT_IS_SFNT( face->face ) ) { +#if 1 + FT_F26Dot6 tt_char_width, tt_char_height, tt_dim_x, tt_dim_y; + FT_UInt nn; + + instance->strike_index=0xFFFFU; + + tt_char_width = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5); + tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5); + + tt_dim_x = FLOOR64( ( tt_char_width * trans->xres + 36 ) / 72 + 32 ); + tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 ); + + if ( tt_dim_x && !tt_dim_y ) + tt_dim_y = tt_dim_x; + else if ( !tt_dim_x && tt_dim_y ) + tt_dim_x = tt_dim_y; + + for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ ) + { + FT_Bitmap_Size* sz = &face->face->available_sizes[nn]; + + if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) ) + { + instance->strike_index = nn; + break; + } + } +#else /* See Set_Char_Sizes() in ttdriver.c */ FT_Error err; TT_Face tt_face; @@ -482,6 +530,7 @@ sfnt = (SFNT_Service)tt_face->sfnt; err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index); if ( err ) instance->strike_index=0xFFFFU; +#endif } /* maintain a linked list of instances */ @@ -799,31 +848,61 @@ * parse the htmx field in TrueType font. */ -/* from src/truetype/ttgload.c */ static void -tt_get_metrics( TT_HoriHeader* header, +tt_get_metrics( FT_Face face, FT_UInt idx, + FT_UInt num_hmetrics, FT_Short* bearing, FT_UShort* advance ) -/* Copyright 1996-2001, 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ { - TT_LongMetrics longs_m; - FT_UShort k = header->number_Of_HMetrics; + /* read the metrics directly from the horizontal header, we + * parse the SFNT table directly through the standard FreeType API. + * this works with any version of the library and doesn't need to + * peek at its internals. Maybe a bit less + */ + FT_UInt count = num_hmetrics; + FT_ULong length = 0; + FT_ULong offset = 0; + FT_Error error; - if ( k == 0 ) { - *bearing = *advance = 0; - return; - } + error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length ); - if ( idx < (FT_UInt)k ) { - longs_m = (TT_LongMetrics )header->long_metrics + idx; - *bearing = longs_m->bearing; - *advance = longs_m->advance; + if ( count == 0 || error ) + { + *advance = 0; + *bearing = 0; + } + else if ( idx < count ) + { + offset = idx * 4L; + if ( offset + 4 > length ) + { + *advance = 0; + *bearing = 0; + } + else + { + *advance = sfnt_get_ushort( face, TTAG_hmtx, offset ); + *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 ); + } + } + else + { + offset = 4L * (count - 1); + if ( offset + 4 > length ) + { + *advance = 0; + *bearing = 0; + } + else + { + *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset ); + offset += 4 + 2 * ( idx - count ); + if ( offset + 2 > length) + *bearing = 0; + else + *bearing = sfnt_get_short ( face, TTAG_hmtx, offset ); } - else { - *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k]; - *advance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance; } } @@ -831,6 +910,7 @@ ft_get_very_lazy_bbox( FT_UInt index, FT_Face face, FT_Size size, + FT_UInt num_hmetrics, double slant, FT_Matrix *matrix, FT_BBox *bbox, @@ -838,15 +918,14 @@ FT_Long *vertAdvance) { if ( FT_IS_SFNT( face ) ) { - TT_Face ttface = (TT_Face)face; FT_Size_Metrics *smetrics = &size->metrics; FT_Short leftBearing = 0; FT_UShort advance = 0; FT_Vector p0, p1, p2, p3; /* horizontal */ - tt_get_metrics(&ttface->horizontal, index, - &leftBearing, &advance); + tt_get_metrics( face, index, num_hmetrics, + &leftBearing, &advance ); #if 0 fprintf(stderr,"x_scale=%f y_scale=%f\n", @@ -903,8 +982,30 @@ static FT_Error FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index, - FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return ) + FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return, + int *sbitchk_incomplete_but_exist ) { +#if 1 + if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL ) + { + FT_Error error; + FT_Bitmap_Size* sz = &ft_face->available_sizes[strike_index]; + + error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 ); + if ( !error ) + { + error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY ); + if ( !error ) + { + if ( metrics_return != NULL ) + *metrics_return = ft_face->glyph->metrics; + + return 0; + } + } + } + return -1; +#elif (FREETYPE_VERSION >= 2001008) SFNT_Service sfnt; TT_Face face; FT_Error error; @@ -925,7 +1026,8 @@ face = (TT_Face)ft_face; sfnt = (SFNT_Service)face->sfnt; - if ( strike_index != 0xFFFFU && sfnt->load_sbits ) { + if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image && + sfnt->load_sbits) { /* Check whether there is a glyph sbit for the current index */ error = sfnt->find_sbit_image( face, glyph_index, strike_index, &range, &strike, &glyph_offset ); @@ -968,6 +1070,17 @@ Exit: return error; +#else /* if (FREETYPE_VERSION < 2001008) */ + TT_Face face; + SFNT_Service sfnt; + if ( ! FT_IS_SFNT( ft_face ) ) return -1; + face = (TT_Face)ft_face; + sfnt = (SFNT_Service)face->sfnt; + if ( strike_index != 0xFFFFU && sfnt->load_sbits ) { + if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1; + } + return -1; +#endif } int @@ -986,6 +1099,7 @@ int dx, dy; int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth, ascent, descent; + int sbitchk_incomplete_but_exist; double bbox_center_raw; face = instance->face; @@ -1014,15 +1128,17 @@ int new_width; double ratio; + sbitchk_incomplete_but_exist=0; if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) { if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index, - idx,&sbit_metrics)==0 ) { + idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) { bitmap_metrics = &sbit_metrics; } } if( bitmap_metrics == NULL ) { - if ( instance->ttcap.flags & TTCAP_IS_VERY_LAZY ) { + if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) { if( ft_get_very_lazy_bbox( idx, face->face, instance->size, + face->num_hmetrics, instance->ttcap.vl_slant, &instance->transformation.matrix, &bbox, &outline_hori_advance, @@ -1040,6 +1156,8 @@ } if( bitmap_metrics ) { + FT_Pos factor; + leftSideBearing = bitmap_metrics->horiBearingX / 64; rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64; bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0; @@ -1062,8 +1180,8 @@ rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic; leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic; /* */ - rawCharacterWidth = - (unsigned short)(short)(floor(1000 * bitmap_metrics->horiAdvance + factor = bitmap_metrics->horiAdvance; + rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor * instance->ttcap.scaleBBoxWidth * ratio / 64. / instance->pixel_size)); } @@ -1155,14 +1273,16 @@ else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1; else{ int sbit_available=0; + sbitchk_incomplete_but_exist=0; if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) { if( FT_Do_SBit_Metrics(face->face,instance->size, - instance->strike_index,idx,NULL)==0 ) { + instance->strike_index,idx,NULL, + &sbitchk_incomplete_but_exist)==0 ) { sbit_available=1; } } if( sbit_available == 0 ) { - if ( instance->ttcap.flags & TTCAP_IS_VERY_LAZY ) { + if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) { if( FT_IS_SFNT(face->face) ) correct=1; } } @@ -1183,10 +1303,27 @@ } if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) { +#ifdef USE_GET_CBOX + FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox); + ftrc = 0; +#else + ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox); +#endif + if( ftrc != 0 ) return FTtoXReturnCode(ftrc); + bbox.yMin = FLOOR64( bbox.yMin ); + bbox.yMax = CEIL64 ( bbox.yMax ); + ht_actual = ( bbox.yMax - bbox.yMin ) >> 6; + /* FreeType think a glyph with 0 height control box is invalid. + * So just let X to create a empty bitmap instead. */ + if ( ht_actual == 0 ) + is_outline = -1; + else + { ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO); if( ftrc != 0 ) return FTtoXReturnCode(ftrc); is_outline = 1; } + } else{ is_outline=0; } @@ -1197,6 +1334,7 @@ if( is_outline == 1 ){ if( correct ){ if( ft_get_very_lazy_bbox( idx, face->face, instance->size, + face->num_hmetrics, instance->ttcap.vl_slant, &instance->transformation.matrix, &bbox, &outline_hori_advance, --- XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.h.orig 2004-04-14 17:32:43.000000000 +0200 +++ XFree86-4.6.0/xc/lib/font/FreeType/ftfuncs.h 2006-07-19 08:17:53.774289000 +0200 @@ -47,6 +47,7 @@ char *filename; FT_Face face; int bitmap; + FT_UInt num_hmetrics; struct _FTInstance *instances; struct _FTInstance *active_instance; struct _FTFace *next; /* link to next face in bucket */ --- XFree86-4.6.0/xc/programs/fonttosfnt/util.c.orig 2005-02-07 02:01:16.000000000 +0100 +++ XFree86-4.6.0/xc/programs/fonttosfnt/util.c 2006-07-19 17:46:00.392569500 +0200 @@ -34,7 +34,6 @@ #include #include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H #include FT_BDF_H #include "X11/Xos.h" #include "fonttosfnt.h"