diff --git a/ChangeLog b/ChangeLog index ec5d202a7..7e3f632d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-05-19 George Williams + + * src/type1/t1load.c (mm_axis_unmap, mm_weights_unmap): New + auxiliary functions. + (T1_Get_MM_Var): Provide axis tags. + Use mm_axis_unmap and mm_weights_unmap to provide default values + for design and normalized axis coordinates. + + * include/freetype/t1tables.h (PS_DesignMapRec): Change type of + `design_points' to FT_Long. + Update all users. + 2004-05-17 Werner Lemberg * src/base/ftbbox.c (BBox_Conic_Check): Fix boundary cases. diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h index 9aa6d8247..525b5c08e 100644 --- a/include/freetype/ftmm.h +++ b/include/freetype/ftmm.h @@ -125,12 +125,13 @@ FT_BEGIN_HEADER /* minimum :: The axis's minimum design coordinate. */ /* */ /* def :: The axis's default design coordinate. */ - /* Not meaningful for MM. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ /* */ /* maximum :: The axis's maximum design coordinate. */ /* */ /* tag :: The axis's tag (the GX equivalent to `name'). */ - /* Not meaningful for MM. */ + /* FreeType provides default values for MM if possible. */ /* */ /* strid :: The entry in `name' table (another GX version of */ /* `name'). */ diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h index 1b89c5f51..60938aa83 100644 --- a/include/freetype/t1tables.h +++ b/include/freetype/t1tables.h @@ -226,7 +226,7 @@ FT_BEGIN_HEADER typedef struct PS_DesignMap_ { FT_Byte num_points; - FT_Fixed* design_points; + FT_Long* design_points; FT_Fixed* blend_points; } PS_DesignMapRec, *PS_DesignMap; diff --git a/src/type1/t1load.c b/src/type1/t1load.c index b5b052239..7ec163ad5 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -215,6 +215,85 @@ #define FT_FIXED_TO_INT( a ) ( FT_RoundFix( a ) >> 16 ) + /*************************************************************************/ + /* */ + /* Given a normalized (blend) coordinate, figure out the design */ + /* coordinate appropriate for that value. */ + /* */ + FT_LOCAL_DEF( FT_Fixed ) + mm_axis_unmap( PS_DesignMap axismap, + FT_Fixed ncv ) + { + int j; + + + if ( ncv <= axismap->blend_points[0] ) + return axismap->design_points[0]; + + for ( j = 1; j < axismap->num_points; ++j ) + { + if ( ncv <= axismap->blend_points[j] ) + { + FT_Fixed t = FT_MulDiv( ncv - axismap->blend_points[j - 1], + 0x10000L, + axismap->blend_points[j] - + axismap->blend_points[j - 1] ); + + + return axismap->design_points[j - 1] + + FT_MulDiv( t, + axismap->design_points[j] - + axismap->design_points[j - 1], + 1L ); + } + } + + return axismap->design_points[axismap->num_points - 1]; + } + + + /*************************************************************************/ + /* */ + /* Given a vector of weights, one for each design, figure out the */ + /* normalized axis coordinates which gave rise to those weights. */ + /* */ + FT_LOCAL_DEF( void ) + mm_weights_unmap( FT_Fixed* weights, + FT_Fixed* axiscoords, + FT_UInt axis_count ) + { + FT_ASSERT( axis_count <= T1_MAX_MM_AXIS ); + + if ( axis_count == 1 ) + axiscoords[0] = weights[1]; + + else if ( axis_count == 2 ) + { + axiscoords[0] = weights[3] + weights[1]; + axiscoords[1] = weights[3] + weights[2]; + } + + else if ( axis_count == 3 ) + { + axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4]; + } + + else + { + axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] + + weights[7] + weights[5] + weights[3] + weights[1]; + axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] + + weights[7] + weights[6] + weights[3] + weights[2]; + axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[7] + weights[6] + weights[5] + weights[4]; + axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] + + weights[11] + weights[10] + weights[9] + weights[8]; + } + } + + /*************************************************************************/ /* */ /* Just a wrapper around T1_Get_Multi_Master to support the different */ @@ -229,6 +308,8 @@ FT_Multi_Master mmaster; FT_Error error; FT_UInt i; + FT_Fixed axiscoords[T1_MAX_MM_AXIS]; + PS_Blend blend = face->blend; error = T1_Get_Multi_Master( face, &mmaster ); @@ -254,8 +335,26 @@ mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ - mmvar->axis[i].tag = 0xFFFFFFFFLU; /* Does not apply */ mmvar->axis[i].strid = 0xFFFFFFFFLU; /* Does not apply */ + mmvar->axis[i].tag = 0xFFFFFFFFLU; /* Does not apply */ + + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); + else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' ); + else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 ) + mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' ); + } + + if ( blend->num_designs == 1U << blend->num_axis ) + { + mm_weights_unmap( blend->default_weight_vector, + axiscoords, + blend->num_axis ); + + for ( i = 0; i < mmaster.num_axis; ++i ) + mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], + axiscoords[i] ); } *master = mmvar; @@ -334,14 +433,14 @@ FT_Long design = coords[n]; FT_Fixed the_blend; PS_DesignMap map = blend->design_map + n; - FT_Fixed* designs = map->design_points; + FT_Long* designs = map->design_points; FT_Fixed* blends = map->blend_points; FT_Int before = -1, after = -1; for ( p = 0; p < (FT_UInt)map->num_points; p++ ) { - FT_Fixed p_design = designs[p]; + FT_Long p_design = designs[p]; /* exact match? */