diff --git a/ChangeLog b/ChangeLog index 6c60e5fdd..da8d49172 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2006-01-23 Chia-I Wu + + * include/freetype/freetype.h (FT_Select_Size): Rename the second + argument from `idx' to `strike_index'. + (FT_Size_Request_Type): Add FT_SIZE_REQUEST_TYPE_MAX to the end of + this enum. + + * include/freetype/internal/ftobjs.h (FT_REQUEST_WIDTH, + FT_REQUEST_HEIGHT): New macros to get the width and height of a + request, in fractional pixels. + + * include/freetype/internal/ftobjs.h (FT_Select_Metrics, + FT_Request_Metrics), src/base/ftobjs.c (FT_Select_Metrics, + FT_Request_Metrics): New base functions to set the font metrics. They + were part of FT_Select_Size/FT_Request_Size and are made independent + functions so that metrics are not set again and again. + + * src/base/ftobjs.c (FT_Select_Size, FT_Request_Size): Metrics are set + only when driver's size_select/size_request is NULL. That is, drivers + should set the metrics themselves. + (FT_Match_Size): Round before matching. This was what we did and it + does cause some problems without rounding. + + * src/cff/cffobjs.c (cff_size_select), src/truetype/ttdriver.c + (tt_size_select): Set the font metrics. + s/index/strike_index/. + The scaled metrics are always preferred over strikes' metrics, even + when some strike is selected. This is done because the strikes' + metrics are not reliable, e.g., the sign of the descender is wrong for + some fonts. + + * src/cff/cffobjs.c (cff_size_request), src/truetype/ttdriver.c + (tt_size_request): Set the font metrics. + Call cff_size_select/tt_size_select when some strike is matched. + + * src/bdf/bdfdrivr.c, src/cff/cffobjs.c, src/cid/cidobjs.c, + src/pcf/pcfdrivr.c, src/truetype/ttdriver.c, src/type1/t1objs.c, + src/type1/t1objs.h, src/type42/t42objs.c, src/winfonts/winfnt.c: + Set the font metrics. + s/index/strike_index/. + + * src/tools/test_afm.c, src/psaux/psconv.c: Older versions of these + files were committed. Just a catch-up. + (PS_Conv_ToFixed): Remove the `goto'. + (PS_Conv_ASCIIHexDecode, PS_Conv_EexecDecode): Speed up a little. + + * src/sfnt/ttsbit.c (tt_face_load_sbit_strikes, + tt_face_load_strike_metrics), src/sfnt/ttsbit0.c + (tt_face_load_sbit_strikes, tt_face_load_strike_metrics): The + advertised metrics in `available_sizes' are different from those + actually used. + 2006-01-23 Chia-I Wu * src/psaux/psaux.c src/psaux/psauxmod.c src/type1/t1driver.c: Make diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 736987ee0..a079c8ca7 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -1975,18 +1975,18 @@ FT_BEGIN_HEADER /* Select a bitmap strike. */ /* */ /* */ - /* face :: A handle to a target face object. */ + /* face :: A handle to a target face object. */ /* */ /* */ - /* idx :: The index of the bitmap strike in the `available_sizes' */ - /* field of @FT_FaceRec structure. */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ /* */ /* */ /* FreeType error code. 0 means success. */ /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, - FT_Int idx ); + FT_Int strike_index ); /*************************************************************************/ @@ -2032,7 +2032,9 @@ FT_BEGIN_HEADER FT_SIZE_REQUEST_TYPE_NOMINAL, FT_SIZE_REQUEST_TYPE_REAL_DIM, FT_SIZE_REQUEST_TYPE_BBOX, - FT_SIZE_REQUEST_TYPE_CELL + FT_SIZE_REQUEST_TYPE_CELL, + + FT_SIZE_REQUEST_TYPE_MAX } FT_Size_Request_Type; diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index c78073261..8b5e08942 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -451,6 +451,28 @@ FT_BEGIN_HEADER /* */ +#define FT_REQUEST_WIDTH( req ) \ + ( ( req )->horiResolution \ + ? (FT_Pos)( ( req )->width * ( req )->horiResolution + 36 ) / 72 \ + : ( req )->width ) + +#define FT_REQUEST_HEIGHT( req ) \ + ( ( req )->vertResolution \ + ? (FT_Pos)( ( req )->height * ( req )->vertResolution + 36 ) / 72 \ + : ( req )->height ) + + /* set the metrics according to a bitmap strike */ + FT_BASE( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ); + + + /* set the metrics according to a size request */ + FT_BASE( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ); + + /* * Match a size request against `available_sizes'. */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 5ee4710b2..5702996c8 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -2006,28 +2006,26 @@ if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) return FT_Err_Unimplemented_Feature; - if ( req->horiResolution ) - w = ( req->width * req->horiResolution + 36 ) / 72; - else - w = req->width; - - if ( req->vertResolution ) - h = ( req->height * req->vertResolution + 36 ) / 72; - else - h = req->height; + w = FT_REQUEST_WIDTH( req ); + h = FT_REQUEST_HEIGHT( req ); if ( req->width && !req->height ) h = w; else if ( !req->width && req->height ) w = h; + w = FT_PIX_ROUND( w ); + h = FT_PIX_ROUND( h ); + for ( i = 0; i < face->num_fixed_sizes; i++ ) { - if ( h != face->available_sizes[i].y_ppem ) + FT_Bitmap_Size* bsize = face->available_sizes + i; + + + if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) continue; - if ( w == face->available_sizes[i].x_ppem || - ignore_width ) + if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) { if ( index ) *index = (FT_ULong)i; @@ -2076,27 +2074,16 @@ } - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Select_Size( FT_Face face, - FT_Int index ) + FT_BASE_DEF( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ) { - FT_Driver_Class clazz; FT_Size_Metrics* metrics; FT_Bitmap_Size* bsize; - if ( !face || !FT_HAS_FIXED_SIZES( face ) ) - return FT_Err_Invalid_Face_Handle; - - if ( index < 0 || index >= face->num_fixed_sizes ) - return FT_Err_Invalid_Argument; - - clazz = face->driver->clazz; metrics = &face->size->metrics; - - bsize = face->available_sizes + index; + bsize = face->available_sizes + strike_index; metrics->x_ppem = ( bsize->x_ppem + 32 ) >> 6; metrics->y_ppem = ( bsize->y_ppem + 32 ) >> 6; @@ -2119,32 +2106,17 @@ metrics->height = bsize->height << 6; metrics->max_advance = bsize->x_ppem; } - - if ( clazz->select_size ) - return clazz->select_size( face->size, (FT_ULong)index ); - else - return FT_Err_Ok; } - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Request_Size( FT_Face face, - FT_Size_Request req ) + FT_BASE_DEF( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ) { FT_Driver_Class clazz; FT_Size_Metrics* metrics; - FT_Error error; - FT_Bool bitmap_only = 0; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !req || req->width < 0 || req->height < 0 ) - return FT_Err_Invalid_Argument; - clazz = face->driver->clazz; metrics = &face->size->metrics; @@ -2174,25 +2146,20 @@ break; default: - return FT_Err_Unimplemented_Feature; + /* this never happens */ + return; break; } + /* to be on the safe side */ if ( w < 0 ) w = -w; if ( h < 0 ) h = -h; - if ( req->horiResolution ) - scaled_w = ( req->width * req->horiResolution + 36 ) / 72; - else - scaled_w = req->width; - - if ( req->vertResolution ) - scaled_h = ( req->height * req->vertResolution + 36 ) / 72; - else - scaled_h = req->height; + scaled_w = FT_REQUEST_WIDTH( req ); + scaled_h = FT_REQUEST_HEIGHT( req ); /* determine scales */ if ( req->width ) @@ -2223,7 +2190,7 @@ scaled_w = FT_MulDiv( scaled_h, w, h ); } - /* calculate ppem */ + /* calculate the ppems */ if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) { scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); @@ -2234,23 +2201,64 @@ metrics->y_ppem = ( scaled_h + 32 ) >> 6; ft_recompute_scaled_metrics( face, metrics ); - - error = FT_Err_Ok; } else { FT_ZERO( metrics ); metrics->x_scale = 1L << 22; metrics->y_scale = 1L << 22; - - if ( FT_HAS_FIXED_SIZES( face ) ) - bitmap_only = 1; - - error = FT_Err_Invalid_Pixel_Size; } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ) + { + FT_Driver_Class clazz; + + + if ( !face || !FT_HAS_FIXED_SIZES( face ) ) + return FT_Err_Invalid_Face_Handle; + + if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) + return FT_Err_Invalid_Argument; + + clazz = face->driver->clazz; + + if ( clazz->select_size ) + return clazz->select_size( face->size, (FT_ULong)strike_index ); + + FT_Select_Metrics( face, (FT_ULong)strike_index ); + + return FT_Err_Ok; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ) + { + FT_Driver_Class clazz; + FT_ULong strike_index; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !req || req->width < 0 || req->height < 0 || + req->type >= FT_SIZE_REQUEST_TYPE_MAX ) + return FT_Err_Invalid_Argument; + + clazz = face->driver->clazz; if ( clazz->request_size ) - error = clazz->request_size( face->size, req ); + return clazz->request_size( face->size, req ); + /* * The reason that a driver doesn't have `request_size' defined is * either that the scaling here suffices or that the supported formats @@ -2258,20 +2266,23 @@ * * In the latter case, a simple size matching is done. */ - else if ( bitmap_only ) + if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) { - FT_ULong index; + FT_Error error; - if ( !FT_Match_Size( face, req, 0, &index ) ) - { - FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n", index )); + error = FT_Match_Size( face, req, 0, &strike_index ); + if ( error ) + return error; - error = FT_Select_Size( face, index ); - } + FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n", strike_index )); + + return FT_Select_Size( face, (FT_Int)strike_index ); } - return error; + FT_Request_Metrics( face, req ); + + return FT_Err_Ok; } diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 7611e9aa7..dcb16c967 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -583,17 +583,15 @@ THE SOFTWARE. FT_CALLBACK_DEF( FT_Error ) BDF_Size_Select( FT_Size size, - FT_ULong index ) + FT_ULong strike_index ) { bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont; - FT_UNUSED( index ); + FT_Select_Metrics( size->face, strike_index ); size->metrics.ascender = bdffont->font_ascent << 6; size->metrics.descender = -bdffont->font_descent << 6; - size->metrics.height = ( bdffont->font_ascent + - bdffont->font_descent ) << 6; size->metrics.max_advance = bdffont->bbx.width << 6; return BDF_Err_Ok; @@ -611,11 +609,7 @@ THE SOFTWARE. FT_Long height; - if ( req->vertResolution ) - height = ( req->height * req->vertResolution + 36 ) / 72; - else - height = req->height; - + height = FT_REQUEST_HEIGHT( req ); height = ( height + 32 ) >> 6; switch ( req->type ) diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index 504f098cd..2f28b1755 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -165,38 +165,19 @@ } +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + FT_LOCAL_DEF( FT_Error ) - cff_size_request( FT_Size size, - FT_Size_Request req ) + cff_size_select( FT_Size size, + FT_ULong strike_index ) { CFF_Size cffsize = (CFF_Size)size; PSH_Globals_Funcs funcs; -#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - FT_UNUSED( req ); - -#else + cffsize->strike_index = strike_index; - if ( FT_HAS_FIXED_SIZES( size->face ) ) - { - CFF_Face cffface = (CFF_Face)size->face; - SFNT_Service sfnt = cffface->sfnt; - FT_Size_Metrics* metrics = &size->metrics; - FT_ULong index; - FT_Error error; - - - if ( !( error = sfnt->set_sbit_strike( - cffface, req, &index ) ) && - !( error = sfnt->load_strike_metrics( - cffface, index, metrics ) ) ) - cffsize->strike_index = index; - else - cffsize->strike_index = 0xFFFFFFFFUL; - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + FT_Select_Metrics( size->face, strike_index ); funcs = cff_size_get_globals_funcs( cffsize ); @@ -209,21 +190,35 @@ return CFF_Err_Ok; } +#endif + + + FT_LOCAL_DEF( FT_Error ) + cff_size_request( FT_Size size, + FT_Size_Request req ) + { + CFF_Size cffsize = (CFF_Size)size; + PSH_Globals_Funcs funcs; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - FT_LOCAL_DEF( FT_Error ) - cff_size_select( FT_Size size, - FT_ULong index ) - { - CFF_Face cffface = (CFF_Face)size->face; - CFF_Size cffsize = (CFF_Size)size; - FT_Size_Metrics* metrics = &size->metrics; - SFNT_Interface* sfnt = cffface->sfnt; - FT_Error error; - PSH_Globals_Funcs funcs; + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + CFF_Face cffface = (CFF_Face)size->face; + SFNT_Service sfnt = cffface->sfnt; + FT_ULong index; + if ( sfnt->set_sbit_strike( cffface, req, &index ) ) + cffsize->strike_index = 0xFFFFFFFFUL; + else + return cff_size_select( size, index ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + FT_Request_Metrics( size->face, req ); + funcs = cff_size_get_globals_funcs( cffsize ); if ( funcs ) @@ -232,17 +227,9 @@ size->metrics.y_scale, 0, 0 ); - error = sfnt->load_strike_metrics( cffface, index, metrics ); - if ( error ) - cffsize->strike_index = 0xFFFFFFFFUL; - else - cffsize->strike_index = index; - - return error; + return CFF_Err_Ok; } -#endif - /*************************************************************************/ /* */ diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index 20ca1e098..d6b0a2d3a 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -158,8 +158,8 @@ { PSH_Globals_Funcs funcs; - FT_UNUSED( req ); + FT_Request_Metrics( size->face, req ); funcs = cid_size_get_globals_funcs( (CID_Size)size ); diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index c0fe2304f..3aaeb477d 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -364,22 +364,16 @@ THE SOFTWARE. FT_CALLBACK_DEF( FT_Error ) PCF_Size_Select( FT_Size size, - FT_ULong index ) + FT_ULong strike_index ) { - PCF_Face face = (PCF_Face)size->face; - - FT_UNUSED( index ); + PCF_Accel accel = &( (PCF_Face)size->face )->accel; - size->metrics.ascender = face->accel.fontAscent << 6; - size->metrics.descender = -face->accel.fontDescent << 6; -#if 0 - size->metrics.height = face->accel.maxbounds.ascent << 6; -#else - size->metrics.height = size->metrics.ascender - - size->metrics.descender; -#endif - size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6; + FT_Select_Metrics( size->face, strike_index ); + + size->metrics.ascender = accel->fontAscent << 6; + size->metrics.descender = -accel->fontDescent << 6; + size->metrics.max_advance = accel->maxbounds.characterWidth << 6; return PCF_Err_Ok; } @@ -389,17 +383,13 @@ THE SOFTWARE. PCF_Size_Request( FT_Size size, FT_Size_Request req ) { - PCF_Face face = (PCF_Face)size->face; - FT_Bitmap_Size* bsize = size->face->available_sizes; - FT_Error error = PCF_Err_Invalid_Pixel_Size; + PCF_Face face = (PCF_Face)size->face; + FT_Bitmap_Size* bsize = size->face->available_sizes; + FT_Error error = PCF_Err_Invalid_Pixel_Size; FT_Long height; - if ( req->vertResolution ) - height = ( req->height * req->vertResolution + 36 ) / 72; - else - height = req->height; - + height = FT_REQUEST_HEIGHT( req ); height = ( height + 32 ) >> 6; switch ( req->type ) diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index 2c798e21b..e775b1abf 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -1101,6 +1101,9 @@ THE SOFTWARE. FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); +#if 0 + bsize->height = face->accel.maxbounds.ascent << 6; +#endif bsize->height = (FT_Short)( face->accel.fontAscent + face->accel.fontDescent ); diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c index e5c6269ed..6cdcb27c9 100644 --- a/src/psaux/psconv.c +++ b/src/psaux/psconv.c @@ -164,17 +164,12 @@ } if ( *p != '.' ) - { integral = PS_Conv_ToInt( &p, limit ) << 16; - - if ( p == limit ) - goto Exit; - } else integral = 0; /* read the decimal part */ - if ( *p == '.' ) + if ( p < limit && *p == '.' ) { p++; @@ -206,7 +201,6 @@ power_ten += PS_Conv_ToInt( &p, limit ); } - Exit: while ( power_ten > 0 ) { integral *= 10; @@ -339,7 +333,8 @@ FT_UInt r = 0; - for ( p = *cursor; r < 2 * n && p < limit; p++ ) + n *= 2; + for ( p = *cursor; r < n && p < limit; p++ ) { char c; @@ -376,20 +371,22 @@ FT_UInt n, FT_UShort* seed ) { - FT_Byte* p; - FT_UInt r; + FT_Byte* p; + FT_UInt r; + FT_UShort s = *seed; for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ ) { - FT_Byte b = ( *p ^ ( *seed >> 8 ) ); + FT_Byte b = ( *p ^ ( s >> 8 ) ); - *seed = (FT_UShort)( ( *p + *seed ) * 52845U + 22719 ); + s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); *buffer++ = b; } *cursor = p; + *seed = s; return r; } diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index 4589160a8..56b5f45a5 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -599,18 +599,17 @@ FT_Bitmap_Size* bsize = root->available_sizes + n; TT_SBit_Strike strike = face->sbit_strikes + n; FT_UShort fupem = face->header.Units_Per_EM; - FT_Short height = (FT_Short)( face->horizontal.Ascender - - face->horizontal.Descender + - face->horizontal.Line_Gap ); FT_Short avg = face->os2.xAvgCharWidth; - /* assume 72dpi */ - bsize->height = - (FT_Short)( ( height * strike->y_ppem + fupem / 2 ) / fupem ); + /* XXX: Is this correct? */ + bsize->height = strike->hori.ascender - strike->hori.descender; bsize->width = (FT_Short)( ( avg * strike->y_ppem + fupem / 2 ) / fupem ); + + /* assume 72dpi */ bsize->size = strike->y_ppem << 6; + bsize->x_ppem = strike->x_ppem << 6; bsize->y_ppem = strike->y_ppem << 6; } @@ -692,6 +691,8 @@ strike = face->sbit_strikes + strike_index; + metrics->x_ppem = strike->x_ppem; + metrics->y_ppem = strike->y_ppem; metrics->ascender = strike->hori.ascender << 6; metrics->descender = strike->hori.descender << 6; @@ -701,7 +702,6 @@ strike->hori.max_width + strike->hori.min_advance_SB ) << 6; - /* XXX: Is this correct? */ metrics->height = metrics->ascender - metrics->descender; return SFNT_Err_Ok; diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index 78b55c822..ce0e6c612 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -148,12 +148,8 @@ * depths in the FT_Bitmap_Size record. This is a design error. */ { - FT_Memory memory = face->root.stream->memory; - FT_UInt em_size = (FT_UInt) face->header.Units_Per_EM; - FT_Short height = (FT_Short)( face->horizontal.Ascender - - face->horizontal.Descender + - face->horizontal.Line_Gap ); - + FT_Memory memory = face->root.stream->memory; + FT_UInt em_size = (FT_UInt)face->header.Units_Per_EM; FT_Short avgwidth = face->os2.xAvgCharWidth; @@ -164,16 +160,22 @@ { FT_Bitmap_Size* bsize = face->root.available_sizes + nn; FT_UInt x_ppem, y_ppem; + FT_Char ascender, descender; - x_ppem = p[44]; - y_ppem = p[45]; + ascender = (FT_Char)p[16]; + descender = (FT_Char)p[17]; + x_ppem = p[44]; + y_ppem = p[45]; bsize->x_ppem = (FT_Pos)(x_ppem << 6); bsize->y_ppem = (FT_Pos)(y_ppem << 6); - bsize->height = (FT_Short)( height*y_ppem + em_size / 2 ) / em_size; - bsize->width = (FT_Short)( avgwidth*y_ppem + em_size / 2 ) / em_size; + /* XXX: Is this correct? */ + bsize->height = ascender - descender; + bsize->width = (FT_Short)( avgwidth * y_ppem + em_size / 2 ) / em_size; + + /* assume 72dpi */ bsize->size = bsize->y_ppem; p += 48; @@ -219,18 +221,20 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - FT_Byte* strike; + FT_Bitmap_Size* bsize; + FT_Byte* strike; -#ifdef FT_OPTIMIZE_MEMORY + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) return SFNT_Err_Invalid_Argument; -#else - if ( strike_index >= (FT_ULong)face->num_sbit_strikes ) - return SFNT_Err_Invalid_Argument; -#endif + bsize = ( (FT_Face)face )->available_sizes + strike_index; strike = face->sbit_table + 8 + strike_index * 48; + metrics->x_ppem = bsize->x_ppem >> 6; + metrics->y_ppem = bsize->y_ppem >> 6; + metrics->height = bsize->height << 6; + metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ @@ -240,9 +244,6 @@ (FT_Char)strike[23] /* min_advance_SB */ ) << 6; - /* XXX: Is this correct? */ - metrics->height = metrics->ascender - metrics->descender; - return SFNT_Err_Ok; } diff --git a/src/tools/test_afm.c b/src/tools/test_afm.c index d82f454ae..005644251 100644 --- a/src/tools/test_afm.c +++ b/src/tools/test_afm.c @@ -1,3 +1,7 @@ +/* + * gcc -I../../include -o test_afm test_afm.c \ + * -L../../objs/.libs -lfreetype -lz -static + */ #include #include FT_FREETYPE_H #include FT_INTERNAL_STREAM_H @@ -31,7 +35,7 @@ printf( "\n" ); - if ( fi->NumTrackKern ) + if ( fi->NumKernPair ) printf( "There are %d kerning pairs:\n", fi->NumKernPair ); else diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 580804f0a..d125a42f8 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -134,6 +134,43 @@ /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + tt_size_select( FT_Size size, + FT_ULong strike_index ) + { + TT_Face ttface = (TT_Face)size->face; + TT_Size ttsize = (TT_Size)size; + FT_Error error = TT_Err_Ok; + + + ttsize->strike_index = strike_index; + + if ( FT_IS_SCALABLE( size->face ) ) + { + /* use the scaled metrics, even when tt_size_reset fails */ + FT_Select_Metrics( size->face, strike_index ); + + tt_size_reset( ttsize ); + } + else + { + SFNT_Service sfnt = ttface->sfnt; + FT_Size_Metrics* metrics = &size->metrics; + + + error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); + if ( error ) + ttsize->strike_index = 0xFFFFFFFFUL; + } + + return error; + } + +#endif + + static FT_Error tt_size_request( FT_Size size, FT_Size_Request req ) @@ -142,30 +179,27 @@ TT_Size ttsize = (TT_Size)size; FT_Error error = TT_Err_Ok; -#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - FT_UNUSED( req ); - -#else +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS if ( FT_HAS_FIXED_SIZES( size->face ) ) { - SFNT_Service sfnt = ttface->sfnt; - FT_Size_Metrics* metrics = &size->metrics; - FT_ULong index; + SFNT_Service sfnt = ttface->sfnt; + FT_ULong index; - if ( !( error = sfnt->set_sbit_strike( - ttface, req, &index ) ) && - !( error = sfnt->load_strike_metrics( - ttface, index, metrics ) ) ) - ttsize->strike_index = index; - else + error = sfnt->set_sbit_strike( ttface, req, &index ); + + if ( error ) ttsize->strike_index = 0xFFFFFFFFUL; + else + return tt_size_select( size, index ); } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + FT_Request_Metrics( size->face, req ); + if ( FT_IS_SCALABLE( size->face ) ) error = tt_size_reset( ttsize ); @@ -173,34 +207,6 @@ } -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - static FT_Error - tt_size_select( FT_Size size, - FT_ULong index ) - { - TT_Face ttface = (TT_Face)size->face; - TT_Size ttsize = (TT_Size)size; - FT_Size_Metrics* metrics = &size->metrics; - SFNT_Service sfnt = ttface->sfnt; - FT_Error error; - - - if ( FT_IS_SCALABLE( size->face ) ) - tt_size_reset( ttsize ); - - error = sfnt->load_strike_metrics( ttface, index, metrics ); - if ( error ) - ttsize->strike_index = 0xFFFFFFFFUL; - else - ttsize->strike_index = index; - - return error; - } - -#endif - - /*************************************************************************/ /* */ /* */ diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index 642654a3b..ae715f51a 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -111,10 +111,13 @@ FT_LOCAL_DEF( FT_Error ) - T1_Size_Request( T1_Size size ) + T1_Size_Request( T1_Size size, + FT_Size_Request req ) { PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); - + + + FT_Request_Metrics( size->root.face, req ); if ( funcs ) funcs->set_scale( (PSH_Globals)size->root.internal, diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h index 6449e1e87..ba258d267 100644 --- a/src/type1/t1objs.h +++ b/src/type1/t1objs.h @@ -109,7 +109,8 @@ FT_BEGIN_HEADER T1_Size_Done( T1_Size size ); FT_LOCAL( FT_Error ) - T1_Size_Request( T1_Size size ); + T1_Size_Request( T1_Size size, + FT_Size_Request req ); FT_LOCAL( FT_Error ) T1_Size_Init( T1_Size size ); diff --git a/src/type42/t42objs.c b/src/type42/t42objs.c index c9d0fc83a..a67f85875 100644 --- a/src/type42/t42objs.c +++ b/src/type42/t42objs.c @@ -494,24 +494,35 @@ FT_Size_Request req ) { T42_Face face = (T42_Face)size->root.face; + FT_Error error; FT_Activate_Size( size->ttsize ); - return FT_Request_Size( face->ttf_face, req ); + error = FT_Request_Size( face->ttf_face, req ); + if ( !error ) + ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; + + return error; } FT_LOCAL_DEF( FT_Error ) T42_Size_Select( T42_Size size, - FT_ULong index ) + FT_ULong strike_index ) { T42_Face face = (T42_Face)size->root.face; + FT_Error error; FT_Activate_Size( size->ttsize ); - return FT_Select_Size( face->ttf_face, index ); + error = FT_Select_Size( face->ttf_face, strike_index ); + if ( !error ) + ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; + + return error; + } diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index eabf94639..8f74300da 100644 --- a/src/winfonts/winfnt.c +++ b/src/winfonts/winfnt.c @@ -574,15 +574,15 @@ static FT_Error FNT_Size_Select( FT_Size size ) { - FNT_Face face = (FNT_Face)size->face; - FT_WinFNT_Header header = &face->font->header; + FNT_Face face = (FNT_Face)size->face; + FT_WinFNT_Header header = &face->font->header; + FT_Select_Metrics( size->face, 0 ); + size->metrics.ascender = header->ascent * 64; size->metrics.descender = -( header->pixel_height - header->ascent ) * 64; - size->metrics.height = ( header->pixel_height + - header->external_leading ) * 64; size->metrics.max_advance = header->max_width * 64; return FNT_Err_Ok; @@ -600,11 +600,7 @@ FT_Long height; - if ( req->vertResolution ) - height = ( req->height * req->vertResolution + 36 ) / 72; - else - height = req->height; - + height = FT_REQUEST_HEIGHT( req ); height = ( height + 32 ) >> 6; switch ( req->type )