diff --git a/ChangeLog b/ChangeLog index 080f03e9d..e19cb50f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2017-12-20 Werner Lemberg + + Speed up FT_Set_Var_{Design,Blend}_Coordinates if curr == new. + + We exit early if the current design or blend coordinates are + identical to the new ones. + + * src/truetype/ttgxvar.c (tt_set_mm_blend, TT_Set_Var_Design): + Implement it, returning internal error code -1 if there will be no + variation change. + + * src/type1/t1load.c (t1_set_mm_blend): Ditto. + + * src/base/ftmm.c (FT_Set_Var_Design_Coordinates, + FT_Set_MM_Blend_Coordinates, FT_Set_Var_Blend_Coordinates): Updated. + 2017-12-18 Werner Lemberg [sfnt] Fix charmap type 2 iterator (#52646). diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h index a934f9452..a92ae345b 100644 --- a/include/freetype/internal/services/svmm.h +++ b/include/freetype/internal/services/svmm.h @@ -48,11 +48,15 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Long* coords ); + /* use return value -1 to indicate that the new coordinates */ + /* are equal to the current ones; no changes are thus needed */ typedef FT_Error (*FT_Set_Var_Design_Func)( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); + /* use return value -1 to indicate that the new coordinates */ + /* are equal to the current ones; no changes are thus needed */ typedef FT_Error (*FT_Set_MM_Blend_Func)( FT_Face face, FT_UInt num_coords, diff --git a/src/base/ftmm.c b/src/base/ftmm.c index e0131ece3..6a42df6e9 100644 --- a/src/base/ftmm.c +++ b/src/base/ftmm.c @@ -203,6 +203,10 @@ error = FT_ERR( Invalid_Argument ); if ( service_mm->set_var_design ) error = service_mm->set_var_design( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; } if ( !error ) @@ -275,6 +279,10 @@ error = FT_ERR( Invalid_Argument ); if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; } if ( !error ) @@ -322,6 +330,10 @@ error = FT_ERR( Invalid_Argument ); if ( service_mm->set_mm_blend ) error = service_mm->set_mm_blend( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; } if ( !error ) diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 8230419c7..2acd7e05b 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -2432,6 +2432,12 @@ } else { + FT_Bool have_diff = 0; + FT_UInt j; + FT_Fixed* c; + FT_Fixed* n; + + manageCvt = mcvt_retain; for ( i = 0; i < num_coords; i++ ) @@ -2439,10 +2445,34 @@ if ( blend->normalizedcoords[i] != coords[i] ) { manageCvt = mcvt_load; + have_diff = 1; break; } } + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt idx = (FT_UInt)face->root.face_index >> 16; + + + c = blend->normalizedcoords + i; + n = blend->normalized_stylecoords + idx * mmvar->num_axis + i; + for ( j = i; j < mmvar->num_axis; j++, n++, c++ ) + if ( *c != *n ) + have_diff = 1; + } + else + { + c = blend->normalizedcoords + i; + for ( j = i; j < mmvar->num_axis; j++, c++ ) + if ( *c != 0 ) + have_diff = 1; + } + + /* return value -1 indicates `no change' */ + if ( !have_diff ) + return -1; + for ( ; i < mmvar->num_axis; i++ ) { if ( blend->normalizedcoords[i] != 0 ) @@ -2664,8 +2694,11 @@ FT_Memory memory = face->root.memory; FT_Fixed* c; + FT_Fixed* n; FT_Fixed* normalized = NULL; + FT_Bool have_diff = 0; + if ( !face->blend ) { @@ -2690,25 +2723,35 @@ goto Exit; } - FT_MEM_COPY( blend->coords, - coords, - num_coords * sizeof ( FT_Fixed ) ); - - c = blend->coords + num_coords; + c = blend->coords; + n = coords; + for ( i = 0; i < num_coords; i++, n++, c++ ) + { + if ( *c != *n ) + { + *c = *n; + have_diff = 1; + } + } if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) { FT_UInt instance_index; FT_Var_Named_Style* named_style; - FT_Fixed* n; instance_index = (FT_UInt)face->root.face_index >> 16; named_style = mmvar->namedstyle + instance_index - 1; n = named_style->coords + num_coords; - for ( i = num_coords; i < mmvar->num_axis; i++, n++, c++ ) - *c = *n; + for ( ; i < mmvar->num_axis; i++, n++, c++ ) + { + if ( *c != *n ) + { + *c = *n; + have_diff = 1; + } + } } else { @@ -2716,10 +2759,20 @@ a = mmvar->axis + num_coords; - for ( i = num_coords; i < mmvar->num_axis; i++, a++, c++ ) - *c = a->def; + for ( ; i < mmvar->num_axis; i++, a++, c++ ) + { + if ( *c != a->def ) + { + *c = a->def; + have_diff = 1; + } + } } + /* return value -1 indicates `no change' */ + if ( !have_diff ) + return -1; + if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; diff --git a/src/type1/t1load.c b/src/type1/t1load.c index bdb986a01..70e7c68df 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -374,6 +374,8 @@ PS_Blend blend = face->blend; FT_UInt n, m; + FT_Bool have_diff = 0; + if ( !blend ) return FT_THROW( Invalid_Argument ); @@ -405,10 +407,16 @@ result = FT_MulFix( result, factor ); } - blend->weight_vector[n] = result; + + if ( blend->weight_vector[n] != result ) + { + blend->weight_vector[n] = result; + have_diff = 1; + } } - return FT_Err_Ok; + /* return value -1 indicates `no change' */ + return have_diff ? FT_Err_Ok : -1; }