diff --git a/ChangeLog b/ChangeLog index 43ef3fbd9..6fb4fc932 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2017-03-12 Werner Lemberg + + [truetype] Store and use design coordinates also. + + * include/freetype/internal/services/svmm.h (FT_Get_Var_Blend_Func): + Add `normalizedcoords' argument. + + * src/truetype/ttgxvar.h (GX_BlendRec): Add `coords' field to store + the design coordinates of the current instance. + Updated. + + * src/truetype/ttgxvar.c (TT_Set_MM_Blend): Move functionality to... + (tt_set_mm_blend): ... New function. + Convert data in `normalizedcoords' array to `coords' array on + demand. + (TT_Set_Var_Design): Store argument data in `coords' array. + (TT_Get_Var_Design): Get data from `coords' array. + (tt_get_var_blend): Updated. + (tt_done_blend): Updated. + + * src/cff/cffload.c, src/cff/cffload.h (cff_get_var_blend): Updated. + + * src/cff/cf2ft.c (cf2_getNormalizedVector): Updated. + + * src/cff/cffobjs.c (cff_face_init): Updated. + 2017-03-12 Werner Lemberg src/truetype/ttgxvar.[ch]: s/avar_checked/avar_loaded/. diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h index 97af1ac98..1d51cd909 100644 --- a/include/freetype/internal/services/svmm.h +++ b/include/freetype/internal/services/svmm.h @@ -72,6 +72,7 @@ FT_BEGIN_HEADER (*FT_Get_Var_Blend_Func)( FT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); typedef void diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c index 5cca92a11..eb8472f11 100644 --- a/src/cff/cf2ft.c +++ b/src/cff/cf2ft.c @@ -457,7 +457,7 @@ FT_ASSERT( decoder && decoder->builder.face ); FT_ASSERT( vec && len ); - return cff_get_var_blend( decoder->builder.face, len, vec, NULL ); + return cff_get_var_blend( decoder->builder.face, len, NULL, vec, NULL ); } #endif diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 47626a714..d356ab361 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -1572,12 +1572,17 @@ cff_get_var_blend( CFF_Face face, FT_UInt *num_coords, FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ) { FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; - return mm->get_var_blend( FT_FACE( face ), num_coords, coords, mm_var ); + return mm->get_var_blend( FT_FACE( face ), + num_coords, + coords, + normalizedcoords, + mm_var ); } diff --git a/src/cff/cffload.h b/src/cff/cffload.h index 1709a661e..c745e8127 100644 --- a/src/cff/cffload.h +++ b/src/cff/cffload.h @@ -112,6 +112,7 @@ FT_BEGIN_HEADER cff_get_var_blend( CFF_Face face, FT_UInt *num_coords, FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); FT_LOCAL( void ) diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index bcda2a913..832276143 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -703,7 +703,7 @@ if ( error ) goto Exit; - mm->get_var_blend( cffface, NULL, NULL, &mm_var ); + mm->get_var_blend( cffface, NULL, NULL, NULL, &mm_var ); if ( mm_var->namedstyle ) { diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 641d07c00..5abcd02ee 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2259,35 +2259,11 @@ } - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_MM_Blend */ - /* */ - /* */ - /* Set the blend (normalized) coordinates for this instance of the */ - /* font. Check that the `gvar' table is reasonable and does some */ - /* initial preparation. */ - /* */ - /* */ - /* face :: The font. */ - /* Initialize the blend structure with `gvar' data. */ - /* */ - /* */ - /* num_coords :: The number of available coordinates. If it is */ - /* larger than the number of axes, ignore the excess */ - /* values. If it is smaller than the number of axes, */ - /* use the default value (0) for the remaining axes. */ - /* */ - /* coords :: An array of `num_coords', each between [-1,1]. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - TT_Set_MM_Blend( TT_Face face, + static FT_Error + tt_set_mm_blend( TT_Face face, FT_UInt num_coords, - FT_Fixed* coords ) + FT_Fixed* coords, + FT_Bool set_design_coords ) { FT_Error error = FT_Err_Ok; GX_Blend blend; @@ -2318,7 +2294,8 @@ if ( num_coords > mmvar->num_axis ) { - FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", + FT_TRACE2(( "TT_Set_MM_Blend:" + " only using first %d of %d coordinates\n", mmvar->num_axis, num_coords )); num_coords = mmvar->num_axis; } @@ -2347,6 +2324,12 @@ if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) ) goto Exit; + if ( !blend->coords ) + { + if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) + goto Exit; + } + if ( !blend->normalizedcoords ) { if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) @@ -2391,6 +2374,12 @@ coords, num_coords * sizeof ( FT_Fixed ) ); + if ( set_design_coords ) + ft_var_to_design( face, + num_coords, + blend->normalizedcoords, + blend->coords ); + face->doblend = TRUE; if ( face->cvt ) @@ -2449,6 +2438,40 @@ } + /*************************************************************************/ + /* */ + /* */ + /* TT_Set_MM_Blend */ + /* */ + /* */ + /* Set the blend (normalized) coordinates for this instance of the */ + /* font. Check that the `gvar' table is reasonable and does some */ + /* initial preparation. */ + /* */ + /* */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, ignore the excess */ + /* values. If it is smaller than the number of axes, */ + /* use the default value (0) for the remaining axes. */ + /* */ + /* coords :: An array of `num_coords', each between [-1,1]. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + return tt_set_mm_blend( face, num_coords, coords, 1 ); + } + + /*************************************************************************/ /* */ /* */ @@ -2493,7 +2516,8 @@ nc = num_coords; if ( num_coords > blend->num_axis ) { - FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n", + FT_TRACE2(( "TT_Get_MM_Blend:" + " only using first %d of %d coordinates\n", blend->num_axis, num_coords )); nc = blend->num_axis; } @@ -2546,11 +2570,16 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error = FT_Err_Ok; - FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i; + FT_Memory memory = face->root.memory; + + FT_Var_Axis* a; + FT_Fixed* c; FT_Fixed* normalized = NULL; - FT_UInt num_axes; if ( !face->blend ) @@ -2559,9 +2588,33 @@ goto Exit; } - num_axes = face->blend->mmvar->num_axis; + blend = face->blend; + mmvar = blend->mmvar; - if ( FT_NEW_ARRAY( normalized, num_axes ) ) + if ( num_coords > mmvar->num_axis ) + { + FT_TRACE2(( "TT_Set_Var_Design:" + " only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; + } + + if ( !blend->coords ) + { + if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) + goto Exit; + } + + FT_MEM_COPY( blend->coords, + coords, + num_coords * sizeof ( FT_Fixed ) ); + + a = mmvar->axis + num_coords; + c = coords + num_coords; + for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ ) + *c = a->def; + + if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; if ( !face->blend->avar_loaded ) @@ -2569,7 +2622,7 @@ ft_var_to_normalized( face, num_coords, coords, normalized ); - error = TT_Set_MM_Blend( face, num_axes, normalized ); + error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); Exit: FT_FREE( normalized ); @@ -2605,6 +2658,8 @@ FT_Fixed* coords ) { FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_UInt i, nc; if ( !face->blend ) @@ -2613,13 +2668,30 @@ return error; } - if ( !face->blend->avar_loaded ) - ft_var_load_avar( face ); + blend = face->blend; - ft_var_to_design( face, - num_coords, - face->blend->normalizedcoords, - coords ); + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "TT_Get_Var_Design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + if ( face->doblend ) + { + for ( i = 0; i < nc; i++ ) + coords[i] = blend->coords[i]; + } + else + { + for ( i = 0; i < nc; i++ ) + coords[i] = 0; + } + + for ( ; i < num_coords; i++ ) + coords[i] = 0; return FT_Err_Ok; } @@ -3506,16 +3578,19 @@ tt_get_var_blend( TT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ) { if ( face->blend ) { if ( num_coords ) - *num_coords = face->blend->num_axis; + *num_coords = face->blend->num_axis; if ( coords ) - *coords = face->blend->normalizedcoords; + *coords = face->blend->coords; + if ( normalizedcoords ) + *normalizedcoords = face->blend->normalizedcoords; if ( mm_var ) - *mm_var = face->blend->mmvar; + *mm_var = face->blend->mmvar; } else { @@ -3583,6 +3658,7 @@ /* blend->num_axis might not be set up yet */ num_axes = blend->mmvar->num_axis; + FT_FREE( blend->coords ); FT_FREE( blend->normalizedcoords ); FT_FREE( blend->normalized_stylecoords ); FT_FREE( blend->mmvar ); diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 804678cb9..7e81719a3 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -220,6 +220,11 @@ FT_BEGIN_HEADER /* num_axis :: */ /* The number of axes along which interpolation may happen. */ /* */ + /* coords :: */ + /* An array of design coordinates (in user space) indicating the */ + /* contribution along each axis to the final interpolated font. */ + /* `normalizedcoords' holds the same values. */ + /* */ /* normalizedcoords :: */ /* An array of normalized values (between [-1,1]) indicating the */ /* contribution along each axis to the final interpolated font. */ @@ -294,6 +299,7 @@ FT_BEGIN_HEADER typedef struct GX_BlendRec_ { FT_UInt num_axis; + FT_Fixed* coords; FT_Fixed* normalizedcoords; FT_MM_Var* mmvar; @@ -423,6 +429,7 @@ FT_BEGIN_HEADER tt_get_var_blend( TT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); FT_LOCAL( void )