From bcc438b15ef0b22055ae6f4ed55e0981794f483a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wu=2C=20Chia-I=20=28=E5=90=B3=E4=BD=B3=E4=B8=80=29?= Date: Mon, 23 Jan 2006 14:12:40 +0000 Subject: [PATCH] * 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. --- ChangeLog | 52 ++++++++++ include/freetype/freetype.h | 12 ++- include/freetype/internal/ftobjs.h | 22 +++++ src/base/ftobjs.c | 153 ++++++++++++++++------------- src/bdf/bdfdrivr.c | 12 +-- src/cff/cffobjs.c | 69 ++++++------- src/cid/cidobjs.c | 2 +- src/pcf/pcfdrivr.c | 30 ++---- src/pcf/pcfread.c | 3 + src/psaux/psconv.c | 21 ++-- src/sfnt/ttsbit.c | 14 +-- src/sfnt/ttsbit0.c | 39 ++++---- src/tools/test_afm.c | 6 +- src/truetype/ttdriver.c | 76 +++++++------- src/type1/t1objs.c | 7 +- src/type1/t1objs.h | 3 +- src/type42/t42objs.c | 17 +++- src/winfonts/winfnt.c | 14 +-- 18 files changed, 316 insertions(+), 236 deletions(-) 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,31 +2106,16 @@ 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 - - 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; - } + cffsize->strike_index = strike_index; -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + FT_Select_Metrics( size->face, strike_index ); funcs = cff_size_get_globals_funcs( cffsize ); @@ -209,20 +190,34 @@ return CFF_Err_Ok; } +#endif -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS FT_LOCAL_DEF( FT_Error ) - cff_size_select( FT_Size size, - FT_ULong index ) + cff_size_request( FT_Size size, + FT_Size_Request req ) { - 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; +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + 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 ); @@ -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; + PCF_Accel accel = &( (PCF_Face)size->face )->accel; - FT_UNUSED( index ); + FT_Select_Metrics( size->face, strike_index ); - 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; + 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,72 +134,78 @@ /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + static FT_Error - tt_size_request( FT_Size size, - FT_Size_Request req ) + 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; -#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - FT_UNUSED( req ); + ttsize->strike_index = strike_index; -#else + if ( FT_IS_SCALABLE( size->face ) ) + { + /* use the scaled metrics, even when tt_size_reset fails */ + FT_Select_Metrics( size->face, strike_index ); - if ( FT_HAS_FIXED_SIZES( size->face ) ) + tt_size_reset( ttsize ); + } + else { SFNT_Service sfnt = ttface->sfnt; FT_Size_Metrics* metrics = &size->metrics; - 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->load_strike_metrics( ttface, strike_index, metrics ); + if ( error ) ttsize->strike_index = 0xFFFFFFFFUL; } -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - if ( FT_IS_SCALABLE( size->face ) ) - error = tt_size_reset( ttsize ); - return error; } +#endif -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS static FT_Error - tt_size_select( FT_Size size, - FT_ULong index ) + tt_size_request( FT_Size size, + FT_Size_Request req ) { - 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; + TT_Face ttface = (TT_Face)size->face; + TT_Size ttsize = (TT_Size)size; + FT_Error error = TT_Err_Ok; - if ( FT_IS_SCALABLE( size->face ) ) - tt_size_reset( ttsize ); +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - error = sfnt->load_strike_metrics( ttface, index, metrics ); - if ( error ) - ttsize->strike_index = 0xFFFFFFFFUL; - else - ttsize->strike_index = index; + if ( FT_HAS_FIXED_SIZES( size->face ) ) + { + SFNT_Service sfnt = ttface->sfnt; + FT_ULong index; + + + 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 ); 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 )