diff options
Diffstat (limited to 'src/3rdparty/freetype/src/truetype')
18 files changed, 1210 insertions, 3412 deletions
diff --git a/src/3rdparty/freetype/src/truetype/module.mk b/src/3rdparty/freetype/src/truetype/module.mk index f6e1c91a5d..5d44ac1f41 100644 --- a/src/3rdparty/freetype/src/truetype/module.mk +++ b/src/3rdparty/freetype/src/truetype/module.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 1996-2022 by +# Copyright (C) 1996-2023 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/truetype/rules.mk b/src/3rdparty/freetype/src/truetype/rules.mk index d0d2404b8f..dde26de1cc 100644 --- a/src/3rdparty/freetype/src/truetype/rules.mk +++ b/src/3rdparty/freetype/src/truetype/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 1996-2022 by +# Copyright (C) 1996-2023 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -33,8 +33,7 @@ TT_DRV_SRC := $(TT_DIR)/ttdriver.c \ $(TT_DIR)/ttgxvar.c \ $(TT_DIR)/ttinterp.c \ $(TT_DIR)/ttobjs.c \ - $(TT_DIR)/ttpload.c \ - $(TT_DIR)/ttsubpix.c + $(TT_DIR)/ttpload.c # TrueType driver headers # diff --git a/src/3rdparty/freetype/src/truetype/truetype.c b/src/3rdparty/freetype/src/truetype/truetype.c index 41c844acbb..fcc0ea334f 100644 --- a/src/3rdparty/freetype/src/truetype/truetype.c +++ b/src/3rdparty/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ * * FreeType TrueType driver component (body only). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -24,7 +24,6 @@ #include "ttinterp.c" #include "ttobjs.c" /* object manager */ #include "ttpload.c" /* tables loader */ -#include "ttsubpix.c" /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.c b/src/3rdparty/freetype/src/truetype/ttdriver.c index 245d97cb58..d1496fec7f 100644 --- a/src/3rdparty/freetype/src/truetype/ttdriver.c +++ b/src/3rdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ * * TrueType font driver implementation (body). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -57,7 +57,7 @@ * PROPERTY SERVICE * */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, const void* value, @@ -93,17 +93,22 @@ interpreter_version = *iv; } - if ( interpreter_version == TT_INTERPRETER_VERSION_35 -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - || interpreter_version == TT_INTERPRETER_VERSION_38 -#endif + switch ( interpreter_version ) + { + case TT_INTERPRETER_VERSION_35: + driver->interpreter_version = TT_INTERPRETER_VERSION_35; + break; + + case TT_INTERPRETER_VERSION_38: + case TT_INTERPRETER_VERSION_40: #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - || interpreter_version == TT_INTERPRETER_VERSION_40 + driver->interpreter_version = TT_INTERPRETER_VERSION_40; + break; #endif - ) - driver->interpreter_version = interpreter_version; - else + + default: error = FT_ERR( Unimplemented_Feature ); + } return error; } @@ -114,10 +119,10 @@ } - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_property_get( FT_Module module, /* TT_Driver */ const char* property_name, - const void* value ) + void* value ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; @@ -144,8 +149,8 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, /* set_property */ - (FT_Properties_GetFunc)tt_property_get /* get_property */ + tt_property_set, /* FT_Properties_SetFunc set_property */ + tt_property_get /* FT_Properties_GetFunc get_property */ ) @@ -198,35 +203,35 @@ * * They can be implemented by format-specific interfaces. */ - static FT_Error - tt_get_kerning( FT_Face ttface, /* TT_Face */ + FT_CALLBACK_DEF( FT_Error ) + tt_get_kerning( FT_Face face, /* TT_Face */ FT_UInt left_glyph, FT_UInt right_glyph, FT_Vector* kerning ) { - TT_Face face = (TT_Face)ttface; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + TT_Face ttface = (TT_Face)face; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; kerning->x = 0; kerning->y = 0; if ( sfnt ) - kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); + kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph ); return 0; } - static FT_Error - tt_get_advances( FT_Face ttface, + FT_CALLBACK_DEF( FT_Error ) + tt_get_advances( FT_Face face, /* TT_Face */ FT_UInt start, FT_UInt count, FT_Int32 flags, FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face)ttface; + TT_Face ttface = (TT_Face)face; /* XXX: TODO: check for sbits */ @@ -235,8 +240,8 @@ { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without VVAR table */ - if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && - !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif @@ -247,7 +252,7 @@ /* since we don't need `tsb', we use zero for `yMax' parameter */ - TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah ); + TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah ); advances[nn] = ah; } } @@ -255,8 +260,8 @@ { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* no fast retrieval for blended MM fonts without HVAR table */ - if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && - !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) return FT_THROW( Unimplemented_Feature ); #endif @@ -266,7 +271,7 @@ FT_UShort aw; - TT_Get_HMetrics( face, start + nn, &lsb, &aw ); + TT_Get_HMetrics( ttface, start + nn, &lsb, &aw ); advances[nn] = aw; } } @@ -290,7 +295,7 @@ #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_size_select( FT_Size size, FT_ULong strike_index ) { @@ -306,7 +311,7 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize, 0 ); /* ignore return value */ + tt_size_reset( ttsize ); /* ignore return value */ } else { @@ -327,7 +332,7 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - static FT_Error + FT_CALLBACK_DEF( FT_Error ) tt_size_request( FT_Size size, FT_Size_Request req ) { @@ -367,7 +372,7 @@ if ( FT_IS_SCALABLE( size->face ) ) { - error = tt_size_reset( ttsize, 0 ); + error = tt_size_reset( ttsize ); #ifdef TT_USE_BYTECODE_INTERPRETER /* for the `MPS' bytecode instruction we need the point size */ @@ -426,15 +431,15 @@ * @Return: * FreeType error code. 0 means success. */ - static FT_Error - tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ - FT_Size ttsize, /* TT_Size */ + FT_CALLBACK_DEF( FT_Error ) + tt_glyph_load( FT_GlyphSlot slot, /* TT_GlyphSlot */ + FT_Size size, /* TT_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { - TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; - TT_Size size = (TT_Size)ttsize; - FT_Face face = ttslot->face; + TT_GlyphSlot ttslot = (TT_GlyphSlot)slot; + TT_Size ttsize = (TT_Size)size; + FT_Face face = ttslot->face; FT_Error error; @@ -476,12 +481,12 @@ } /* use hinted metrics only if we load a glyph with hinting */ - size->metrics = ( load_flags & FT_LOAD_NO_HINTING ) - ? &ttsize->metrics - : &size->hinted_metrics; + ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING ) + ? &size->metrics + : &ttsize->hinted_metrics; /* now fill in the glyph slot with outline/bitmap/layered */ - error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); + error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ /* slot->outline.dropout_mode = 2; */ @@ -507,34 +512,47 @@ FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, /* get_mm */ - (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ - (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ - (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ - (FT_Set_Var_Design_Func) TT_Set_Var_Design, /* set_var_design */ - (FT_Get_Var_Design_Func) TT_Get_Var_Design, /* get_var_design */ - (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ - (FT_Set_MM_WeightVector_Func)NULL, /* set_mm_weightvector */ - (FT_Get_MM_WeightVector_Func)NULL, /* get_mm_weightvector */ - - (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ - (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + NULL, /* FT_Get_MM_Func get_mm */ + NULL, /* FT_Set_MM_Design_Func set_mm_design */ + TT_Set_MM_Blend, /* FT_Set_MM_Blend_Func set_mm_blend */ + TT_Get_MM_Blend, /* FT_Get_MM_Blend_Func get_mm_blend */ + TT_Get_MM_Var, /* FT_Get_MM_Var_Func get_mm_var */ + TT_Set_Var_Design, /* FT_Set_Var_Design_Func set_var_design */ + TT_Get_Var_Design, /* FT_Get_Var_Design_Func get_var_design */ + TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func set_named_instance */ + TT_Get_Default_Named_Instance, + /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ + NULL, /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ + NULL, /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ + + tt_construct_ps_name, /* FT_Construct_PS_Name_Func construct_ps_name */ + tt_var_load_delta_set_index_mapping, + /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ + tt_var_load_item_variation_store, + /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ + tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func get_item_delta */ + tt_var_done_item_variation_store, + /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ + tt_var_done_delta_set_index_map, + /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ + tt_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ + tt_done_blend /* FT_Done_Blend_Func done_blend */ ) FT_DEFINE_SERVICE_METRICSVARIATIONSREC( tt_service_metrics_variations, - (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ - (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ - (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + tt_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ + NULL, /* FT_LSB_Adjust_Func lsb_adjust */ + NULL, /* FT_RSB_Adjust_Func rsb_adjust */ - (FT_VAdvance_Adjust_Func)tt_vadvance_adjust, /* vadvance_adjust */ - (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ - (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ - (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + tt_vadvance_adjust, /* FT_VAdvance_Adjust_Func vadvance_adjust */ + NULL, /* FT_TSB_Adjust_Func tsb_adjust */ + NULL, /* FT_BSB_Adjust_Func bsb_adjust */ + NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ - (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ + tt_apply_mvar, /* FT_Metrics_Adjust_Func metrics_adjust */ + tt_size_reset_height /* FT_Size_Reset_Func size_reset */ ) #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.h b/src/3rdparty/freetype/src/truetype/ttdriver.h index c477c0b1dd..757a66f425 100644 --- a/src/3rdparty/freetype/src/truetype/ttdriver.h +++ b/src/3rdparty/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ * * High-level TrueType driver interface (specification). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/src/truetype/tterrors.h b/src/3rdparty/freetype/src/truetype/tterrors.h index 2c95ea17b2..008ee99853 100644 --- a/src/3rdparty/freetype/src/truetype/tterrors.h +++ b/src/3rdparty/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ * * TrueType error codes (specification only). * - * Copyright (C) 2001-2022 by + * Copyright (C) 2001-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/src/truetype/ttgload.c b/src/3rdparty/freetype/src/truetype/ttgload.c index 2ca63d65a3..dc427e8a11 100644 --- a/src/3rdparty/freetype/src/truetype/ttgload.c +++ b/src/3rdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (body). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -35,7 +35,6 @@ #endif #include "tterrors.h" -#include "ttsubpix.h" /************************************************************************** @@ -152,9 +151,6 @@ FT_UInt glyph_index ) { TT_Face face = loader->face; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); -#endif FT_Error error; FT_Stream stream = loader->stream; @@ -183,20 +179,6 @@ loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && - loader->exec ) - { - loader->exec->sph_tweak_flags = 0; - - /* This may not be the right place for this, but it works... */ - /* Note that we have to unconditionally load the tweaks since */ - /* it is possible that glyphs individually switch ClearType's */ - /* backward compatibility mode on and off. */ - sph_set_tweaks( loader, glyph_index ); - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - #ifdef FT_CONFIG_OPTION_INCREMENTAL /* With the incremental interface, these values are set by */ /* a call to `tt_get_metrics_incremental'. */ @@ -362,17 +344,16 @@ FT_Byte* p = load->cursor; FT_Byte* limit = load->limit; FT_GlyphLoader gloader = load->gloader; + FT_Outline* outline = &gloader->current.outline; FT_Int n_contours = load->n_contours; - FT_Outline* outline; - FT_UShort n_ins; FT_Int n_points; + FT_UShort n_ins; FT_Byte *flag, *flag_limit; FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x, y; - FT_Short *cont, *cont_limit, prev_cont; - FT_Int xy_size = 0; + FT_Short *cont, *cont_limit, last; /* check that we can add the contours to the glyph */ @@ -380,41 +361,27 @@ if ( error ) goto Fail; - /* reading the contours' endpoints & number of points */ - cont = gloader->current.outline.contours; - cont_limit = cont + n_contours; - /* check space for contours array + instructions count */ - if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) + if ( n_contours >= 0xFFF || p + 2 * n_contours + 2 > limit ) goto Invalid_Outline; - prev_cont = FT_NEXT_SHORT( p ); - - if ( n_contours > 0 ) - cont[0] = prev_cont; - - if ( prev_cont < 0 ) - goto Invalid_Outline; + /* reading the contours' endpoints & number of points */ + cont = outline->contours; + cont_limit = cont + n_contours; - for ( cont++; cont < cont_limit; cont++ ) + last = -1; + for ( ; cont < cont_limit; cont++ ) { - cont[0] = FT_NEXT_SHORT( p ); - if ( cont[0] <= prev_cont ) - { - /* unordered contours: this is invalid */ - goto Invalid_Outline; - } - prev_cont = cont[0]; - } + *cont = FT_NEXT_SHORT( p ); - n_points = 0; - if ( n_contours > 0 ) - { - n_points = cont[-1] + 1; - if ( n_points < 0 ) + if ( *cont <= last ) goto Invalid_Outline; + + last = *cont; } + n_points = last + 1; + FT_TRACE5(( " # of points: %d\n", n_points )); /* note that we will add four phantom points later */ @@ -422,59 +389,48 @@ if ( error ) goto Fail; - /* reading the bytecode instructions */ - load->glyph->control_len = 0; - load->glyph->control_data = NULL; - - if ( p + 2 > limit ) - goto Invalid_Outline; - + /* space checked above */ n_ins = FT_NEXT_USHORT( p ); FT_TRACE5(( " Instructions size: %u\n", n_ins )); + /* check instructions size */ + if ( p + n_ins > limit ) + { + FT_TRACE1(( "TT_Load_Simple_Glyph: excessive instruction count\n" )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + #ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { - FT_ULong tmp; + TT_ExecContext exec = load->exec; + FT_Memory memory = exec->memory; - /* check instructions size */ - if ( ( limit - p ) < n_ins ) - { - FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } + if ( exec->glyphSize ) + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ - /* and thus update the bytecode array size by ourselves */ - - tmp = load->exec->glyphSize; - error = Update_Max( load->exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&load->exec->glyphIns, - n_ins ); - - load->exec->glyphSize = (FT_UInt)tmp; - if ( error ) - return error; + /* and thus allocate the bytecode array size by ourselves */ + if ( n_ins ) + { + if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ) + return error; - load->glyph->control_len = n_ins; - load->glyph->control_data = load->exec->glyphIns; + FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins ); - if ( n_ins ) - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + exec->glyphSize = n_ins; + } } #endif /* TT_USE_BYTECODE_INTERPRETER */ p += n_ins; - outline = &gloader->current.outline; - /* reading the point tags */ flag = (FT_Byte*)outline->tags; flag_limit = flag + n_points; @@ -512,9 +468,6 @@ flag = (FT_Byte*)outline->tags; x = 0; - if ( p + xy_size > limit ) - goto Invalid_Outline; - for ( ; vec < vec_limit; vec++, flag++ ) { FT_Pos delta = 0; @@ -544,7 +497,7 @@ /* reading the Y coordinates */ - vec = gloader->current.outline.points; + vec = outline->points; vec_limit = vec + n_points; flag = (FT_Byte*)outline->tags; y = 0; @@ -737,19 +690,19 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) FT_TRACE7(( " scaling: %f\n", - subglyph->transform.xx / 65536.0 )); + (double)subglyph->transform.xx / 65536 )); else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) FT_TRACE7(( " scaling: x=%f, y=%f\n", - subglyph->transform.xx / 65536.0, - subglyph->transform.yy / 65536.0 )); + (double)subglyph->transform.xx / 65536, + (double)subglyph->transform.yy / 65536 )); else if ( subglyph->flags & WE_HAVE_A_2X2 ) { FT_TRACE7(( " scaling: xx=%f, yx=%f\n", - subglyph->transform.xx / 65536.0, - subglyph->transform.yx / 65536.0 )); + (double)subglyph->transform.xx / 65536, + (double)subglyph->transform.yx / 65536 )); FT_TRACE7(( " xy=%f, yy=%f\n", - subglyph->transform.xy / 65536.0, - subglyph->transform.yy / 65536.0 )); + (double)subglyph->transform.xy / 65536, + (double)subglyph->transform.yy / 65536 )); } subglyph++; @@ -801,7 +754,7 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)load->outline.n_points - + zone->n_points = (FT_UShort)load->outline.n_points + 4 - (FT_UShort)start_point; zone->n_contours = load->outline.n_contours - (FT_Short)start_contour; @@ -827,8 +780,7 @@ TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { -#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ - defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -836,35 +788,34 @@ TT_GlyphZone zone = &loader->zone; #ifdef TT_USE_BYTECODE_INTERPRETER - FT_Long n_ins; + TT_ExecContext exec = loader->exec; + FT_Long n_ins = exec->glyphSize; #else FT_UNUSED( is_composite ); #endif #ifdef TT_USE_BYTECODE_INTERPRETER - n_ins = loader->glyph->control_len; - /* save original point positions in `org' array */ if ( n_ins > 0 ) FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); /* Reset graphics state. */ - loader->exec->GS = loader->size->GS; + exec->GS = loader->size->GS; /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */ /* completely refer to the (already) hinted subglyphs. */ if ( is_composite ) { - loader->exec->metrics.x_scale = 1 << 16; - loader->exec->metrics.y_scale = 1 << 16; + exec->metrics.x_scale = 1 << 16; + exec->metrics.y_scale = 1 << 16; FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points ); } else { - loader->exec->metrics.x_scale = loader->size->metrics->x_scale; - loader->exec->metrics.y_scale = loader->size->metrics->y_scale; + exec->metrics.x_scale = loader->size->metrics->x_scale; + exec->metrics.y_scale = loader->size->metrics->y_scale; } #endif @@ -884,53 +835,37 @@ { FT_Error error; - FT_GlyphLoader gloader = loader->gloader; - FT_Outline current_outline = gloader->current.outline; - - TT_Set_CodeRange( loader->exec, tt_coderange_glyph, - loader->exec->glyphIns, n_ins ); + TT_Set_CodeRange( exec, tt_coderange_glyph, exec->glyphIns, n_ins ); - loader->exec->is_composite = is_composite; - loader->exec->pts = *zone; + exec->is_composite = is_composite; + exec->pts = *zone; - error = TT_Run_Context( loader->exec ); - if ( error && loader->exec->pedantic_hinting ) + error = TT_Run_Context( exec ); + if ( error && exec->pedantic_hinting ) return error; /* store drop-out mode in bits 5-7; set bit 2 also as a marker */ - current_outline.tags[0] |= - ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; + loader->gloader->current.outline.tags[0] |= + ( exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE; } #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* Save possibly modified glyph phantom points unless in v40 backward */ /* compatibility mode, where no movement on the x axis means no reason */ /* to change bearings or advance widths. */ - if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && - loader->exec->backward_compatibility ) ) - { -#endif - loader->pp1 = zone->cur[zone->n_points - 4]; - loader->pp2 = zone->cur[zone->n_points - 3]; - loader->pp3 = zone->cur[zone->n_points - 2]; - loader->pp4 = zone->cur[zone->n_points - 1]; + #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - } + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + exec->backward_compatibility ) + return FT_Err_Ok; #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); - - else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) - FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + loader->pp1 = zone->cur[zone->n_points - 4]; + loader->pp2 = zone->cur[zone->n_points - 3]; + loader->pp3 = zone->cur[zone->n_points - 2]; + loader->pp4 = zone->cur[zone->n_points - 1]; return FT_Err_Ok; } @@ -949,10 +884,10 @@ static FT_Error TT_Process_Simple_Glyph( TT_Loader loader ) { - FT_GlyphLoader gloader = loader->gloader; - FT_Error error = FT_Err_Ok; - FT_Outline* outline; - FT_Int n_points; + FT_Error error = FT_Err_Ok; + FT_GlyphLoader gloader = loader->gloader; + FT_Outline* outline = &gloader->current.outline; + FT_Int n_points = outline->n_points; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Memory memory = loader->face->root.memory; @@ -960,49 +895,25 @@ #endif - outline = &gloader->current.outline; - n_points = outline->n_points; - /* set phantom points */ - outline->points[n_points ] = loader->pp1; outline->points[n_points + 1] = loader->pp2; outline->points[n_points + 2] = loader->pp3; outline->points[n_points + 3] = loader->pp4; - outline->tags[n_points ] = 0; - outline->tags[n_points + 1] = 0; - outline->tags[n_points + 2] = 0; - outline->tags[n_points + 3] = 0; - n_points += 4; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) { - if ( FT_NEW_ARRAY( unrounded, n_points ) ) + if ( FT_QNEW_ARRAY( unrounded, n_points ) ) goto Exit; /* Deltas apply to the unscaled data. */ - error = TT_Vary_Apply_Glyph_Deltas( loader->face, - loader->glyph_index, + error = TT_Vary_Apply_Glyph_Deltas( loader, outline, - unrounded, - (FT_UInt)n_points ); - - /* recalculate linear horizontal and vertical advances */ - /* if we don't have HVAR and VVAR, respectively */ - - /* XXX: change all FreeType modules to store `linear' and `vadvance' */ - /* in 26.6 format before the `base' module scales them to 16.16 */ - if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x - - unrounded[n_points - 4].x ) / 64; - if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x - - unrounded[n_points - 2].x ) / 64; - + unrounded ); if ( error ) goto Exit; } @@ -1014,20 +925,10 @@ tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, - loader->zone.n_points + 4 ); + loader->zone.n_points ); } { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - TT_Face face = loader->face; - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); - - FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics->x_ppem; - FT_String* style = face->root.style_name; - FT_UInt x_scale_factor = 1000; -#endif - FT_Vector* vec = outline->points; FT_Vector* limit = outline->points + n_points; @@ -1037,52 +938,6 @@ FT_Bool do_scale = FALSE; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - /* scale, but only if enabled and only if TT hinting is being used */ - if ( IS_HINTED( loader->load_flags ) ) - x_scale_factor = sph_test_tweak_x_scaling( face, - family, - ppem, - style, - loader->glyph_index ); - /* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || - x_scale_factor != 1000 ) - { - x_scale = FT_MulDiv( loader->size->metrics->x_scale, - (FT_Long)x_scale_factor, 1000 ); - y_scale = loader->size->metrics->y_scale; - - /* compensate for any scaling by de/emboldening; */ - /* the amount was determined via experimentation */ - if ( x_scale_factor != 1000 && ppem > 11 ) - { -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Vector* orig_points = outline->points; - - - if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) - outline->points = unrounded; -#endif - FT_Outline_EmboldenXY( outline, - FT_MulFix( 1280 * ppem, - 1000 - x_scale_factor ), - 0 ); -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) - outline->points = orig_points; -#endif - } - do_scale = TRUE; - } - } - else - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) @@ -1156,11 +1011,7 @@ } if ( IS_HINTED( loader->load_flags ) ) - { - loader->zone.n_points += 4; - error = TT_Hint_Glyph( loader, 0 ); - } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT Exit: @@ -1355,12 +1206,12 @@ FT_UInt start_contour ) { FT_Error error; - FT_Outline* outline; + FT_Outline* outline = &loader->gloader->base.outline; + FT_Stream stream = loader->stream; + FT_UShort n_ins; FT_UInt i; - outline = &loader->gloader->base.outline; - /* make room for phantom points */ error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, outline->n_points + 4, @@ -1373,19 +1224,17 @@ outline->points[outline->n_points + 2] = loader->pp3; outline->points[outline->n_points + 3] = loader->pp4; - outline->tags[outline->n_points ] = 0; - outline->tags[outline->n_points + 1] = 0; - outline->tags[outline->n_points + 2] = 0; - outline->tags[outline->n_points + 3] = 0; - #ifdef TT_USE_BYTECODE_INTERPRETER { - FT_Stream stream = loader->stream; - FT_UShort n_ins, max_ins; - FT_ULong tmp; + TT_ExecContext exec = loader->exec; + FT_Memory memory = exec->memory; + if ( exec->glyphSize ) + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; + /* TT_Load_Composite_Glyph only gives us the offset of instructions */ /* so we read them here */ if ( FT_STREAM_SEEK( loader->ins_pos ) || @@ -1394,39 +1243,24 @@ FT_TRACE5(( " Instructions size = %hu\n", n_ins )); - /* check it */ - max_ins = loader->face->max_profile.maxSizeOfInstructions; - if ( n_ins > max_ins ) - { - /* don't trust `maxSizeOfInstructions'; */ - /* only do a rough safety check */ - if ( n_ins > loader->byte_len ) - { - FT_TRACE1(( "TT_Process_Composite_Glyph:" - " too many instructions (%hu) for glyph with length %u\n", - n_ins, loader->byte_len )); - return FT_THROW( Too_Many_Hints ); - } - - tmp = loader->exec->glyphSize; - error = Update_Max( loader->exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&loader->exec->glyphIns, - n_ins ); + if ( !n_ins ) + return FT_Err_Ok; - loader->exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; + /* don't trust `maxSizeOfInstructions'; */ + /* only do a rough safety check */ + if ( n_ins > loader->byte_len ) + { + FT_TRACE1(( "TT_Process_Composite_Glyph:" + " too many instructions (%hu) for glyph with length %u\n", + n_ins, loader->byte_len )); + return FT_THROW( Too_Many_Hints ); } - else if ( n_ins == 0 ) - return FT_Err_Ok; - if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) + if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) || + FT_STREAM_READ( exec->glyphIns, n_ins ) ) return error; - loader->glyph->control_data = loader->exec->glyphIns; - loader->glyph->control_len = n_ins; + exec->glyphSize = n_ins; } #endif @@ -1436,11 +1270,9 @@ /* Some points are likely touched during execution of */ /* instructions on components. So let's untouch them. */ - for ( i = 0; i < loader->zone.n_points; i++ ) + for ( i = 0; i < loader->zone.n_points - 4U; i++ ) loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH; - loader->zone.n_points += 4; - return TT_Hint_Glyph( loader, 1 ); } @@ -1532,45 +1364,31 @@ static void tt_loader_set_pp( TT_Loader loader ) { - FT_Bool subpixel_hinting = 0; - FT_Bool grayscale = 0; - FT_Bool use_aw_2 = 0; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); -#endif - - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting - : 0; - grayscale = loader->exec ? loader->exec->grayscale - : 0; - } -#endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) - { - subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean - : 0; - grayscale = loader->exec ? loader->exec->grayscale_cleartype - : 0; - } -#endif - - use_aw_2 = FT_BOOL( subpixel_hinting && grayscale ); - loader->pp1.x = loader->bbox.xMin - loader->left_bearing; loader->pp1.y = 0; loader->pp2.x = loader->pp1.x + loader->advance; loader->pp2.y = 0; - loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp3.x = 0; loader->pp3.y = loader->bbox.yMax + loader->top_bearing; - loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp4.x = 0; loader->pp4.y = loader->pp3.y - loader->vadvance; + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + { + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); + + + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + loader->exec && + loader->exec->subpixel_hinting_lean && + loader->exec->grayscale_cleartype ) + { + loader->pp3.x = loader->advance / 2; + loader->pp4.x = loader->advance / 2; + } + } +#endif } @@ -1693,8 +1511,14 @@ else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_ULong len; - offset = tt_face_get_location( face, glyph_index, &loader->byte_len ); + + offset = tt_face_get_location( FT_FACE( face ), glyph_index, &len ); + + loader->byte_len = (FT_UInt)len; + } if ( loader->byte_len > 0 ) { @@ -1761,57 +1585,29 @@ /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ FT_Vector points[4]; - char tags[4] = { 1, 1, 1, 1 }; - short contours[4] = { 0, 1, 2, 3 }; FT_Outline outline; /* unrounded values */ FT_Vector unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; - points[0].x = loader->pp1.x; - points[0].y = loader->pp1.y; - points[1].x = loader->pp2.x; - points[1].y = loader->pp2.y; - - points[2].x = loader->pp3.x; - points[2].y = loader->pp3.y; - points[3].x = loader->pp4.x; - points[3].y = loader->pp4.y; + points[0] = loader->pp1; + points[1] = loader->pp2; + points[2] = loader->pp3; + points[3] = loader->pp4; - outline.n_points = 4; - outline.n_contours = 4; + outline.n_points = 0; + outline.n_contours = 0; outline.points = points; - outline.tags = tags; - outline.contours = contours; + outline.tags = NULL; + outline.contours = NULL; /* this must be done before scaling */ - error = TT_Vary_Apply_Glyph_Deltas( loader->face, - glyph_index, + error = TT_Vary_Apply_Glyph_Deltas( loader, &outline, - unrounded, - (FT_UInt)outline.n_points ); + unrounded ); if ( error ) goto Exit; - - loader->pp1.x = points[0].x; - loader->pp1.y = points[0].y; - loader->pp2.x = points[1].x; - loader->pp2.y = points[1].y; - - loader->pp3.x = points[2].x; - loader->pp3.y = points[2].y; - loader->pp4.x = points[3].x; - loader->pp4.y = points[3].y; - - /* recalculate linear horizontal and vertical advances */ - /* if we don't have HVAR and VVAR, respectively */ - if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = FT_PIX_ROUND( unrounded[1].x - - unrounded[0].x ) / 64; - if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = FT_PIX_ROUND( unrounded[3].x - - unrounded[2].x ) / 64; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1948,10 +1744,7 @@ short i, limit; FT_SubGlyph subglyph; - FT_Outline outline; - FT_Vector* points = NULL; - char* tags = NULL; - short* contours = NULL; + FT_Outline outline = { 0, 0, NULL, NULL, NULL, 0 }; FT_Vector* unrounded = NULL; @@ -1959,19 +1752,14 @@ /* construct an outline structure for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ - outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); - outline.n_contours = outline.n_points; - - outline.points = NULL; - outline.tags = NULL; - outline.contours = NULL; - - if ( FT_NEW_ARRAY( points, outline.n_points ) || - FT_NEW_ARRAY( tags, outline.n_points ) || - FT_NEW_ARRAY( contours, outline.n_points ) || - FT_NEW_ARRAY( unrounded, outline.n_points ) ) + if ( FT_QNEW_ARRAY( outline.points, limit + 4 ) || + FT_QNEW_ARRAY( outline.tags, limit ) || + FT_QNEW_ARRAY( outline.contours, limit ) || + FT_QNEW_ARRAY( unrounded, limit + 4 ) ) goto Exit1; + outline.n_contours = outline.n_points = limit; + subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) @@ -1979,47 +1767,22 @@ /* applying deltas for anchor points doesn't make sense, */ /* but we don't have to specially check this since */ /* unused delta values are zero anyways */ - points[i].x = subglyph->arg1; - points[i].y = subglyph->arg2; - tags[i] = 1; - contours[i] = i; + outline.points[i].x = subglyph->arg1; + outline.points[i].y = subglyph->arg2; + outline.tags[i] = ON_CURVE_POINT; + outline.contours[i] = i; } - points[i].x = loader->pp1.x; - points[i].y = loader->pp1.y; - tags[i] = 1; - contours[i] = i; - - i++; - points[i].x = loader->pp2.x; - points[i].y = loader->pp2.y; - tags[i] = 1; - contours[i] = i; - - i++; - points[i].x = loader->pp3.x; - points[i].y = loader->pp3.y; - tags[i] = 1; - contours[i] = i; - - i++; - points[i].x = loader->pp4.x; - points[i].y = loader->pp4.y; - tags[i] = 1; - contours[i] = i; - - outline.points = points; - outline.tags = tags; - outline.contours = contours; + outline.points[i++] = loader->pp1; + outline.points[i++] = loader->pp2; + outline.points[i++] = loader->pp3; + outline.points[i ] = loader->pp4; /* this call provides additional offsets */ /* for each component's translation */ - if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( - face, - glyph_index, - &outline, - unrounded, - (FT_UInt)outline.n_points ) ) ) + if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( loader, + &outline, + unrounded ) ) ) goto Exit1; subglyph = gloader->current.subglyphs; @@ -2028,32 +1791,11 @@ { if ( subglyph->flags & ARGS_ARE_XY_VALUES ) { - subglyph->arg1 = (FT_Int16)points[i].x; - subglyph->arg2 = (FT_Int16)points[i].y; + subglyph->arg1 = (FT_Int16)outline.points[i].x; + subglyph->arg2 = (FT_Int16)outline.points[i].y; } } - loader->pp1.x = points[i + 0].x; - loader->pp1.y = points[i + 0].y; - loader->pp2.x = points[i + 1].x; - loader->pp2.y = points[i + 1].y; - - loader->pp3.x = points[i + 2].x; - loader->pp3.y = points[i + 2].y; - loader->pp4.x = points[i + 3].x; - loader->pp4.y = points[i + 3].y; - - /* recalculate linear horizontal and vertical advances */ - /* if we don't have HVAR and VVAR, respectively */ - if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = - FT_PIX_ROUND( unrounded[outline.n_points - 3].x - - unrounded[outline.n_points - 4].x ) / 64; - if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = - FT_PIX_ROUND( unrounded[outline.n_points - 1].x - - unrounded[outline.n_points - 2].x ) / 64; - Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); @@ -2229,12 +1971,11 @@ compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { - TT_Face face = loader->face; - + TT_Face face = loader->face; + TT_Size size = loader->size; + TT_GlyphSlot glyph = loader->glyph; FT_BBox bbox; FT_Fixed y_scale; - TT_GlyphSlot glyph = loader->glyph; - TT_Size size = loader->size; y_scale = 0x10000L; @@ -2372,17 +2113,13 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { - TT_Face face; - SFNT_Service sfnt; - FT_Stream stream; + TT_Face face = (TT_Face)glyph->face; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + FT_Stream stream = face->root.stream; FT_Error error; TT_SBit_MetricsRec sbit_metrics; - face = (TT_Face)glyph->face; - sfnt = (SFNT_Service)face->sfnt; - stream = face->root.stream; - error = sfnt->load_sbit_image( face, size->strike_index, glyph_index, @@ -2433,22 +2170,18 @@ FT_Int32 load_flags, FT_Bool glyf_table_only ) { - TT_Face face; - FT_Stream stream; + TT_Face face = (TT_Face)glyph->face; + FT_Stream stream = face->root.stream; #ifdef TT_USE_BYTECODE_INTERPRETER FT_Error error; FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); -#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ - defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( glyph->face ); #endif #endif - face = (TT_Face)glyph->face; - stream = face->root.stream; - FT_ZERO( loader ); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -2463,20 +2196,6 @@ FT_Bool grayscale_cleartype; #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - FT_Bool subpixel_hinting = FALSE; - -#if 0 - /* not used yet */ - FT_Bool compatible_widths; - FT_Bool symmetrical_smoothing; - FT_Bool bgr; - FT_Bool vertical_lcd; - FT_Bool subpixel_positioned; - FT_Bool gray_cleartype; -#endif -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - FT_Bool reexecute = FALSE; @@ -2496,6 +2215,9 @@ if ( !exec ) return FT_THROW( Could_Not_Find_Context ); + grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) { @@ -2512,6 +2234,7 @@ FT_BOOL( subpixel_hinting_lean && ( load_flags & FT_LOAD_TARGET_LCD_V ) ); + grayscale = FT_BOOL( grayscale && !subpixel_hinting_lean ); } else { @@ -2521,111 +2244,11 @@ } #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) - { - subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ) && - SPH_OPTION_SET_SUBPIXEL ); - - if ( subpixel_hinting ) - grayscale = FALSE; - else if ( SPH_OPTION_SET_GRAYSCALE ) - { - grayscale = TRUE; - subpixel_hinting = FALSE; - } - else - grayscale = FALSE; - - if ( FT_IS_TRICKY( glyph->face ) ) - subpixel_hinting = FALSE; - - exec->ignore_x_mode = subpixel_hinting || grayscale; - exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - -#if 1 - exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; - exec->symmetrical_smoothing = TRUE; - exec->bgr = FALSE; - exec->vertical_lcd = FALSE; - exec->subpixel_positioned = TRUE; - exec->gray_cleartype = FALSE; -#else /* 0 */ - exec->compatible_widths = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_COMPATIBLE_WIDTHS ); - exec->symmetrical_smoothing = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_SYMMETRICAL_SMOOTHING ); - exec->bgr = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_BGR ); - exec->vertical_lcd = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_VERTICAL_LCD ); - exec->subpixel_positioned = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_SUBPIXEL_POSITIONED ); - exec->gray_cleartype = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - TT_LOAD_GRAY_CLEARTYPE ); -#endif /* 0 */ - - } - else - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) - grayscale = FT_BOOL( !subpixel_hinting_lean && - FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - else -#endif - grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - error = TT_Load_Context( exec, face, size ); if ( error ) return error; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { - /* a change from mono to subpixel rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( subpixel_hinting != exec->subpixel_hinting ) - { - FT_TRACE4(( "tt_loader_init: subpixel hinting change," - " re-executing `prep' table\n" )); - - exec->subpixel_hinting = subpixel_hinting; - reexecute = TRUE; - } - - /* a change from mono to grayscale rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale ) - { - FT_TRACE4(( "tt_loader_init: grayscale hinting change," - " re-executing `prep' table\n" )); - - exec->grayscale = grayscale; - reexecute = TRUE; - } - } - else - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - - { - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) { @@ -2683,14 +2306,6 @@ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* check whether we have a font hinted for ClearType -- */ - /* note that this flag can also be modified in a glyph's bytecode */ - if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && - exec->GS.instruct_control & 4 ) - exec->ignore_x_mode = FALSE; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* * Toggle backward compatibility according to what font wants, except @@ -2727,13 +2342,6 @@ !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && exec->backward_compatibility ) && #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - !( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && - !SPH_OPTION_BITMAP_WIDTHS && - FT_LOAD_TARGET_MODE( loader->load_flags ) != - FT_RENDER_MODE_MONO && - exec->compatible_widths ) && -#endif !face->postscript.isFixedPitch ) { loader->widthp = size->widthp; @@ -2816,6 +2424,7 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { + TT_Face face = (TT_Face)glyph->face; FT_Error error; TT_LoaderRec loader; @@ -2840,8 +2449,6 @@ /* if we have a bitmap-only font, return an empty glyph */ if ( !FT_IS_SCALABLE( glyph->face ) ) { - TT_Face face = (TT_Face)glyph->face; - FT_Short left_bearing = 0; FT_Short top_bearing = 0; @@ -2900,9 +2507,6 @@ if ( FT_IS_SCALABLE( glyph->face ) || FT_HAS_SBIX( glyph->face ) ) { - TT_Face face = (TT_Face)glyph->face; - - /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); @@ -2971,23 +2575,25 @@ #ifdef FT_CONFIG_OPTION_SVG /* check for OT-SVG */ - if ( ( load_flags & FT_LOAD_COLOR ) && ( (TT_Face)glyph->face )->svg ) + if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 && + ( load_flags & FT_LOAD_COLOR ) && + face->svg ) { - SFNT_Service sfnt; - - FT_Short leftBearing; - FT_Short topBearing; - FT_UShort advanceX; - FT_UShort advanceY; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; FT_TRACE3(( "Trying to load SVG glyph\n" )); - sfnt = (SFNT_Service)( (TT_Face)glyph->face )->sfnt; error = sfnt->load_svg_doc( glyph, glyph_index ); if ( !error ) { - TT_Face face = (TT_Face)glyph->face; + FT_Fixed x_scale = size->root.metrics.x_scale; + FT_Fixed y_scale = size->root.metrics.y_scale; + + FT_Short leftBearing; + FT_Short topBearing; + FT_UShort advanceX; + FT_UShort advanceY; FT_TRACE3(( "Successfully loaded SVG glyph\n" )); @@ -3005,15 +2611,11 @@ &topBearing, &advanceY ); - advanceX = (FT_UShort)FT_MulDiv( advanceX, - glyph->face->size->metrics.x_ppem, - glyph->face->units_per_EM ); - advanceY = (FT_UShort)FT_MulDiv( advanceY, - glyph->face->size->metrics.y_ppem, - glyph->face->units_per_EM ); + glyph->linearHoriAdvance = advanceX; + glyph->linearVertAdvance = advanceY; - glyph->metrics.horiAdvance = advanceX << 6; - glyph->metrics.vertAdvance = advanceY << 6; + glyph->metrics.horiAdvance = FT_MulFix( advanceX, x_scale ); + glyph->metrics.vertAdvance = FT_MulFix( advanceY, y_scale ); return error; } @@ -3073,6 +2675,9 @@ if ( IS_HINTED( load_flags ) ) { + glyph->control_data = loader.exec->glyphIns; + glyph->control_len = loader.exec->glyphSize; + if ( loader.exec->GS.scan_control ) { /* convert scan conversion mode to FT_OUTLINE_XXX flags */ diff --git a/src/3rdparty/freetype/src/truetype/ttgload.h b/src/3rdparty/freetype/src/truetype/ttgload.h index 3195351f78..f18637dce3 100644 --- a/src/3rdparty/freetype/src/truetype/ttgload.h +++ b/src/3rdparty/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ * * TrueType Glyph Loader (specification). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.c b/src/3rdparty/freetype/src/truetype/ttgxvar.c index 6a0edef29b..ad4f266b27 100644 --- a/src/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/src/3rdparty/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader * - * Copyright (C) 2004-2022 by + * Copyright (C) 2004-2023 by * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. * * This file is part of the FreeType project, and may only be used, @@ -42,8 +42,10 @@ #include <ft2build.h> #include <freetype/internal/ftdebug.h> #include FT_CONFIG_CONFIG_H +#include <freetype/internal/ftcalc.h> #include <freetype/internal/ftstream.h> #include <freetype/internal/sfnt.h> +#include <freetype/internal/services/svmetric.h> #include <freetype/tttags.h> #include <freetype/ttnameid.h> #include <freetype/ftmm.h> @@ -353,15 +355,24 @@ static void ft_var_load_avar( TT_Face face ) { - FT_Stream stream = FT_FACE_STREAM( face ); - FT_Memory memory = stream->memory; + FT_Error error; + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + FT_Int i, j; + GX_Blend blend = face->blend; GX_AVarSegment segment; - FT_Error error; - FT_Long version; - FT_Long axisCount; - FT_Int i, j; - FT_ULong table_len; + GX_AVarTable table; + + FT_Long version; + FT_Long axisCount; + FT_ULong table_len; + +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION + FT_ULong table_offset; + FT_ULong store_offset; + FT_ULong axisMap_offset; +#endif FT_TRACE2(( "AVAR " )); @@ -374,13 +385,21 @@ return; } +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION + table_offset = FT_STREAM_POS(); +#endif + if ( FT_FRAME_ENTER( table_len ) ) return; version = FT_GET_LONG(); axisCount = FT_GET_LONG(); - if ( version != 0x00010000L ) + if ( version != 0x00010000L +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION + && version != 0x00020000L +#endif + ) { FT_TRACE2(( "bad table version\n" )); goto Exit; @@ -396,10 +415,14 @@ goto Exit; } - if ( FT_QNEW_ARRAY( blend->avar_segment, axisCount ) ) + if ( FT_NEW( blend->avar_table ) ) goto Exit; + table = blend->avar_table; - segment = &blend->avar_segment[0]; + if ( FT_QNEW_ARRAY( table->avar_segment, axisCount ) ) + goto Exit; + + segment = &table->avar_segment[0]; for ( i = 0; i < axisCount; i++, segment++ ) { FT_TRACE5(( " axis %d:\n", i )); @@ -412,9 +435,9 @@ /* it right now since loading the `avar' table is optional. */ for ( j = i - 1; j >= 0; j-- ) - FT_FREE( blend->avar_segment[j].correspondence ); + FT_FREE( table->avar_segment[j].correspondence ); - FT_FREE( blend->avar_segment ); + FT_FREE( table->avar_segment ); goto Exit; } @@ -426,36 +449,70 @@ FT_fdot14ToFixed( FT_GET_SHORT() ); FT_TRACE5(( " mapping %.5f to %.5f\n", - segment->correspondence[j].fromCoord / 65536.0, - segment->correspondence[j].toCoord / 65536.0 )); + (double)segment->correspondence[j].fromCoord / 65536, + (double)segment->correspondence[j].toCoord / 65536 )); } FT_TRACE5(( "\n" )); } +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION + if ( version < 0x00020000L ) + goto Exit; + + axisMap_offset = FT_GET_ULONG(); + store_offset = FT_GET_ULONG(); + + if ( store_offset ) + { + error = tt_var_load_item_variation_store( + FT_FACE( face ), + table_offset + store_offset, + &table->itemStore ); + if ( error ) + goto Exit; + } + + if ( axisMap_offset ) + { + error = tt_var_load_delta_set_index_mapping( + FT_FACE( face ), + table_offset + axisMap_offset, + &table->axisMap, + &table->itemStore, + table_len ); + if ( error ) + goto Exit; + } +#endif + + Exit: FT_FRAME_EXIT(); } - static FT_Error - ft_var_load_item_variation_store( TT_Face face, + FT_LOCAL_DEF( FT_Error ) + tt_var_load_item_variation_store( FT_Face face, /* TT_Face */ FT_ULong offset, GX_ItemVarStore itemStore ) { + TT_Face ttface = (TT_Face)face; FT_Stream stream = FT_FACE_STREAM( face ); FT_Memory memory = stream->memory; FT_Error error; FT_UShort format; FT_ULong region_offset; - FT_UInt i, j, k; - FT_UInt wordDeltaCount; - FT_Bool long_words; - GX_Blend blend = face->blend; - GX_ItemVarData varData; + FT_UInt data_count; + FT_UShort axis_count; + FT_UInt region_count; + FT_UInt i, j; + FT_Bool long_words; + + GX_Blend blend = ttface->blend; FT_ULong* dataOffsetArray = NULL; @@ -465,31 +522,31 @@ if ( format != 1 ) { - FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n", + FT_TRACE2(( "tt_var_load_item_variation_store: bad store format %d\n", format )); error = FT_THROW( Invalid_Table ); goto Exit; } /* read top level fields */ - if ( FT_READ_ULONG( region_offset ) || - FT_READ_USHORT( itemStore->dataCount ) ) + if ( FT_READ_ULONG( region_offset ) || + FT_READ_USHORT( data_count ) ) goto Exit; /* we need at least one entry in `itemStore->varData' */ - if ( !itemStore->dataCount ) + if ( !data_count ) { - FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" )); + FT_TRACE2(( "tt_var_load_item_variation_store: missing varData\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } /* make temporary copy of item variation data offsets; */ /* we will parse region list first, then come back */ - if ( FT_QNEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) + if ( FT_QNEW_ARRAY( dataOffsetArray, data_count ) ) goto Exit; - for ( i = 0; i < itemStore->dataCount; i++ ) + for ( i = 0; i < data_count; i++ ) { if ( FT_READ_ULONG( dataOffsetArray[i] ) ) goto Exit; @@ -499,39 +556,40 @@ if ( FT_STREAM_SEEK( offset + region_offset ) ) goto Exit; - if ( FT_READ_USHORT( itemStore->axisCount ) || - FT_READ_USHORT( itemStore->regionCount ) ) + if ( FT_READ_USHORT( axis_count ) || + FT_READ_USHORT( region_count ) ) goto Exit; - if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis ) + if ( axis_count != (FT_Long)blend->mmvar->num_axis ) { - FT_TRACE2(( "ft_var_load_item_variation_store:" + FT_TRACE2(( "tt_var_load_item_variation_store:" " number of axes in item variation store\n" )); FT_TRACE2(( " " " and `fvar' table are different\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + itemStore->axisCount = axis_count; /* new constraint in OpenType 1.8.4 */ - if ( itemStore->regionCount >= 32768U ) + if ( region_count >= 32768U ) { - FT_TRACE2(( "ft_var_load_item_variation_store:" + FT_TRACE2(( "tt_var_load_item_variation_store:" " too many variation region tables\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } - if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) ) + if ( FT_NEW_ARRAY( itemStore->varRegionList, region_count ) ) goto Exit; + itemStore->regionCount = region_count; for ( i = 0; i < itemStore->regionCount; i++ ) { GX_AxisCoords axisCoords; - if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, - itemStore->axisCount ) ) + if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, axis_count ) ) goto Exit; axisCoords = itemStore->varRegionList[i].axisList; @@ -555,47 +613,56 @@ /* end of region list parse */ /* use dataOffsetArray now to parse varData items */ - if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) ) + if ( FT_NEW_ARRAY( itemStore->varData, data_count ) ) goto Exit; + itemStore->dataCount = data_count; - for ( i = 0; i < itemStore->dataCount; i++ ) + for ( i = 0; i < data_count; i++ ) { - varData = &itemStore->varData[i]; + GX_ItemVarData varData = &itemStore->varData[i]; + + FT_UInt item_count; + FT_UShort word_delta_count; + FT_UInt region_idx_count; + FT_UInt per_region_size; + if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) ) goto Exit; - if ( FT_READ_USHORT( varData->itemCount ) || - FT_READ_USHORT( wordDeltaCount ) || - FT_READ_USHORT( varData->regionIdxCount ) ) + if ( FT_READ_USHORT( item_count ) || + FT_READ_USHORT( word_delta_count ) || + FT_READ_USHORT( region_idx_count ) ) goto Exit; - long_words = !!( wordDeltaCount & 0x8000 ); - wordDeltaCount &= 0x7FFF; + long_words = !!( word_delta_count & 0x8000 ); + word_delta_count &= 0x7FFF; /* check some data consistency */ - if ( wordDeltaCount > varData->regionIdxCount ) + if ( word_delta_count > region_idx_count ) { FT_TRACE2(( "bad short count %d or region count %d\n", - wordDeltaCount, - varData->regionIdxCount )); + word_delta_count, + region_idx_count )); error = FT_THROW( Invalid_Table ); goto Exit; } - if ( varData->regionIdxCount > itemStore->regionCount ) + if ( region_idx_count > itemStore->regionCount ) { FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n", - varData->regionIdxCount, + region_idx_count, i )); error = FT_THROW( Invalid_Table ); goto Exit; } /* parse region indices */ - if ( FT_NEW_ARRAY( varData->regionIndices, - varData->regionIdxCount ) ) + if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) ) goto Exit; + varData->regionIdxCount = region_idx_count; + varData->wordDeltaCount = word_delta_count; + varData->longWords = long_words; for ( j = 0; j < varData->regionIdxCount; j++ ) { @@ -611,56 +678,22 @@ } } - /* Parse delta set. */ - /* */ - /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes */ - /* each if `long_words` isn't set, and twice as much otherwise. */ - /* */ - /* On output, deltas are expanded to `regionIdxCount` shorts each. */ - if ( FT_NEW_ARRAY( varData->deltaSet, - varData->regionIdxCount * varData->itemCount ) ) - goto Exit; - - /* the delta set is stored as a 2-dimensional array of shorts */ + per_region_size = word_delta_count + region_idx_count; if ( long_words ) - { - /* new in OpenType 1.9, currently for 'COLR' table only; */ - /* the deltas are interpreted as 16.16 fixed-point scaling values */ - - /* not supported yet */ + per_region_size *= 2; + if ( FT_NEW_ARRAY( varData->deltaSet, per_region_size * item_count ) ) + goto Exit; + if ( FT_Stream_Read( stream, + varData->deltaSet, + per_region_size * item_count ) ) + { + FT_TRACE2(( "deltaSet read failed." )); error = FT_THROW( Invalid_Table ); goto Exit; } - else - { - for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) - { - for ( k = 0; k < wordDeltaCount; k++, j++ ) - { - /* read the short deltas */ - FT_Short delta; - - if ( FT_READ_SHORT( delta ) ) - goto Exit; - - varData->deltaSet[j] = delta; - } - - for ( ; k < varData->regionIdxCount; k++, j++ ) - { - /* read the (signed) byte deltas */ - FT_Char delta; - - - if ( FT_READ_CHAR( delta ) ) - goto Exit; - - varData->deltaSet[j] = delta; - } - } - } + varData->itemCount = item_count; } Exit: @@ -670,8 +703,8 @@ } - static FT_Error - ft_var_load_delta_set_index_mapping( TT_Face face, + FT_LOCAL_DEF( FT_Error ) + tt_var_load_delta_set_index_mapping( FT_Face face, /* TT_Face */ FT_ULong offset, GX_DeltaSetIdxMap map, GX_ItemVarStore itemStore, @@ -728,7 +761,7 @@ /* rough sanity check */ if ( map->mapCount * entrySize > table_len ) { - FT_TRACE1(( "ft_var_load_delta_set_index_mapping:" + FT_TRACE1(( "tt_var_load_delta_set_index_mapping:" " invalid number of delta-set index mappings\n" )); error = FT_THROW( Invalid_Table ); goto Exit; @@ -758,6 +791,16 @@ mapData = ( mapData << 8 ) | data; } + /* new in OpenType 1.8.4 */ + if ( mapData == 0xFFFFFFFFUL ) + { + /* no variation data for this item */ + map->outerIndex[i] = 0xFFFFU; + map->innerIndex[i] = 0xFFFFU; + + continue; + } + outerIndex = mapData >> innerBitCount; if ( outerIndex >= itemStore->dataCount ) @@ -887,8 +930,8 @@ table = blend->hvar_table; } - error = ft_var_load_item_variation_store( - face, + error = tt_var_load_item_variation_store( + FT_FACE( face ), table_offset + store_offset, &table->itemStore ); if ( error ) @@ -896,8 +939,8 @@ if ( widthMap_offset ) { - error = ft_var_load_delta_set_index_mapping( - face, + error = tt_var_load_delta_set_index_mapping( + FT_FACE( face ), table_offset + widthMap_offset, &table->widthMap, &table->itemStore, @@ -938,26 +981,86 @@ } - static FT_Int - ft_var_get_item_delta( TT_Face face, + FT_LOCAL_DEF( FT_ItemVarDelta ) + tt_var_get_item_delta( FT_Face face, /* TT_Face */ GX_ItemVarStore itemStore, FT_UInt outerIndex, FT_UInt innerIndex ) { - GX_ItemVarData varData; - FT_Short* deltaSet; + TT_Face ttface = (TT_Face)face; + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + GX_ItemVarData varData; + FT_ItemVarDelta* deltaSet = NULL; + FT_ItemVarDelta deltaSetStack[16]; + + FT_Fixed* scalars = NULL; + FT_Fixed scalarsStack[16]; + + FT_UInt master, j; + FT_ItemVarDelta returnValue = 0; + FT_UInt per_region_size; + FT_Byte* bytes; + - FT_UInt master, j; - FT_Fixed netAdjustment = 0; /* accumulated adjustment */ - FT_Fixed scaledDelta; - FT_Fixed delta; + if ( !ttface->blend || !ttface->blend->normalizedcoords ) + return 0; + /* OpenType 1.8.4+: No variation data for this item */ + /* as indices have special value 0xFFFF. */ + if ( outerIndex == 0xFFFF && innerIndex == 0xFFFF ) + return 0; /* See pseudo code from `Font Variations Overview' */ /* in the OpenType specification. */ - varData = &itemStore->varData[outerIndex]; - deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex]; + if ( outerIndex >= itemStore->dataCount ) + return 0; /* Out of range. */ + + varData = &itemStore->varData[outerIndex]; + + if ( innerIndex >= varData->itemCount ) + return 0; /* Out of range. */ + + if ( varData->regionIdxCount < 16 ) + { + deltaSet = deltaSetStack; + scalars = scalarsStack; + } + else + { + if ( FT_QNEW_ARRAY( deltaSet, varData->regionIdxCount ) ) + goto Exit; + if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) ) + goto Exit; + } + + /* Parse delta set. */ + /* */ + /* Deltas are (word_delta_count + region_idx_count) bytes each */ + /* if `longWords` isn't set, and twice as much otherwise. */ + per_region_size = varData->wordDeltaCount + varData->regionIdxCount; + if ( varData->longWords ) + per_region_size *= 2; + + bytes = varData->deltaSet + per_region_size * innerIndex; + + if ( varData->longWords ) + { + for ( master = 0; master < varData->wordDeltaCount; master++ ) + deltaSet[master] = FT_NEXT_LONG( bytes ); + for ( ; master < varData->regionIdxCount; master++ ) + deltaSet[master] = FT_NEXT_SHORT( bytes ); + } + else + { + for ( master = 0; master < varData->wordDeltaCount; master++ ) + deltaSet[master] = FT_NEXT_SHORT( bytes ); + for ( ; master < varData->regionIdxCount; master++ ) + deltaSet[master] = FT_NEXT_CHAR( bytes ); + } /* outer loop steps through master designs to be blended */ for ( master = 0; master < varData->regionIdxCount; master++ ) @@ -986,40 +1089,59 @@ else if ( axis->peakCoord == 0 ) continue; - else if ( face->blend->normalizedcoords[j] == axis->peakCoord ) + else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord ) continue; /* ignore this region if coords are out of range */ - else if ( face->blend->normalizedcoords[j] <= axis->startCoord || - face->blend->normalizedcoords[j] >= axis->endCoord ) + else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord || + ttface->blend->normalizedcoords[j] >= axis->endCoord ) { scalar = 0; break; } /* cumulative product of all the axis scalars */ - else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) + else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord ) scalar = FT_MulDiv( scalar, - face->blend->normalizedcoords[j] - axis->startCoord, + ttface->blend->normalizedcoords[j] - axis->startCoord, axis->peakCoord - axis->startCoord ); else scalar = FT_MulDiv( scalar, - axis->endCoord - face->blend->normalizedcoords[j], + axis->endCoord - ttface->blend->normalizedcoords[j], axis->endCoord - axis->peakCoord ); - } /* per-axis loop */ - /* get the scaled delta for this region */ - delta = FT_intToFixed( deltaSet[master] ); - scaledDelta = FT_MulFix( scalar, delta ); + } /* per-axis loop */ - /* accumulate the adjustments from each region */ - netAdjustment = netAdjustment + scaledDelta; + scalars[master] = scalar; } /* per-region loop */ - return FT_fixedToInt( netAdjustment ); + + /* Compute the scaled delta for this region. + * + * From: https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables: + * + * `Fixed` is a 32-bit (16.16) type and, in the general case, requires + * 32-bit deltas. As described above, the `DeltaSet` record can + * accommodate deltas that are, logically, either 16-bit or 32-bit. + * When scaled deltas are applied to `Fixed` values, the `Fixed` value + * is treated like a 32-bit integer. + * + * `FT_MulAddFix` internally uses 64-bit precision; it thus can handle + * deltas ranging from small 8-bit to large 32-bit values that are + * applied to 16.16 `FT_Fixed` / OpenType `Fixed` values. + */ + returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount ); + + Exit: + if ( scalars != scalarsStack ) + FT_FREE( scalars ); + if ( deltaSet != deltaSetStack ) + FT_FREE( deltaSet ); + + return returnValue; } @@ -1112,35 +1234,27 @@ } else { - GX_ItemVarData varData; - - /* no widthMap data */ outerIndex = 0; innerIndex = gindex; - - varData = &table->itemStore.varData[outerIndex]; - if ( gindex >= varData->itemCount ) - { - FT_TRACE2(( "gindex %d out of range\n", gindex )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } } - delta = ft_var_get_item_delta( face, + delta = tt_var_get_item_delta( FT_FACE( face ), &table->itemStore, outerIndex, innerIndex ); - FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n", - vertical ? "vertical height" : "horizontal width", - *avalue, - delta, - delta == 1 ? "" : "s", - vertical ? "VVAR" : "HVAR" )); - - *avalue += delta; + if ( delta ) + { + FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n", + vertical ? "vertical height" : "horizontal width", + *avalue, + delta, + delta == 1 ? "" : "s", + vertical ? "VVAR" : "HVAR" )); + + *avalue = ADD_INT( *avalue, delta ); + } Exit: return error; @@ -1148,20 +1262,20 @@ FT_LOCAL_DEF( FT_Error ) - tt_hadvance_adjust( TT_Face face, + tt_hadvance_adjust( FT_Face face, /* TT_Face */ FT_UInt gindex, FT_Int *avalue ) { - return tt_hvadvance_adjust( face, gindex, avalue, 0 ); + return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 0 ); } FT_LOCAL_DEF( FT_Error ) - tt_vadvance_adjust( TT_Face face, + tt_vadvance_adjust( FT_Face face, /* TT_Face */ FT_UInt gindex, FT_Int *avalue ) { - return tt_hvadvance_adjust( face, gindex, avalue, 1 ); + return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 1 ); } @@ -1307,8 +1421,8 @@ records_offset = FT_STREAM_POS(); - error = ft_var_load_item_variation_store( - face, + error = tt_var_load_item_variation_store( + FT_FACE( face ), table_offset + store_offset, &blend->mvar_table->itemStore ); if ( error ) @@ -1323,7 +1437,7 @@ return; value = blend->mvar_table->values; - limit = value + blend->mvar_table->valueCount; + limit = FT_OFFSET( value, blend->mvar_table->valueCount ); itemStore = &blend->mvar_table->itemStore; for ( ; value < limit; value++ ) @@ -1332,6 +1446,13 @@ value->outerIndex = FT_GET_USHORT(); value->innerIndex = FT_GET_USHORT(); + /* new in OpenType 1.8.4 */ + if ( value->outerIndex == 0xFFFFU && value->innerIndex == 0xFFFFU ) + { + /* no variation data for this item */ + continue; + } + if ( value->outerIndex >= itemStore->dataCount || value->innerIndex >= itemStore->varData[value->outerIndex] .itemCount ) @@ -1349,7 +1470,7 @@ FT_TRACE2(( "loaded\n" )); value = blend->mvar_table->values; - limit = value + blend->mvar_table->valueCount; + limit = FT_OFFSET( value, blend->mvar_table->valueCount ); /* save original values of the data MVAR is going to modify */ for ( ; value < limit; value++ ) @@ -1374,15 +1495,14 @@ static FT_Error - tt_size_reset_iterator( FT_ListNode node, + ft_size_reset_iterator( FT_ListNode node, void* user ) { - TT_Size size = (TT_Size)node->data; - - FT_UNUSED( user ); + FT_Size size = (FT_Size)node->data; + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)user; - tt_size_reset( size, 1 ); + var->size_reset( size ); return FT_Err_Ok; } @@ -1401,33 +1521,36 @@ * The font face. */ FT_LOCAL_DEF( void ) - tt_apply_mvar( TT_Face face ) + tt_apply_mvar( FT_Face face ) /* TT_Face */ { - GX_Blend blend = face->blend; + TT_Face ttface = (TT_Face)face; + + GX_Blend blend = ttface->blend; GX_Value value, limit; + FT_Short mvar_hasc_delta = 0; FT_Short mvar_hdsc_delta = 0; FT_Short mvar_hlgp_delta = 0; - if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) + if ( !( ttface->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) return; value = blend->mvar_table->values; - limit = value + blend->mvar_table->valueCount; + limit = FT_OFFSET( value, blend->mvar_table->valueCount ); for ( ; value < limit; value++ ) { - FT_Short* p = ft_var_get_value_pointer( face, value->tag ); + FT_Short* p = ft_var_get_value_pointer( ttface, value->tag ); FT_Int delta; - delta = ft_var_get_item_delta( face, + delta = tt_var_get_item_delta( face, &blend->mvar_table->itemStore, value->outerIndex, value->innerIndex ); - if ( p ) + if ( p && delta ) { FT_TRACE5(( "value %c%c%c%c (%d unit%s) adjusted by %d unit%s (MVAR)\n", (FT_Char)( value->tag >> 24 ), @@ -1455,7 +1578,8 @@ /* adjust all derived values */ { - FT_Face root = &face->root; + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)ttface->face_var; /* * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender, @@ -1483,24 +1607,25 @@ * whether they were actually changed or the font had the OS/2 table's * fsSelection's bit 7 (USE_TYPO_METRICS) set. */ - FT_Short current_line_gap = root->height - root->ascender + - root->descender; + FT_Short current_line_gap = face->height - face->ascender + + face->descender; - root->ascender = root->ascender + mvar_hasc_delta; - root->descender = root->descender + mvar_hdsc_delta; - root->height = root->ascender - root->descender + + face->ascender = face->ascender + mvar_hasc_delta; + face->descender = face->descender + mvar_hdsc_delta; + face->height = face->ascender - face->descender + current_line_gap + mvar_hlgp_delta; - root->underline_position = face->postscript.underlinePosition - - face->postscript.underlineThickness / 2; - root->underline_thickness = face->postscript.underlineThickness; + face->underline_position = ttface->postscript.underlinePosition - + ttface->postscript.underlineThickness / 2; + face->underline_thickness = ttface->postscript.underlineThickness; - /* iterate over all FT_Size objects and call `tt_size_reset' */ - /* to propagate the metrics changes */ - FT_List_Iterate( &root->sizes_list, - tt_size_reset_iterator, - NULL ); + /* iterate over all FT_Size objects and call `var->size_reset' */ + /* to propagate the metrics changes */ + if ( var && var->size_reset ) + FT_List_Iterate( &face->sizes_list, + ft_size_reset_iterator, + (void*)var ); } } @@ -1725,7 +1850,7 @@ blend->tuplecoords[i * gvar_head.axisCount + j] = FT_fdot14ToFixed( FT_GET_SHORT() ); FT_TRACE5(( "%.5f ", - blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); + (double)blend->tuplecoords[i * gvar_head.axisCount + j] / 65536 )); } FT_TRACE5(( "]\n" )); } @@ -1796,7 +1921,7 @@ for ( i = 0; i < blend->num_axis; i++ ) { FT_TRACE6(( " axis %d coordinate %.5f:\n", - i, blend->normalizedcoords[i] / 65536.0 )); + i, (double)blend->normalizedcoords[i] / 65536 )); /* It's not clear why (for intermediate tuples) we don't need */ /* to check against start/end -- the documentation says we don't. */ @@ -1819,7 +1944,7 @@ if ( blend->normalizedcoords[i] == tuple_coords[i] ) { FT_TRACE6(( " tuple coordinate %.5f fits perfectly\n", - tuple_coords[i] / 65536.0 )); + (double)tuple_coords[i] / 65536 )); /* `apply' does not change */ continue; } @@ -1832,13 +1957,13 @@ blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) { FT_TRACE6(( " tuple coordinate %.5f is exceeded, stop\n", - tuple_coords[i] / 65536.0 )); + (double)tuple_coords[i] / 65536 )); apply = 0; break; } FT_TRACE6(( " tuple coordinate %.5f fits\n", - tuple_coords[i] / 65536.0 )); + (double)tuple_coords[i] / 65536 )); apply = FT_MulDiv( apply, blend->normalizedcoords[i], tuple_coords[i] ); @@ -1852,15 +1977,15 @@ { FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ is exceeded," " stop\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); + (double)im_start_coords[i] / 65536, + (double)im_end_coords[i] / 65536 )); apply = 0; break; } FT_TRACE6(( " intermediate tuple range ]%.5f;%.5f[ fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); + (double)im_start_coords[i] / 65536, + (double)im_end_coords[i] / 65536 )); if ( blend->normalizedcoords[i] < tuple_coords[i] ) apply = FT_MulDiv( apply, blend->normalizedcoords[i] - im_start_coords[i], @@ -1872,7 +1997,7 @@ } } - FT_TRACE6(( " apply factor is %.5f\n", apply / 65536.0 )); + FT_TRACE6(( " apply factor is %.5f\n", (double)apply / 65536 )); return apply; } @@ -1886,12 +2011,18 @@ FT_Fixed* coords, FT_Fixed* normalized ) { + FT_Error error = FT_Err_Ok; + FT_Memory memory = face->root.memory; + FT_UInt i, j; + GX_Blend blend; FT_MM_Var* mmvar; - FT_UInt i, j; FT_Var_Axis* a; GX_AVarSegment av; + FT_Fixed* new_normalized = NULL; + FT_Fixed* old_normalized; + blend = face->blend; mmvar = blend->mmvar; @@ -1914,15 +2045,15 @@ FT_Fixed coord = coords[i]; - FT_TRACE5(( " %d: %.5f\n", i, coord / 65536.0 )); + FT_TRACE5(( " %d: %.5f\n", i, (double)coord / 65536 )); if ( coord > a->maximum || coord < a->minimum ) { FT_TRACE1(( "ft_var_to_normalized: design coordinate %.5f\n", - coord / 65536.0 )); + (double)coord / 65536 )); FT_TRACE1(( " is out of range [%.5f;%.5f];" " clamping\n", - a->minimum / 65536.0, - a->maximum / 65536.0 )); + (double)a->minimum / 65536, + (double)a->maximum / 65536 )); } if ( coord > a->def ) @@ -1942,30 +2073,91 @@ for ( ; i < mmvar->num_axis; i++ ) normalized[i] = 0; - if ( blend->avar_segment ) + if ( blend->avar_table ) { + GX_AVarTable table = blend->avar_table; + + FT_TRACE5(( "normalized design coordinates" " before applying `avar' data:\n" )); - av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; i++, av++ ) + if ( table->avar_segment ) { - for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + av = table->avar_segment; + + for ( i = 0; i < mmvar->num_axis; i++, av++ ) { - if ( normalized[i] < av->correspondence[j].fromCoord ) + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) { - FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 )); + if ( normalized[i] < av->correspondence[j].fromCoord ) + { + FT_TRACE5(( " %.5f\n", (double)normalized[i] / 65536 )); + + normalized[i] = + FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord ) + + av->correspondence[j - 1].toCoord; + break; + } + } + } + } - normalized[i] = - FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, - av->correspondence[j].toCoord - - av->correspondence[j - 1].toCoord, - av->correspondence[j].fromCoord - - av->correspondence[j - 1].fromCoord ) + - av->correspondence[j - 1].toCoord; - break; + if ( table->itemStore.varData ) + { + if ( FT_QNEW_ARRAY( new_normalized, mmvar->num_axis ) ) + return; + + /* Install our half-normalized coordinates for the next */ + /* Item Variation Store to work with. */ + old_normalized = face->blend->normalizedcoords; + face->blend->normalizedcoords = normalized; + + for ( i = 0; i < mmvar->num_axis; i++ ) + { + FT_Fixed v = normalized[i]; + FT_UInt innerIndex = i; + FT_UInt outerIndex = 0; + FT_Int delta; + + + if ( table->axisMap.innerIndex ) + { + FT_UInt idx = i; + + + if ( idx >= table->axisMap.mapCount ) + idx = table->axisMap.mapCount - 1; + + outerIndex = table->axisMap.outerIndex[idx]; + innerIndex = table->axisMap.innerIndex[idx]; } + + delta = tt_var_get_item_delta( FT_FACE( face ), + &table->itemStore, + outerIndex, + innerIndex ); + + v += delta << 2; + + /* Clamp value range. */ + v = v >= 0x10000L ? 0x10000 : v; + v = v <= -0x10000L ? -0x10000 : v; + + new_normalized[i] = v; } + + for ( i = 0; i < mmvar->num_axis; i++ ) + { + normalized[i] = new_normalized[i]; + } + + face->blend->normalizedcoords = old_normalized; + + FT_FREE( new_normalized ); } } } @@ -2003,9 +2195,9 @@ for ( ; i < num_coords; i++ ) design[i] = 0; - if ( blend->avar_segment ) + if ( blend->avar_table && blend->avar_table->avar_segment ) { - GX_AVarSegment av = blend->avar_segment; + GX_AVarSegment av = blend->avar_table->avar_segment; FT_TRACE5(( "design coordinates" @@ -2025,7 +2217,7 @@ av->correspondence[j - 1].toCoord ) + av->correspondence[j - 1].fromCoord; - FT_TRACE5(( " %.5f\n", design[i] / 65536.0 )); + FT_TRACE5(( " %.5f\n", (double)design[i] / 65536 )); break; } } @@ -2106,11 +2298,12 @@ * FreeType error code. 0 means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Var( TT_Face face, + TT_Get_MM_Var( FT_Face face, /* TT_Face */ FT_MM_Var* *master ) { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; + TT_Face ttface = (TT_Face)face; + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = FT_FACE_MEMORY( face ); FT_ULong table_len; FT_Error error = FT_Err_Ok; FT_ULong fvar_start = 0; @@ -2170,32 +2363,23 @@ FT_FRAME_END }; + /* `num_instances` holds the number of all named instances including */ + /* the default instance, which might be missing in the table of named */ + /* instances (in 'fvar'). This value is validated in `sfobjs.c` and */ + /* may be reset to 0 if consistency checks fail. */ + num_instances = (FT_UInt)face->style_flags >> 16; /* read the font data and set up the internal representation */ /* if not already done */ - need_init = !face->blend; + need_init = !ttface->blend; if ( need_init ) { FT_TRACE2(( "FVAR " )); - /* both `fvar' and `gvar' must be present */ - if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar, - stream, &table_len ) ) ) - { - /* CFF2 is an alternate to gvar here */ - if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2, + if ( FT_SET_ERROR( ttface->goto_table( ttface, TTAG_fvar, stream, &table_len ) ) ) - { - FT_TRACE1(( "\n" )); - FT_TRACE1(( "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); - goto Exit; - } - } - - if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar, - stream, &table_len ) ) ) { FT_TRACE1(( "is missing\n" )); goto Exit; @@ -2208,6 +2392,17 @@ if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) goto Exit; + /* If `num_instances` is larger, synthetization of the default */ + /* instance is required. If `num_instances` is smaller, */ + /* however, the value has been reset to 0 in `sfnt_init_face` */ + /* (in `sfobjs.c`); in this case we have underallocated `mmvar` */ + /* structs. */ + if ( num_instances < fvar_head.instanceCount ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + usePsName = FT_BOOL( fvar_head.instanceSize == 6 + 4 * fvar_head.axisCount ); @@ -2217,19 +2412,14 @@ fvar_head.axisCount, fvar_head.axisCount == 1 ? "is" : "es" )); - if ( FT_NEW( face->blend ) ) + if ( FT_NEW( ttface->blend ) ) goto Exit; - num_axes = fvar_head.axisCount; - face->blend->num_axis = num_axes; + num_axes = fvar_head.axisCount; + ttface->blend->num_axis = num_axes; } else - num_axes = face->blend->num_axis; - - /* `num_instances' holds the number of all named instances, */ - /* including the default instance which might be missing */ - /* in fvar's table of named instances */ - num_instances = (FT_UInt)face->root.style_flags >> 16; + num_axes = ttface->blend->num_axis; /* prepare storage area for MM data; this cannot overflow */ /* 32-bit arithmetic because of the size limits used in the */ @@ -2258,16 +2448,16 @@ if ( need_init ) { - face->blend->mmvar_len = mmvar_size + - axis_flags_size + - axis_size + - namedstyle_size + - next_coords_size + - next_name_size; - - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + ttface->blend->mmvar_len = mmvar_size + + axis_flags_size + + axis_size + + namedstyle_size + + next_coords_size + + next_name_size; + + if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) goto Exit; - face->blend->mmvar = mmvar; + ttface->blend->mmvar = mmvar; /* set up pointers and offsets into the `mmvar' array; */ /* the data gets filled in later on */ @@ -2358,9 +2548,9 @@ " %10.5f %10.5f %10.5f 0x%04X%s\n", i, a->name, - a->minimum / 65536.0, - a->def / 65536.0, - a->maximum / 65536.0, + (double)a->minimum / 65536, + (double)a->def / 65536, + (double)a->maximum / 65536, *axis_flags, invalid ? " (invalid, disabled)" : "" )); #endif @@ -2373,27 +2563,27 @@ /* named instance coordinates are stored as design coordinates; */ /* we have to convert them to normalized coordinates also */ - if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords, + if ( FT_NEW_ARRAY( ttface->blend->normalized_stylecoords, num_axes * num_instances ) ) goto Exit; - if ( fvar_head.instanceCount && !face->blend->avar_loaded ) + if ( fvar_head.instanceCount && !ttface->blend->avar_loaded ) { FT_ULong offset = FT_STREAM_POS(); - ft_var_load_avar( face ); + ft_var_load_avar( ttface ); if ( FT_STREAM_SEEK( offset ) ) goto Exit; } - FT_TRACE5(( "%d instance%s\n", + FT_TRACE5(( "%d named instance%s\n", fvar_head.instanceCount, fvar_head.instanceCount == 1 ? "" : "s" )); ns = mmvar->namedstyle; - nsc = face->blend->normalized_stylecoords; + nsc = ttface->blend->normalized_stylecoords; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { /* PostScript names add 2 bytes to the instance record size */ @@ -2416,7 +2606,7 @@ #ifdef FT_DEBUG_LEVEL_TRACE { - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_String* strname = NULL; FT_String* psname = NULL; @@ -2428,7 +2618,7 @@ if ( ns->strid != 0xFFFF ) { - (void)sfnt->get_name( face, + (void)sfnt->get_name( ttface, (FT_UShort)ns->strid, &strname ); if ( strname && !ft_strcmp( strname, ".notdef" ) ) @@ -2437,7 +2627,7 @@ if ( ns->psid != 0xFFFF ) { - (void)sfnt->get_name( face, + (void)sfnt->get_name( ttface, (FT_UShort)ns->psid, &psname ); if ( psname && !ft_strcmp( psname, ".notdef" ) ) @@ -2446,7 +2636,7 @@ (void)FT_STREAM_SEEK( pos ); - FT_TRACE5(( " instance %d (%s%s%s, %s%s%s)\n", + FT_TRACE5(( " named instance %d (%s%s%s, %s%s%s)\n", i, strname ? "name: `" : "", strname ? strname : "unnamed", @@ -2460,7 +2650,7 @@ } #endif /* FT_DEBUG_LEVEL_TRACE */ - ft_var_to_normalized( face, num_axes, ns->coords, nsc ); + ft_var_to_normalized( ttface, num_axes, ns->coords, nsc ); nsc += num_axes; FT_FRAME_EXIT(); @@ -2468,15 +2658,17 @@ if ( num_instances != fvar_head.instanceCount ) { - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Int found, dummy1, dummy2; FT_UInt strid = ~0U; - /* the default instance is missing in array the */ - /* of named instances; try to synthesize an entry */ - found = sfnt->get_name_id( face, + /* The default instance is missing in array the */ + /* of named instances; try to synthesize an entry. */ + /* If this fails, `default_named_instance` remains */ + /* at value zero, which doesn't do any harm. */ + found = sfnt->get_name_id( ttface, TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, &dummy1, &dummy2 ); @@ -2484,7 +2676,7 @@ strid = TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY; else { - found = sfnt->get_name_id( face, + found = sfnt->get_name_id( ttface, TT_NAME_ID_FONT_SUBFAMILY, &dummy1, &dummy2 ); @@ -2494,7 +2686,7 @@ if ( found ) { - found = sfnt->get_name_id( face, + found = sfnt->get_name_id( ttface, TT_NAME_ID_PS_NAME, &dummy1, &dummy2 ); @@ -2503,6 +2695,9 @@ FT_TRACE5(( "TT_Get_MM_Var:" " Adding default instance to named instances\n" )); + /* named instance indices start with value 1 */ + ttface->var_default_named_instance = num_instances; + ns = &mmvar->namedstyle[fvar_head.instanceCount]; ns->strid = strid; @@ -2516,7 +2711,7 @@ } } - ft_var_load_mvar( face ); + ft_var_load_mvar( ttface ); } /* fill the output array if requested */ @@ -2526,9 +2721,9 @@ FT_UInt n; - if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) ) goto Exit; - FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len ); axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size ); @@ -2561,6 +2756,8 @@ a->name = (char*)"OpticalSize"; else if ( a->tag == TTAG_slnt ) a->name = (char*)"Slant"; + else if ( a->tag == TTAG_ital ) + a->name = (char*)"Italic"; next_name += 5; a++; @@ -2602,7 +2799,7 @@ if ( !face->blend ) { - if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + if ( FT_SET_ERROR( TT_Get_MM_Var( FT_FACE( face ), NULL ) ) ) goto Exit; } @@ -2622,11 +2819,11 @@ for ( i = 0; i < num_coords; i++ ) { - FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); + FT_TRACE5(( " %.5f\n", (double)coords[i] / 65536 )); if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n", - coords[i] / 65536.0 )); + (double)coords[i] / 65536 )); FT_TRACE1(( " is out of range [-1;1]\n" )); error = FT_THROW( Invalid_Argument ); goto Exit; @@ -2636,8 +2833,16 @@ FT_TRACE5(( "\n" )); if ( !face->is_cff2 && !blend->glyphoffsets ) - if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) ) + { + /* While a missing 'gvar' table is acceptable, for example for */ + /* fonts that only vary metrics information or 'COLR' v1 */ + /* `PaintVar*` tables, an incorrect SFNT table offset or size */ + /* for 'gvar', or an inconsistent 'gvar' table is not. */ + error = ft_var_load_gvar( face ); + if ( error != FT_Err_Table_Missing && error != FT_Err_Ok ) goto Exit; + error = FT_Err_Ok; + } if ( !blend->coords ) { @@ -2679,26 +2884,29 @@ } } - if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + if ( !have_diff ) { - FT_UInt instance_index = (FT_UInt)face->root.face_index >> 16; + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt instance_index = (FT_UInt)face->root.face_index >> 16; - c = blend->normalizedcoords + i; - n = blend->normalized_stylecoords + - ( instance_index - 1 ) * mmvar->num_axis + - i; + c = blend->normalizedcoords + i; + n = blend->normalized_stylecoords + + ( instance_index - 1 ) * 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; + 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' */ @@ -2762,9 +2970,6 @@ } } - /* enforce recomputation of the PostScript name; */ - FT_FREE( face->postscript_name ); - Exit: return error; } @@ -2796,26 +3001,15 @@ * An array of `num_coords', each between [-1,1]. * * @Return: - * FreeType error code. 0 means success. + * FreeType error code. 0 means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_MM_Blend( TT_Face face, + TT_Set_MM_Blend( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error; - - - error = tt_set_mm_blend( face, num_coords, coords, 1 ); - if ( error ) - return error; - - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - - return FT_Err_Ok; + return tt_set_mm_blend( (TT_Face)face, num_coords, coords, 1 ); } @@ -2843,31 +3037,34 @@ * An array of `num_coords', each between [-1,1]. * * @Return: - * FreeType error code. 0 means success. + * FreeType error code. 0 means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_MM_Blend( TT_Face face, + TT_Get_MM_Blend( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; GX_Blend blend; FT_UInt i, nc; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) return error; } - blend = face->blend; + blend = ttface->blend; if ( !blend->coords ) { /* select default instance coordinates */ /* if no instance is selected yet */ - if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) ) return error; } @@ -2880,7 +3077,7 @@ nc = blend->num_axis; } - if ( face->doblend ) + if ( ttface->doblend ) { for ( i = 0; i < nc; i++ ) coords[i] = blend->normalizedcoords[i]; @@ -2927,15 +3124,16 @@ * FreeType error code. 0 means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_Var_Design( TT_Face face, + TT_Set_Var_Design( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { + TT_Face ttface = (TT_Face)face; FT_Error error = FT_Err_Ok; GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i; - FT_Memory memory = face->root.memory; + FT_Memory memory = FT_FACE_MEMORY( face ); FT_Fixed* c; FT_Fixed* n; @@ -2944,13 +3142,13 @@ FT_Bool have_diff = 0; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } - blend = face->blend; + blend = ttface->blend; mmvar = blend->mmvar; if ( num_coords > mmvar->num_axis ) @@ -2978,13 +3176,13 @@ } } - if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + if ( FT_IS_NAMED_INSTANCE( face ) ) { FT_UInt instance_index; FT_Var_Named_Style* named_style; - instance_index = (FT_UInt)face->root.face_index >> 16; + instance_index = (FT_UInt)face->face_index >> 16; named_style = mmvar->namedstyle + instance_index - 1; n = named_style->coords + num_coords; @@ -3021,22 +3219,17 @@ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; - if ( !face->blend->avar_loaded ) - ft_var_load_avar( face ); + if ( !ttface->blend->avar_loaded ) + ft_var_load_avar( ttface ); FT_TRACE5(( "TT_Set_Var_Design:\n" )); FT_TRACE5(( " normalized design coordinates:\n" )); - ft_var_to_normalized( face, num_coords, blend->coords, normalized ); + ft_var_to_normalized( ttface, num_coords, blend->coords, normalized ); - error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); + error = tt_set_mm_blend( ttface, mmvar->num_axis, normalized, 0 ); if ( error ) goto Exit; - if ( num_coords ) - face->root.face_flags |= FT_FACE_FLAG_VARIATION; - else - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; - Exit: FT_FREE( normalized ); return error; @@ -3069,28 +3262,29 @@ * FreeType error code. 0~means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Get_Var_Design( TT_Face face, + TT_Get_Var_Design( FT_Face face, /* TT_Face */ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error = FT_Err_Ok; + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; GX_Blend blend; FT_UInt i, nc; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) return error; } - blend = face->blend; + blend = ttface->blend; if ( !blend->coords ) { /* select default instance coordinates */ /* if no instance is selected yet */ - if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) ) return error; } @@ -3103,7 +3297,7 @@ nc = blend->num_axis; } - if ( face->doblend ) + if ( ttface->doblend ) { for ( i = 0; i < nc; i++ ) coords[i] = blend->coords[i]; @@ -3139,29 +3333,33 @@ * Value 0 indicates to not use an instance. * * @Return: - * FreeType error code. 0~means success. + * FreeType error code. 0~means success, -1 means success and unchanged + * axis values. */ FT_LOCAL_DEF( FT_Error ) - TT_Set_Named_Instance( TT_Face face, + TT_Set_Named_Instance( FT_Face face, /* TT_Face */ FT_UInt instance_index ) { + TT_Face ttface = (TT_Face)face; FT_Error error; GX_Blend blend; FT_MM_Var* mmvar; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_UInt num_instances; - if ( !face->blend ) + if ( !ttface->blend ) { if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } - blend = face->blend; + blend = ttface->blend; mmvar = blend->mmvar; - num_instances = (FT_UInt)face->root.style_flags >> 16; + num_instances = (FT_UInt)face->style_flags >> 16; /* `instance_index' starts with value 1, thus `>' */ if ( instance_index > num_instances ) @@ -3172,8 +3370,7 @@ if ( instance_index > 0 ) { - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_Var_Named_Style* named_style; FT_String* style_name; @@ -3181,40 +3378,89 @@ named_style = mmvar->namedstyle + instance_index - 1; - error = sfnt->get_name( face, + error = sfnt->get_name( ttface, (FT_UShort)named_style->strid, &style_name ); if ( error ) goto Exit; /* set (or replace) style name */ - FT_FREE( face->root.style_name ); - face->root.style_name = style_name; + FT_FREE( face->style_name ); + face->style_name = style_name; /* finally, select the named instance */ error = TT_Set_Var_Design( face, mmvar->num_axis, named_style->coords ); - if ( error ) - { - /* internal error code -1 means `no change' */ - if ( error == -1 ) - error = FT_Err_Ok; - goto Exit; - } } else + { + /* restore non-VF style name */ + FT_FREE( face->style_name ); + if ( FT_STRDUP( face->style_name, ttface->non_var_style_name ) ) + goto Exit; error = TT_Set_Var_Design( face, 0, NULL ); + } + + Exit: + return error; + } + + + /************************************************************************** + * + * @Function: + * TT_Get_Default_Named_Instance + * + * @Description: + * Get the default named instance. + * + * @Input: + * face :: + * A handle to the source face. + * + * @Output: + * instance_index :: + * The default named instance index. + * + * @Return: + * FreeType error code. 0~means success. + */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ) + { + TT_Face ttface = (TT_Face)face; + FT_Error error = FT_Err_Ok; + + + if ( !ttface->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } - face->root.face_index = ( instance_index << 16 ) | - ( face->root.face_index & 0xFFFFL ); - face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + *instance_index = ttface->var_default_named_instance; Exit: return error; } + /* This function triggers (lazy) recomputation of the `postscript_name` */ + /* field in `TT_Face`. */ + + FT_LOCAL_DEF( void ) + tt_construct_ps_name( FT_Face face ) + { + TT_Face ttface = (TT_Face)face; + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( ttface->postscript_name ); + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -3503,10 +3749,10 @@ { FT_TRACE7(( " %d: %f -> %f\n", j, - ( FT_fdot6ToFixed( face->cvt[j] ) + - old_cvt_delta ) / 65536.0, - ( FT_fdot6ToFixed( face->cvt[j] ) + - cvt_deltas[j] ) / 65536.0 )); + (double)( FT_fdot6ToFixed( face->cvt[j] ) + + old_cvt_delta ) / 65536, + (double)( FT_fdot6ToFixed( face->cvt[j] ) + + cvt_deltas[j] ) / 65536 )); count++; } #endif @@ -3545,10 +3791,10 @@ { FT_TRACE7(( " %d: %f -> %f\n", pindex, - ( FT_fdot6ToFixed( face->cvt[pindex] ) + - old_cvt_delta ) / 65536.0, - ( FT_fdot6ToFixed( face->cvt[pindex] ) + - cvt_deltas[pindex] ) / 65536.0 )); + (double)( FT_fdot6ToFixed( face->cvt[pindex] ) + + old_cvt_delta ) / 65536, + (double)( FT_fdot6ToFixed( face->cvt[pindex] ) + + cvt_deltas[pindex] ) / 65536 )); count++; } #endif @@ -3813,20 +4059,12 @@ * @Description: * Apply the appropriate deltas to the current glyph. * - * @Input: - * face :: - * A handle to the target face object. - * - * glyph_index :: - * The index of the glyph being modified. - * - * n_points :: - * The number of the points in the glyph, including - * phantom points. - * * @InOut: + * loader :: + * A handle to the loader object. + * * outline :: - * The outline to change. + * The outline to change, with appended phantom points. * * @Output: * unrounded :: @@ -3837,15 +4075,16 @@ * FreeType error code. 0 means success. */ FT_LOCAL_DEF( FT_Error ) - TT_Vary_Apply_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, + TT_Vary_Apply_Glyph_Deltas( TT_Loader loader, FT_Outline* outline, - FT_Vector* unrounded, - FT_UInt n_points ) + FT_Vector* unrounded ) { FT_Error error; - FT_Stream stream = face->root.stream; - FT_Memory memory = stream->memory; + TT_Face face = loader->face; + FT_Stream stream = face->root.stream; + FT_Memory memory = stream->memory; + FT_UInt glyph_index = loader->glyph_index; + FT_UInt n_points = (FT_UInt)outline->n_points + 4; FT_Vector* points_org = NULL; /* coordinates in 16.16 format */ FT_Vector* points_out = NULL; /* coordinates in 16.16 format */ @@ -4063,50 +4302,22 @@ FT_Fixed point_delta_y = FT_MulFix( deltas_y[j], apply ); - if ( j < n_points - 4 ) - { - point_deltas_x[j] = old_point_delta_x + point_delta_x; - point_deltas_y[j] = old_point_delta_y + point_delta_y; - } - else - { - /* To avoid double adjustment of advance width or height, */ - /* adjust phantom points only if there is no HVAR or VVAR */ - /* support, respectively. */ - if ( j == ( n_points - 4 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_LSB ) ) - point_deltas_x[j] = old_point_delta_x + point_delta_x; - - else if ( j == ( n_points - 3 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_HADVANCE ) ) - point_deltas_x[j] = old_point_delta_x + point_delta_x; - - else if ( j == ( n_points - 2 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_TSB ) ) - point_deltas_y[j] = old_point_delta_y + point_delta_y; - - else if ( j == ( n_points - 1 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_VADVANCE ) ) - point_deltas_y[j] = old_point_delta_y + point_delta_y; - } + point_deltas_x[j] = old_point_delta_x + point_delta_x; + point_deltas_y[j] = old_point_delta_y + point_delta_y; #ifdef FT_DEBUG_LEVEL_TRACE if ( point_delta_x || point_delta_y ) { FT_TRACE7(( " %d: (%f, %f) -> (%f, %f)\n", j, - ( FT_intToFixed( outline->points[j].x ) + - old_point_delta_x ) / 65536.0, - ( FT_intToFixed( outline->points[j].y ) + - old_point_delta_y ) / 65536.0, - ( FT_intToFixed( outline->points[j].x ) + - point_deltas_x[j] ) / 65536.0, - ( FT_intToFixed( outline->points[j].y ) + - point_deltas_y[j] ) / 65536.0 )); + (double)( FT_intToFixed( outline->points[j].x ) + + old_point_delta_x ) / 65536, + (double)( FT_intToFixed( outline->points[j].y ) + + old_point_delta_y ) / 65536, + (double)( FT_intToFixed( outline->points[j].x ) + + point_deltas_x[j] ) / 65536, + (double)( FT_intToFixed( outline->points[j].y ) + + point_deltas_y[j] ) / 65536 )); count++; } #endif @@ -4165,50 +4376,22 @@ FT_Pos point_delta_y = points_out[j].y - points_org[j].y; - if ( j < n_points - 4 ) - { - point_deltas_x[j] = old_point_delta_x + point_delta_x; - point_deltas_y[j] = old_point_delta_y + point_delta_y; - } - else - { - /* To avoid double adjustment of advance width or height, */ - /* adjust phantom points only if there is no HVAR or VVAR */ - /* support, respectively. */ - if ( j == ( n_points - 4 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_LSB ) ) - point_deltas_x[j] = old_point_delta_x + point_delta_x; - - else if ( j == ( n_points - 3 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_HADVANCE ) ) - point_deltas_x[j] = old_point_delta_x + point_delta_x; - - else if ( j == ( n_points - 2 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_TSB ) ) - point_deltas_y[j] = old_point_delta_y + point_delta_y; - - else if ( j == ( n_points - 1 ) && - !( face->variation_support & - TT_FACE_FLAG_VAR_VADVANCE ) ) - point_deltas_y[j] = old_point_delta_y + point_delta_y; - } + point_deltas_x[j] = old_point_delta_x + point_delta_x; + point_deltas_y[j] = old_point_delta_y + point_delta_y; #ifdef FT_DEBUG_LEVEL_TRACE if ( point_delta_x || point_delta_y ) { FT_TRACE7(( " %d: (%f, %f) -> (%f, %f)\n", j, - ( FT_intToFixed( outline->points[j].x ) + - old_point_delta_x ) / 65536.0, - ( FT_intToFixed( outline->points[j].y ) + - old_point_delta_y ) / 65536.0, - ( FT_intToFixed( outline->points[j].x ) + - point_deltas_x[j] ) / 65536.0, - ( FT_intToFixed( outline->points[j].y ) + - point_deltas_y[j] ) / 65536.0 )); + (double)( FT_intToFixed( outline->points[j].x ) + + old_point_delta_x ) / 65536, + (double)( FT_intToFixed( outline->points[j].y ) + + old_point_delta_y ) / 65536, + (double)( FT_intToFixed( outline->points[j].x ) + + point_deltas_x[j] ) / 65536, + (double)( FT_intToFixed( outline->points[j].y ) + + point_deltas_y[j] ) / 65536 )); count++; } #endif @@ -4232,6 +4415,24 @@ FT_TRACE5(( "\n" )); + /* To avoid double adjustment of advance width or height, */ + /* do not move phantom points if there is HVAR or VVAR */ + /* support, respectively. */ + if ( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) + { + point_deltas_x[n_points - 4] = 0; + point_deltas_y[n_points - 4] = 0; + point_deltas_x[n_points - 3] = 0; + point_deltas_y[n_points - 3] = 0; + } + if ( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) + { + point_deltas_x[n_points - 2] = 0; + point_deltas_y[n_points - 2] = 0; + point_deltas_x[n_points - 1] = 0; + point_deltas_y[n_points - 1] = 0; + } + for ( i = 0; i < n_points; i++ ) { unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] ); @@ -4241,6 +4442,24 @@ outline->points[i].y += FT_fixedToInt( point_deltas_y[i] ); } + /* To avoid double adjustment of advance width or height, */ + /* adjust phantom points only if there is no HVAR or VVAR */ + /* support, respectively. */ + if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + { + loader->pp1 = outline->points[n_points - 4]; + loader->pp2 = outline->points[n_points - 3]; + loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x - + unrounded[n_points - 4].x ) / 64; + } + if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + { + loader->pp3 = outline->points[n_points - 2]; + loader->pp4 = outline->points[n_points - 1]; + loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].y - + unrounded[n_points - 2].y ) / 64; + } + Fail3: FT_FREE( point_deltas_x ); FT_FREE( point_deltas_y ); @@ -4274,22 +4493,25 @@ * the MM machinery in case it isn't loaded yet. */ FT_LOCAL_DEF( FT_Error ) - tt_get_var_blend( TT_Face face, + tt_get_var_blend( FT_Face face, /* TT_Face */ FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ) { - if ( face->blend ) + TT_Face ttface = (TT_Face)face; + + + if ( ttface->blend ) { if ( num_coords ) - *num_coords = face->blend->num_axis; + *num_coords = ttface->blend->num_axis; if ( coords ) - *coords = face->blend->coords; + *coords = ttface->blend->coords; if ( normalizedcoords ) - *normalizedcoords = face->blend->normalizedcoords; + *normalizedcoords = ttface->blend->normalizedcoords; if ( mm_var ) - *mm_var = face->blend->mmvar; + *mm_var = ttface->blend->mmvar; } else { @@ -4305,8 +4527,8 @@ } - static void - ft_var_done_item_variation_store( TT_Face face, + FT_LOCAL_DEF( void ) + tt_var_done_item_variation_store( FT_Face face, GX_ItemVarStore itemStore ) { FT_Memory memory = FT_FACE_MEMORY( face ); @@ -4334,6 +4556,18 @@ } + FT_LOCAL_DEF( void ) + tt_var_done_delta_set_index_map( FT_Face face, + GX_DeltaSetIdxMap deltaSetIdxMap ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( deltaSetIdxMap->innerIndex ); + FT_FREE( deltaSetIdxMap->outerIndex ); + } + + /************************************************************************** * * @Function: @@ -4343,10 +4577,11 @@ * Free the blend internal data structure. */ FT_LOCAL_DEF( void ) - tt_done_blend( TT_Face face ) + tt_done_blend( FT_Face face ) { + TT_Face ttface = (TT_Face)face; FT_Memory memory = FT_FACE_MEMORY( face ); - GX_Blend blend = face->blend; + GX_Blend blend = ttface->blend; if ( blend ) @@ -4362,36 +4597,47 @@ FT_FREE( blend->normalized_stylecoords ); FT_FREE( blend->mmvar ); - if ( blend->avar_segment ) + if ( blend->avar_table ) { - for ( i = 0; i < num_axes; i++ ) - FT_FREE( blend->avar_segment[i].correspondence ); - FT_FREE( blend->avar_segment ); + if ( blend->avar_table->avar_segment ) + { + for ( i = 0; i < num_axes; i++ ) + FT_FREE( blend->avar_table->avar_segment[i].correspondence ); + FT_FREE( blend->avar_table->avar_segment ); + } + + tt_var_done_item_variation_store( face, + &blend->avar_table->itemStore ); + + tt_var_done_delta_set_index_map( face, + &blend->avar_table->axisMap ); + + FT_FREE( blend->avar_table ); } if ( blend->hvar_table ) { - ft_var_done_item_variation_store( face, + tt_var_done_item_variation_store( face, &blend->hvar_table->itemStore ); - FT_FREE( blend->hvar_table->widthMap.innerIndex ); - FT_FREE( blend->hvar_table->widthMap.outerIndex ); + tt_var_done_delta_set_index_map( face, + &blend->hvar_table->widthMap ); FT_FREE( blend->hvar_table ); } if ( blend->vvar_table ) { - ft_var_done_item_variation_store( face, + tt_var_done_item_variation_store( face, &blend->vvar_table->itemStore ); - FT_FREE( blend->vvar_table->widthMap.innerIndex ); - FT_FREE( blend->vvar_table->widthMap.outerIndex ); + tt_var_done_delta_set_index_map( face, + &blend->vvar_table->widthMap ); FT_FREE( blend->vvar_table ); } if ( blend->mvar_table ) { - ft_var_done_item_variation_store( face, + tt_var_done_item_variation_store( face, &blend->mvar_table->itemStore ); FT_FREE( blend->mvar_table->values ); @@ -4407,7 +4653,7 @@ #else /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* ANSI C doesn't like empty source files */ - typedef int _tt_gxvar_dummy; + typedef int tt_gxvar_dummy_; #endif /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.h b/src/3rdparty/freetype/src/truetype/ttgxvar.h index 17915f00d3..e3da6d1705 100644 --- a/src/3rdparty/freetype/src/truetype/ttgxvar.h +++ b/src/3rdparty/freetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ * * TrueType GX Font Variation loader (specification) * - * Copyright (C) 2004-2022 by + * Copyright (C) 2004-2023 by * David Turner, Robert Wilhelm, Werner Lemberg and George Williams. * * This file is part of the FreeType project, and may only be used, @@ -20,6 +20,7 @@ #define TTGXVAR_H_ +#include <freetype/internal/ftmmtypes.h> #include "ttobjs.h" @@ -62,55 +63,21 @@ FT_BEGIN_HEADER } GX_AVarSegmentRec, *GX_AVarSegment; - typedef struct GX_ItemVarDataRec_ - { - FT_UInt itemCount; /* number of delta sets per item */ - FT_UInt regionIdxCount; /* number of region indices in this data */ - FT_UInt* regionIndices; /* array of `regionCount' indices; */ - /* these index `varRegionList' */ - FT_Short* deltaSet; /* array of `itemCount' deltas */ - /* use `innerIndex' for this array */ - - } GX_ItemVarDataRec, *GX_ItemVarData; - - - /* contribution of one axis to a region */ - typedef struct GX_AxisCoordsRec_ - { - FT_Fixed startCoord; - FT_Fixed peakCoord; /* zero means no effect (factor = 1) */ - FT_Fixed endCoord; - - } GX_AxisCoordsRec, *GX_AxisCoords; - - - typedef struct GX_VarRegionRec_ - { - GX_AxisCoords axisList; /* array of axisCount records */ - - } GX_VarRegionRec, *GX_VarRegion; - - - /* item variation store */ - typedef struct GX_ItemVarStoreRec_ - { - FT_UInt dataCount; - GX_ItemVarData varData; /* array of dataCount records; */ - /* use `outerIndex' for this array */ - FT_UShort axisCount; - FT_UInt regionCount; /* total number of regions defined */ - GX_VarRegion varRegionList; - - } GX_ItemVarStoreRec, *GX_ItemVarStore; - - - typedef struct GX_DeltaSetIdxMapRec_ + /************************************************************************** + * + * @Struct: + * GX_AVarTableRec + * + * @Description: + * Data from the `avar' table. + */ + typedef struct GX_AVarTableRec_ { - FT_ULong mapCount; - FT_UInt* outerIndex; /* indices to item var data */ - FT_UInt* innerIndex; /* indices to delta set */ + GX_AVarSegment avar_segment; /* avar_segment[num_axis] */ + GX_ItemVarStoreRec itemStore; /* Item Variation Store */ + GX_DeltaSetIdxMapRec axisMap; /* Axis Mapping */ - } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap; + } GX_AVarTableRec, *GX_AVarTable; /************************************************************************** @@ -245,7 +212,7 @@ FT_BEGIN_HEADER * A Boolean; if set, FreeType tried to load (and parse) the `avar' * table. * - * avar_segment :: + * avar_table :: * Data from the `avar' table. * * hvar_loaded :: @@ -310,7 +277,7 @@ FT_BEGIN_HEADER /* normalized_stylecoords[num_namedstyles][num_axis] */ FT_Bool avar_loaded; - GX_AVarSegment avar_segment; /* avar_segment[num_axis] */ + GX_AVarTable avar_table; FT_Bool hvar_loaded; FT_Bool hvar_checked; @@ -376,70 +343,103 @@ FT_BEGIN_HEADER #define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) #define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) #define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) +#define TTAG_ital FT_MAKE_TAG( 'i', 't', 'a', 'l' ) FT_LOCAL( FT_Error ) - TT_Set_MM_Blend( TT_Face face, + TT_Set_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Get_MM_Blend( TT_Face face, + TT_Get_MM_Blend( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Set_Var_Design( TT_Face face, + TT_Set_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Get_MM_Var( TT_Face face, + TT_Get_MM_Var( FT_Face face, FT_MM_Var* *master ); FT_LOCAL( FT_Error ) - TT_Get_Var_Design( TT_Face face, + TT_Get_Var_Design( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); FT_LOCAL( FT_Error ) - TT_Set_Named_Instance( TT_Face face, + TT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); FT_LOCAL( FT_Error ) + TT_Get_Default_Named_Instance( FT_Face face, + FT_UInt *instance_index ); + + FT_LOCAL( void ) + tt_construct_ps_name( FT_Face face ); + + FT_LOCAL( FT_Error ) tt_face_vary_cvt( TT_Face face, FT_Stream stream ); FT_LOCAL( FT_Error ) - TT_Vary_Apply_Glyph_Deltas( TT_Face face, - FT_UInt glyph_index, + TT_Vary_Apply_Glyph_Deltas( TT_Loader loader, FT_Outline* outline, - FT_Vector* unrounded, - FT_UInt n_points ); + FT_Vector* unrounded ); FT_LOCAL( FT_Error ) - tt_hadvance_adjust( TT_Face face, + tt_hadvance_adjust( FT_Face face, FT_UInt gindex, FT_Int *adelta ); FT_LOCAL( FT_Error ) - tt_vadvance_adjust( TT_Face face, + tt_vadvance_adjust( FT_Face face, FT_UInt gindex, FT_Int *adelta ); FT_LOCAL( void ) - tt_apply_mvar( TT_Face face ); + tt_apply_mvar( FT_Face face ); + + FT_LOCAL( FT_Error ) + tt_var_load_item_variation_store( FT_Face face, + FT_ULong offset, + GX_ItemVarStore itemStore ); + + FT_LOCAL( FT_Error ) + tt_var_load_delta_set_index_mapping( FT_Face face, + FT_ULong offset, + GX_DeltaSetIdxMap map, + GX_ItemVarStore itemStore, + FT_ULong table_len ); + + FT_LOCAL( FT_ItemVarDelta ) + tt_var_get_item_delta( FT_Face face, + GX_ItemVarStore itemStore, + FT_UInt outerIndex, + FT_UInt innerIndex ); + + FT_LOCAL( void ) + tt_var_done_item_variation_store( FT_Face face, + GX_ItemVarStore itemStore ); + + FT_LOCAL( void ) + tt_var_done_delta_set_index_map( FT_Face face, + GX_DeltaSetIdxMap deltaSetIdxMap ); + FT_LOCAL( FT_Error ) - tt_get_var_blend( TT_Face face, + tt_get_var_blend( FT_Face face, FT_UInt *num_coords, FT_Fixed* *coords, FT_Fixed* *normalizedcoords, FT_MM_Var* *mm_var ); FT_LOCAL( void ) - tt_done_blend( TT_Face face ); + tt_done_blend( FT_Face face ); #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.c b/src/3rdparty/freetype/src/truetype/ttinterp.c index e16565c3a5..79df4555d9 100644 --- a/src/3rdparty/freetype/src/truetype/ttinterp.c +++ b/src/3rdparty/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (body). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -29,7 +29,6 @@ #include "ttinterp.h" #include "tterrors.h" -#include "ttsubpix.h" #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif @@ -52,12 +51,6 @@ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_35 ) -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY -#define SUBPIXEL_HINTING_INFINALITY \ - ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ - TT_INTERPRETER_VERSION_38 ) -#endif - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #define SUBPIXEL_HINTING_MINIMAL \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ @@ -278,57 +271,6 @@ /************************************************************************** * * @Function: - * Update_Max - * - * @Description: - * Checks the size of a buffer and reallocates it if necessary. - * - * @Input: - * memory :: - * A handle to the parent memory object. - * - * multiplier :: - * The size in bytes of each element in the buffer. - * - * new_max :: - * The new capacity (size) of the buffer. - * - * @InOut: - * size :: - * The address of the buffer's current size expressed - * in elements. - * - * buff :: - * The address of the buffer base pointer. - * - * @Return: - * FreeType error code. 0 means success. - */ - FT_LOCAL_DEF( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_ULong multiplier, - void* _pbuff, - FT_ULong new_max ) - { - FT_Error error; - void** pbuff = (void**)_pbuff; - - - if ( *size < new_max ) - { - if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) - return error; - *size = new_max; - } - - return FT_Err_Ok; - } - - - /************************************************************************** - * - * @Function: * TT_Load_Context * * @Description: @@ -359,9 +301,9 @@ TT_Size size ) { FT_Int i; - FT_ULong tmp; TT_MaxProfile* maxp; FT_Error error; + FT_Memory memory = exec->memory; exec->face = face; @@ -406,25 +348,15 @@ /* XXX: We reserve a little more elements on the stack to deal safely */ /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = (FT_ULong)exec->stackSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_F26Dot6 ), - (void*)&exec->stack, - maxp->maxStackElements + 32 ); - exec->stackSize = (FT_Long)tmp; - if ( error ) + if ( FT_QRENEW_ARRAY( exec->stack, + exec->stackSize, + maxp->maxStackElements + 32 ) ) return error; + exec->stackSize = maxp->maxStackElements + 32; - tmp = (FT_ULong)exec->glyphSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void*)&exec->glyphIns, - maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UInt)tmp; - if ( error ) - return error; + /* free previous glyph code range */ + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; exec->pts.n_points = 0; exec->pts.n_contours = 0; @@ -1527,18 +1459,19 @@ static void Modify_CVT_Check( TT_ExecContext exc ) { - /* TT_RunIns sets origCvt and restores cvt to origCvt when done. */ if ( exc->iniRange == tt_coderange_glyph && - exc->cvt == exc->origCvt ) + exc->cvt != exc->glyfCvt ) { - exc->error = Update_Max( exc->memory, - &exc->glyfCvtSize, - sizeof ( FT_Long ), - (void*)&exc->glyfCvt, - exc->cvtSize ); - if ( exc->error ) + FT_Memory memory = exc->memory; + FT_Error error; + + + FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize ); + exc->error = error; + if ( error ) return; + exc->glyfCvtSize = exc->cvtSize; FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize ); exc->cvt = exc->glyfCvt; } @@ -1745,17 +1678,6 @@ if ( v != 0 ) { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - ( !exc->ignore_x_mode || - ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) - zone->cur[point].x = ADD_LONG( zone->cur[point].x, - FT_MulDiv( distance, - v, - exc->F_dot_P ) ); - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* Exception to the post-IUP curfew: Allow the x component of */ /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ @@ -1861,12 +1783,6 @@ FT_UShort point, FT_F26Dot6 distance ) { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) - zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); @@ -3070,28 +2986,7 @@ args[0] = 0; } else - { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* subpixel hinting - avoid Typeman Dstroke and */ - /* IStroke and Vacuform rounds */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - ( ( I == 24 && - ( exc->face->sph_found_func_flags & - ( SPH_FDEF_SPACING_1 | - SPH_FDEF_SPACING_2 ) ) ) || - ( I == 22 && - ( exc->sph_in_func_flags & - SPH_FDEF_TYPEMAN_STROKES ) ) || - ( I == 8 && - ( exc->face->sph_found_func_flags & - SPH_FDEF_VACUFORM_ROUND_1 ) && - exc->iup_called ) ) ) - args[0] = 0; - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - args[0] = exc->storage[I]; - } + args[0] = exc->storage[I]; } @@ -3115,23 +3010,21 @@ } else { - /* TT_RunIns sets origStorage and restores storage to origStorage */ - /* when done. */ if ( exc->iniRange == tt_coderange_glyph && - exc->storage == exc->origStorage ) + exc->storage != exc->glyfStorage ) { - FT_ULong tmp = (FT_ULong)exc->glyfStoreSize; + FT_Memory memory = exc->memory; + FT_Error error; - exc->error = Update_Max( exc->memory, - &tmp, - sizeof ( FT_Long ), - (void*)&exc->glyfStorage, - exc->storeSize ); - exc->glyfStoreSize = (FT_UShort)tmp; - if ( exc->error ) + FT_MEM_QRENEW_ARRAY( exc->glyfStorage, + exc->glyfStoreSize, + exc->storeSize ); + exc->error = error; + if ( error ) return; + exc->glyfStoreSize = exc->storeSize; FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize ); exc->storage = exc->glyfStorage; } @@ -3607,106 +3500,6 @@ TT_DefRecord* rec; TT_DefRecord* limit; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* arguments to opcodes are skipped by `SKIP_Code' */ - FT_Byte opcode_pattern[9][12] = { - /* #0 inline delta function 1 */ - { - 0x4B, /* PPEM */ - 0x53, /* GTEQ */ - 0x23, /* SWAP */ - 0x4B, /* PPEM */ - 0x51, /* LTEQ */ - 0x5A, /* AND */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #1 inline delta function 2 */ - { - 0x4B, /* PPEM */ - 0x54, /* EQ */ - 0x58, /* IF */ - 0x38, /* SHPIX */ - 0x1B, /* ELSE */ - 0x21, /* POP */ - 0x21, /* POP */ - 0x59 /* EIF */ - }, - /* #2 diagonal stroke function */ - { - 0x20, /* DUP */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 1 */ - 0x60, /* ADD */ - 0x46, /* GC_cur */ - 0xB0, /* PUSHB_1 */ - /* 64 */ - 0x23, /* SWAP */ - 0x42 /* WS */ - }, - /* #3 VacuFormRound function */ - { - 0x45, /* RCVT */ - 0x23, /* SWAP */ - 0x46, /* GC_cur */ - 0x60, /* ADD */ - 0x20, /* DUP */ - 0xB0 /* PUSHB_1 */ - /* 38 */ - }, - /* #4 TTFautohint bytecode (old) */ - { - 0x20, /* DUP */ - 0x64, /* ABS */ - 0xB0, /* PUSHB_1 */ - /* 32 */ - 0x60, /* ADD */ - 0x66, /* FLOOR */ - 0x23, /* SWAP */ - 0xB0 /* PUSHB_1 */ - }, - /* #5 spacing function 1 */ - { - 0x01, /* SVTCA_x */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #6 spacing function 2 */ - { - 0x01, /* SVTCA_x */ - 0x18, /* RTG */ - 0xB0, /* PUSHB_1 */ - /* 24 */ - 0x43, /* RS */ - 0x58 /* IF */ - }, - /* #7 TypeMan Talk DiagEndCtrl function */ - { - 0x01, /* SVTCA_x */ - 0x20, /* DUP */ - 0xB0, /* PUSHB_1 */ - /* 3 */ - 0x25, /* CINDEX */ - }, - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; - FT_UShort opcode_patterns = 9; - FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; - FT_UShort i; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /* FDEF is only allowed in `prep' or `fpgm' */ if ( exc->iniRange == tt_coderange_glyph ) @@ -3751,136 +3544,15 @@ rec->opc = (FT_UInt16)n; rec->start = exc->IP + 1; rec->active = TRUE; - rec->inline_delta = FALSE; - rec->sph_fdef_flags = 0x0000; if ( n > exc->maxFunc ) exc->maxFunc = (FT_UInt16)n; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* We don't know for sure these are typeman functions, */ - /* however they are only active when RS 22 is called */ - if ( n >= 64 && n <= 66 ) - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; -#endif - /* Now skip the whole function definition. */ /* We don't allow nested IDEFS & FDEFs. */ while ( SkipCode( exc ) == SUCCESS ) { - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( SUBPIXEL_HINTING_INFINALITY ) - { - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( opcode_pointer[i] < opcode_size[i] && - exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) - { - opcode_pointer[i] += 1; - - if ( opcode_pointer[i] == opcode_size[i] ) - { - FT_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n", - i, n, - exc->face->root.family_name, - exc->face->root.style_name )); - - switch ( i ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; - exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; - break; - - case 1: - rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; - exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; - break; - - case 2: - switch ( n ) - { - /* needs to be implemented still */ - case 58: - rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; - exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; - } - break; - - case 3: - switch ( n ) - { - case 0: - rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; - exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; - } - break; - - case 4: - /* probably not necessary to detect anymore */ - rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; - exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; - break; - - case 5: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; - exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1; - } - break; - - case 6: - switch ( n ) - { - case 0: - case 1: - case 2: - case 4: - case 7: - case 8: - rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; - exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2; - } - break; - - case 7: - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - break; - - case 8: -#if 0 - rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; - exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; -#endif - break; - } - opcode_pointer[i] = 0; - } - } - - else - opcode_pointer[i] = 0; - } - - /* Set sph_compatibility_mode only when deltas are detected */ - exc->face->sph_compatibility_mode = - ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | - ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); - } - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - switch ( exc->opcode ) { case 0x89: /* IDEF */ @@ -3908,10 +3580,6 @@ TT_CallRec* pRec; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - exc->sph_in_func_flags = 0x0000; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */ { exc->error = FT_THROW( ENDF_In_Exec_Stream ); @@ -3999,17 +3667,6 @@ if ( !def->active ) goto Fail; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - ( ( exc->iup_called && - ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) - goto Fail; - else - exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /* check the call stack */ if ( exc->callTop >= exc->callSize ) { @@ -4087,15 +3744,6 @@ if ( !def->active ) goto Fail; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) - goto Fail; - else - exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /* check stack */ if ( exc->callTop >= exc->callSize ) { @@ -5001,14 +4649,6 @@ } } -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - ( D < 0 ? NEG_LONG( D ) : D ) == 64 ) - D += 1; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - args[0] = D; } @@ -5270,13 +4910,6 @@ /* except to change the subpixel flags temporarily */ else if ( exc->iniRange == tt_coderange_glyph && K == 3 ) { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* INSTCTRL modifying flag 3 also has an effect */ - /* outside of the CVT program */ - if ( SUBPIXEL_HINTING_INFINALITY ) - exc->ignore_x_mode = !FT_BOOL( L == 4 ); -#endif - #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL /* Native ClearType fonts sign a waiver that turns off all backward */ /* compatibility hacks and lets them program points to the grid like */ @@ -5608,12 +5241,6 @@ } } else -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode ) - Move_Zp2_Point( exc, point, 0, dy, TRUE ); - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Move_Zp2_Point( exc, point, dx, dy, TRUE ); exc->GS.loop--; @@ -5774,76 +5401,6 @@ } } else -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode ) - { - FT_Int B1, B2; - - - /* If not using ignore_x_mode rendering, allow ZP2 move. */ - /* If inline deltas aren't allowed, skip ZP2 move. */ - /* If using ignore_x_mode rendering, allow ZP2 point move if: */ - /* - freedom vector is y and sph_compatibility_mode is off */ - /* - the glyph is composite and the move is in the Y direction */ - /* - the glyph is specifically set to allow SHPIX moves */ - /* - the move is on a previously Y-touched point */ - - /* save point for later comparison */ - B1 = exc->zp2.cur[point].y; - - if ( exc->face->sph_compatibility_mode ) - { - if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) - dy = FT_PIX_ROUND( B1 + dy ) - B1; - - /* skip post-iup deltas */ - if ( exc->iup_called && - ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || - ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) - goto Skip; - - if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && - ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || - ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || - ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) - Move_Zp2_Point( exc, point, 0, dy, TRUE ); - - /* save new point */ - if ( exc->GS.freeVector.y != 0 ) - { - B2 = exc->zp2.cur[point].y; - - /* reverse any disallowed moves */ - if ( ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - Move_Zp2_Point( exc, point, 0, NEG_LONG( dy ), TRUE ); - } - } - else if ( exc->GS.freeVector.y != 0 ) - { - Move_Zp2_Point( exc, point, dx, dy, TRUE ); - - /* save new point */ - B2 = exc->zp2.cur[point].y; - - /* reverse any disallowed moves */ - if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 && - B1 != B2 ) - Move_Zp2_Point( exc, - point, - NEG_LONG( dx ), - NEG_LONG( dy ), - TRUE ); - } - else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) - Move_Zp2_Point( exc, point, dx, dy, TRUE ); - } - else -#endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL if ( SUBPIXEL_HINTING_MINIMAL && exc->backward_compatibility ) @@ -5863,9 +5420,6 @@ #endif Move_Zp2_Point( exc, point, dx, dy, TRUE ); -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - Skip: -#endif exc->GS.loop--; } @@ -5910,28 +5464,6 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) - { - FT_F26Dot6 control_value_cutin = exc->GS.control_value_cutin; - FT_F26Dot6 delta; - - - if ( !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = 0; - - delta = SUB_LONG( distance, args[1] ); - if ( delta < 0 ) - delta = NEG_LONG( delta ); - - if ( delta >= control_value_cutin ) - distance = args[1]; - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp1, point, @@ -5972,14 +5504,7 @@ if ( ( exc->opcode & 1 ) != 0 ) { cur_dist = FAST_PROJECT( &exc->zp0.cur[point] ); -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) - distance = SUB_LONG( Round_None( exc, cur_dist, 3 ), cur_dist ); - else -#endif - distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist ); + distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist ); } else distance = 0; @@ -6042,27 +5567,12 @@ if ( exc->GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ - /* Determined via experimentation and may be incorrect... */ - if ( !( SUBPIXEL_HINTING_INFINALITY && - ( exc->ignore_x_mode && - exc->face->sph_compatibility_mode ) ) ) -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->zp0.org[point].x = TT_MulFix14( distance, + exc->zp0.org[point].x = TT_MulFix14( distance, exc->GS.freeVector.x ); exc->zp0.org[point].y = TT_MulFix14( distance, exc->GS.freeVector.y ); exc->zp0.cur[point] = exc->zp0.org[point]; } -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && - distance > 0 && - exc->GS.freeVector.y != 0 ) - distance = 0; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ org_dist = FAST_PROJECT( &exc->zp0.cur[point] ); @@ -6072,15 +5582,6 @@ FT_F26Dot6 delta; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - exc->GS.freeVector.y == 0 && - !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = 0; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - delta = SUB_LONG( distance, org_dist ); if ( delta < 0 ) delta = NEG_LONG( delta ); @@ -6088,14 +5589,7 @@ if ( delta > control_value_cutin ) distance = org_dist; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) - distance = Round_None( exc, distance, 3 ); - else -#endif - distance = exc->func_round( exc, distance, 3 ); + distance = exc->func_round( exc, distance, 3 ); } exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) ); @@ -6188,14 +5682,7 @@ if ( ( exc->opcode & 4 ) != 0 ) { -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) - distance = Round_None( exc, org_dist, exc->opcode & 3 ); - else -#endif - distance = exc->func_round( exc, org_dist, exc->opcode & 3 ); + distance = exc->func_round( exc, org_dist, exc->opcode & 3 ); } else distance = Round_None( exc, org_dist, exc->opcode & 3 ); @@ -6207,14 +5694,6 @@ FT_F26Dot6 minimum_distance = exc->GS.minimum_distance; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - minimum_distance = 0; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( org_dist >= 0 ) { if ( distance < minimum_distance ) @@ -6357,41 +5836,7 @@ distance = exc->func_round( exc, cvt_dist, exc->opcode & 3 ); } else - { - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.gep0 == exc->GS.gep1 ) - { - FT_F26Dot6 control_value_cutin = exc->GS.control_value_cutin; - - - if ( exc->GS.freeVector.x != 0 && - !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - control_value_cutin = 0; - - if ( exc->GS.freeVector.y != 0 && - ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) - { - if ( cur_dist < -64 ) - cvt_dist -= 16; - else if ( cur_dist > 64 && cur_dist < 84 ) - cvt_dist += 32; - } - - delta = SUB_LONG( cvt_dist, org_dist ); - if ( delta < 0 ) - delta = NEG_LONG( delta ); - - if ( delta > control_value_cutin ) - cvt_dist = org_dist; - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - distance = Round_None( exc, cvt_dist, exc->opcode & 3 ); - } /* minimum distance test */ @@ -6400,14 +5845,6 @@ FT_F26Dot6 minimum_distance = exc->GS.minimum_distance; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) - minimum_distance = 0; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( org_dist >= 0 ) { if ( distance < minimum_distance ) @@ -6420,51 +5857,10 @@ } } -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->GS.freeVector.y != 0 ) - { - FT_Int B1, B2; - - - B1 = exc->zp1.cur[point].y; - - /* Round moves if necessary */ - if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) - distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; - - if ( ( exc->opcode & 16 ) == 0 && - ( exc->opcode & 8 ) == 0 && - ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) - distance += 64; - - exc->func_move( exc, - &exc->zp1, - point, - SUB_LONG( distance, cur_dist ) ); - - B2 = exc->zp1.cur[point].y; - - /* Reverse move if necessary */ - if ( ( exc->face->sph_compatibility_mode && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) || - ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 ) ) - exc->func_move( exc, - &exc->zp1, - point, - SUB_LONG( cur_dist, distance ) ); - } - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - - exc->func_move( exc, - &exc->zp1, - point, - SUB_LONG( distance, cur_dist ) ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( distance, cur_dist ) ); Fail: exc->GS.rp1 = exc->GS.rp0; @@ -6489,17 +5885,6 @@ FT_F26Dot6 distance; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->iup_called && - ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) - { - exc->error = FT_THROW( Invalid_Reference ); - goto Fail; - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( exc->top < exc->GS.loop || BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) { @@ -6874,7 +6259,7 @@ static void - _iup_worker_shift( IUP_Worker worker, + iup_worker_shift_( IUP_Worker worker, FT_UInt p1, FT_UInt p2, FT_UInt p ) @@ -6896,7 +6281,7 @@ static void - _iup_worker_interpolate( IUP_Worker worker, + iup_worker_interpolate_( IUP_Worker worker, FT_UInt p1, FT_UInt p2, FT_UInt ref1, @@ -7058,16 +6443,6 @@ contour = 0; point = 0; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode ) - { - exc->iup_called = TRUE; - if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) - return; - } -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - do { end_point = exc->pts.contours[contour] - exc->pts.first_point; @@ -7090,7 +6465,7 @@ { if ( ( exc->pts.tags[point] & mask ) != 0 ) { - _iup_worker_interpolate( &V, + iup_worker_interpolate_( &V, cur_touched + 1, point - 1, cur_touched, @@ -7102,17 +6477,17 @@ } if ( cur_touched == first_touched ) - _iup_worker_shift( &V, first_point, end_point, cur_touched ); + iup_worker_shift_( &V, first_point, end_point, cur_touched ); else { - _iup_worker_interpolate( &V, + iup_worker_interpolate_( &V, (FT_UShort)( cur_touched + 1 ), end_point, cur_touched, first_touched ); if ( first_touched > 0 ) - _iup_worker_interpolate( &V, + iup_worker_interpolate_( &V, first_point, first_touched - 1, cur_touched, @@ -7140,14 +6515,6 @@ FT_Long B; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - exc->iup_called && - ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) - goto Fail; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; /* some points theoretically may occur more than once, thus UShort isn't enough */ @@ -7200,87 +6567,21 @@ B++; B *= 1L << ( 6 - exc->GS.delta_shift ); -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING_INFINALITY ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility */ + /* mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility ) { - /* - * Allow delta move if - * - * - not using ignore_x_mode rendering, - * - glyph is specifically set to allow it, or - * - glyph is composite and freedom vector is not in subpixel - * direction. - */ - if ( !exc->ignore_x_mode || - ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || - ( exc->is_composite && exc->GS.freeVector.y != 0 ) ) + if ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) exc->func_move( exc, &exc->zp0, A, B ); - - /* Otherwise, apply subpixel hinting and compatibility mode */ - /* rules, always skipping deltas in subpixel direction. */ - else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 ) - { - FT_UShort B1, B2; - - - /* save the y value of the point now; compare after move */ - B1 = (FT_UShort)exc->zp0.cur[A].y; - - /* Standard subpixel hinting: Allow y move for y-touched */ - /* points. This messes up DejaVu ... */ - if ( !exc->face->sph_compatibility_mode && - ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - exc->func_move( exc, &exc->zp0, A, B ); - - /* compatibility mode */ - else if ( exc->face->sph_compatibility_mode && - !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) - { - if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) - B = FT_PIX_ROUND( B1 + B ) - B1; - - /* Allow delta move if using sph_compatibility_mode, */ - /* IUP has not been called, and point is touched on Y. */ - if ( !exc->iup_called && - ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) - exc->func_move( exc, &exc->zp0, A, B ); - } - - B2 = (FT_UShort)exc->zp0.cur[A].y; - - /* Reverse this move if it results in a disallowed move */ - if ( exc->GS.freeVector.y != 0 && - ( ( exc->face->sph_compatibility_mode && - ( B1 & 63 ) == 0 && - ( B2 & 63 ) != 0 ) || - ( ( exc->sph_tweak_flags & - SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && - ( B1 & 63 ) != 0 && - ( B2 & 63 ) != 0 ) ) ) - exc->func_move( exc, &exc->zp0, A, NEG_LONG( B ) ); - } } else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - - { - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - /* See `ttinterp.h' for details on backward compatibility */ - /* mode. */ - if ( SUBPIXEL_HINTING_MINIMAL && - exc->backward_compatibility ) - { - if ( !( exc->iupx_called && exc->iupy_called ) && - ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || - ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) - exc->func_move( exc, &exc->zp0, A, B ); - } - else #endif - exc->func_move( exc, &exc->zp0, A, B ); - } + exc->func_move( exc, &exc->zp0, A, B ); } } else @@ -7383,14 +6684,6 @@ * GETINFO[]: GET INFOrmation * Opcode range: 0x88 * Stack: uint32 --> uint32 - * - * XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May - * 2015) not documented in the OpenType specification. - * - * Selector bit 11 is incorrectly described as bit 8, while the - * real meaning of bit 8 (vertical LCD subpixels) stays - * undocumented. The same mistake can be found in Greg Hitchcock's - * whitepaper. */ static void Ins_GETINFO( TT_ExecContext exc, @@ -7402,31 +6695,8 @@ K = 0; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - /********************************* - * RASTERIZER VERSION - * Selector Bit: 0 - * Return Bit(s): 0-7 - */ - if ( SUBPIXEL_HINTING_INFINALITY && - ( args[0] & 1 ) != 0 && - exc->subpixel_hinting ) - { - if ( exc->ignore_x_mode ) - { - /* if in ClearType backward compatibility mode, */ - /* we sometimes change the TrueType version dynamically */ - K = exc->rasterizer_version; - FT_TRACE6(( "Setting rasterizer version %d\n", - exc->rasterizer_version )); - } - else - K = TT_INTERPRETER_VERSION_38; - } - else -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - if ( ( args[0] & 1 ) != 0 ) - K = driver->interpreter_version; + if ( ( args[0] & 1 ) != 0 ) + K = driver->interpreter_version; /********************************* * GLYPH ROTATED @@ -7449,8 +6719,6 @@ * VARIATION GLYPH * Selector Bit: 3 * Return Bit(s): 10 - * - * XXX: UNDOCUMENTED! */ if ( (args[0] & 8 ) != 0 && exc->face->blend ) K |= 1 << 10; @@ -7525,89 +6793,6 @@ } #endif -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( SUBPIXEL_HINTING_INFINALITY && - exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) - { - - if ( exc->rasterizer_version >= 37 ) - { - /********************************* - * HINTING FOR SUBPIXEL - * Selector Bit: 6 - * Return Bit(s): 13 - */ - if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting ) - K |= 1 << 13; - - /********************************* - * COMPATIBLE WIDTHS ENABLED - * Selector Bit: 7 - * Return Bit(s): 14 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 128 ) != 0 && exc->compatible_widths ) - K |= 1 << 14; - - /********************************* - * VERTICAL LCD SUBPIXELS? - * Selector Bit: 8 - * Return Bit(s): 15 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd ) - K |= 1 << 15; - - /********************************* - * HINTING FOR BGR? - * Selector Bit: 9 - * Return Bit(s): 16 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 512 ) != 0 && exc->bgr ) - K |= 1 << 16; - - if ( exc->rasterizer_version >= 38 ) - { - /********************************* - * SUBPIXEL POSITIONED? - * Selector Bit: 10 - * Return Bit(s): 17 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned ) - K |= 1 << 17; - - /********************************* - * SYMMETRICAL SMOOTHING - * Selector Bit: 11 - * Return Bit(s): 18 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing ) - K |= 1 << 18; - - /********************************* - * GRAY CLEARTYPE - * Selector Bit: 12 - * Return Bit(s): 19 - * - * Functionality still needs to be added - */ - if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype ) - K |= 1 << 19; - } - } - } - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - args[0] = K; } @@ -7742,25 +6927,14 @@ /* documentation is in ttinterp.h */ FT_EXPORT_DEF( FT_Error ) - TT_RunIns( TT_ExecContext exc ) + TT_RunIns( void* exec ) { + TT_ExecContext exc = (TT_ExecContext)exec; + FT_ULong ins_counter = 0; /* executed instructions counter */ FT_ULong num_twilight_points; FT_UShort i; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - FT_Byte opcode_pattern[1][2] = { - /* #8 TypeMan Talk Align */ - { - 0x06, /* SPVTL */ - 0x7D, /* RDTG */ - }, - }; - FT_UShort opcode_patterns = 1; - FT_UShort opcode_pointer[1] = { 0 }; - FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /* We restrict the number of twilight points to a reasonable, */ /* heuristic value to avoid slow execution of malformed bytecode. */ @@ -7832,17 +7006,12 @@ exc->func_move_cvt = Move_CVT; } - exc->origCvt = exc->cvt; - exc->origStorage = exc->storage; exc->iniRange = exc->curRange; Compute_Funcs( exc ); Compute_Round( exc, (FT_Byte)exc->GS.round_state ); /* These flags cancel execution of some opcodes after IUP is called */ -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - exc->iup_called = FALSE; -#endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL exc->iupx_called = FALSE; exc->iupy_called = FALSE; @@ -7911,7 +7080,7 @@ /* a variable number of arguments */ /* it is the job of the application to `activate' GX handling, */ - /* this is, calling any of the GX API functions on the current */ + /* that is, calling any of the GX API functions on the current */ /* font to select a variation instance */ if ( exc->face->blend ) exc->new_top = exc->args + exc->face->blend->num_axis; @@ -7932,39 +7101,6 @@ exc->step_ins = TRUE; exc->error = FT_Err_Ok; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - if ( SUBPIXEL_HINTING_INFINALITY ) - { - for ( i = 0; i < opcode_patterns; i++ ) - { - if ( opcode_pointer[i] < opcode_size[i] && - exc->opcode == opcode_pattern[i][opcode_pointer[i]] ) - { - opcode_pointer[i] += 1; - - if ( opcode_pointer[i] == opcode_size[i] ) - { - FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n", - i, - exc->face->root.family_name, - exc->face->root.style_name )); - - switch ( i ) - { - case 0: - break; - } - opcode_pointer[i] = 0; - } - } - else - opcode_pointer[i] = 0; - } - } - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { FT_Long* args = exc->stack + exc->args; FT_Byte opcode = exc->opcode; @@ -8471,7 +7607,7 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT case 0x91: /* it is the job of the application to `activate' GX handling, */ - /* this is, calling any of the GX API functions on the current */ + /* that is, calling any of the GX API functions on the current */ /* font to select a variation instance */ if ( exc->face->blend ) Ins_GETVARIATION( exc, args ); @@ -8570,7 +7706,8 @@ /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) { + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) + { exc->error = FT_THROW( Execution_Too_Long ); goto LErrorLabel_; } @@ -8593,9 +7730,6 @@ ins_counter, ins_counter == 1 ? "" : "s" )); - exc->cvt = exc->origCvt; - exc->storage = exc->origStorage; - return FT_Err_Ok; LErrorCodeOverflow_: @@ -8605,16 +7739,13 @@ if ( exc->error && !exc->instruction_trap ) FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); - exc->cvt = exc->origCvt; - exc->storage = exc->origStorage; - return exc->error; } #else /* !TT_USE_BYTECODE_INTERPRETER */ /* ANSI C doesn't like empty source files */ - typedef int _tt_interp_dummy; + typedef int tt_interp_dummy_; #endif /* !TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.h b/src/3rdparty/freetype/src/truetype/ttinterp.h index 48f618dc9d..e98e258fe7 100644 --- a/src/3rdparty/freetype/src/truetype/ttinterp.h +++ b/src/3rdparty/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ * * TrueType bytecode interpreter (specification). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -98,48 +98,6 @@ FT_BEGIN_HEADER } TT_CallRec, *TT_CallStack; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - /************************************************************************** - * - * These structures define rules used to tweak subpixel hinting for - * various fonts. "", 0, "", NULL value indicates to match any value. - */ - -#define SPH_MAX_NAME_SIZE 32 -#define SPH_MAX_CLASS_MEMBERS 100 - - typedef struct SPH_TweakRule_ - { - const char family[SPH_MAX_NAME_SIZE]; - const FT_UInt ppem; - const char style[SPH_MAX_NAME_SIZE]; - const FT_ULong glyph; - - } SPH_TweakRule; - - - typedef struct SPH_ScaleRule_ - { - const char family[SPH_MAX_NAME_SIZE]; - const FT_UInt ppem; - const char style[SPH_MAX_NAME_SIZE]; - const FT_ULong glyph; - const FT_ULong scale; - - } SPH_ScaleRule; - - - typedef struct SPH_Font_Class_ - { - const char name[SPH_MAX_NAME_SIZE]; - const char member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE]; - - } SPH_Font_Class; - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - - /************************************************************************** * * The main structure for the interpreter which collects all necessary @@ -193,7 +151,6 @@ FT_BEGIN_HEADER FT_Long* cvt; /* ! */ FT_ULong glyfCvtSize; FT_Long* glyfCvt; /* cvt working copy for glyph */ - FT_Long* origCvt; FT_UInt glyphSize; /* ! glyph instructions buffer size */ FT_Byte* glyphIns; /* ! glyph instructions buffer */ @@ -224,7 +181,6 @@ FT_BEGIN_HEADER FT_Long* storage; /* ! storage area */ FT_UShort glyfStoreSize; FT_Long* glyfStorage; /* storage working copy for glyph */ - FT_Long* origStorage; FT_F26Dot6 period; /* values used for the */ FT_F26Dot6 phase; /* `SuperRounding' */ @@ -401,38 +357,6 @@ FT_BEGIN_HEADER FT_Bool grayscale_cleartype; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - TT_Round_Func func_round_sphn; /* subpixel rounding function */ - - FT_Bool subpixel_hinting; /* Using subpixel hinting? */ - FT_Bool ignore_x_mode; /* Standard rendering mode for */ - /* subpixel hinting. On if gray */ - /* or subpixel hinting is on. */ - - /* The following 6 aren't fully implemented but here for MS rasterizer */ - /* compatibility. */ - FT_Bool compatible_widths; /* compatible widths? */ - FT_Bool symmetrical_smoothing; /* symmetrical_smoothing? */ - FT_Bool bgr; /* bgr instead of rgb? */ - FT_Bool vertical_lcd; /* long side of LCD subpixel */ - /* rectangles is horizontal */ - FT_Bool subpixel_positioned; /* subpixel positioned */ - /* (DirectWrite ClearType)? */ - FT_Bool gray_cleartype; /* ClearType hinting but */ - /* grayscale rendering */ - - FT_Int rasterizer_version; /* MS rasterizer version */ - - FT_Bool iup_called; /* IUP called for glyph? */ - - FT_ULong sph_tweak_flags; /* flags to control */ - /* hint tweaks */ - - FT_ULong sph_in_func_flags; /* flags to indicate if in */ - /* special functions */ - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - /* We maintain two counters (in addition to the instruction counter) */ /* that act as loop detectors for LOOPCALL and jump opcodes with */ /* negative arguments. */ @@ -462,14 +386,6 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Clear_CodeRange( TT_ExecContext exec, FT_Int range ); - - - FT_LOCAL( FT_Error ) - Update_Max( FT_Memory memory, - FT_ULong* size, - FT_ULong multiplier, - void* _pbuff, - FT_ULong new_max ); #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -538,7 +454,7 @@ FT_BEGIN_HEADER * invoked by the TrueType debugger. */ FT_EXPORT( FT_Error ) - TT_RunIns( TT_ExecContext exec ); + TT_RunIns( void* exec ); FT_END_HEADER diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.c b/src/3rdparty/freetype/src/truetype/ttobjs.c index f4f3c69336..5b56af711d 100644 --- a/src/3rdparty/freetype/src/truetype/ttobjs.c +++ b/src/3rdparty/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ * * Objects manager (body). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -312,7 +312,8 @@ #define TRICK_SFNT_IDS_NUM_FACES 31 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] - [TRICK_SFNT_IDS_PER_FACE] = { + [TRICK_SFNT_IDS_PER_FACE] = + { #define TRICK_SFNT_ID_cvt 0 #define TRICK_SFNT_ID_fpgm 1 @@ -581,7 +582,7 @@ FT_Bool result = FALSE; TT_Face face = (TT_Face)ttface; - FT_UInt asize; + FT_ULong asize; FT_ULong i; FT_ULong glyph_index = 0; FT_UInt count = 0; @@ -589,7 +590,7 @@ for( i = 0; i < face->num_locations; i++ ) { - tt_face_get_location( face, i, &asize ); + tt_face_get_location( ttface, i, &asize ); if ( asize > 0 ) { count += 1; @@ -777,7 +778,6 @@ } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - { FT_UInt instance_index = (FT_UInt)face_index >> 16; @@ -785,14 +785,11 @@ if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && instance_index > 0 ) { - error = TT_Set_Named_Instance( face, instance_index ); + error = FT_Set_Named_Instance( ttface, instance_index ); if ( error ) goto Exit; - - tt_apply_mvar( face ); } } - #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* initialize standard glyph loading routines */ @@ -858,7 +855,7 @@ face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( face ); + tt_done_blend( ttface ); face->blend = NULL; #endif } @@ -1004,7 +1001,7 @@ { size->cvt[i] = FT_MulFix( face->cvt[i], scale ); FT_TRACE6(( " %3d: %f (%f)\n", - i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 )); + i, (double)face->cvt[i] / 64, (double)size->cvt[i] / 64 )); } FT_TRACE6(( "\n" )); @@ -1338,39 +1335,29 @@ /************************************************************************** * * @Function: - * tt_size_reset + * tt_size_reset_height * * @Description: - * Reset a TrueType size when resolutions and character dimensions - * have been changed. + * Recompute a TrueType size's ascender, descender, and height + * when resolutions and character dimensions have been changed. + * Used for variation fonts as an iterator function. * * @Input: - * size :: - * A handle to the target size object. - * - * only_height :: - * Only recompute ascender, descender, and height; - * this flag is used for variation fonts where - * `tt_size_reset' is used as an iterator function. + * ft_size :: + * A handle to the target TT_Size object. This function will be called + * through a `FT_Size_Reset_Func` pointer which takes `FT_Size`. This + * function must take `FT_Size` as a result. The passed `FT_Size` is + * expected to point to a `TT_Size`. */ FT_LOCAL_DEF( FT_Error ) - tt_size_reset( TT_Size size, - FT_Bool only_height ) + tt_size_reset_height( FT_Size ft_size ) { - TT_Face face; - FT_Size_Metrics* size_metrics; - - - face = (TT_Face)size->root.face; - - /* nothing to do for CFF2 */ - if ( face->is_cff2 ) - return FT_Err_Ok; + TT_Size size = (TT_Size)ft_size; + TT_Face face = (TT_Face)size->root.face; + FT_Size_Metrics* size_metrics = &size->hinted_metrics; size->ttmetrics.valid = FALSE; - size_metrics = &size->hinted_metrics; - /* copy the result from base layer */ *size_metrics = size->root.metrics; @@ -1397,12 +1384,34 @@ size->ttmetrics.valid = TRUE; - if ( only_height ) - { - /* we must not recompute the scaling values here since */ - /* `tt_size_reset' was already called (with only_height = 0) */ - return FT_Err_Ok; - } + return FT_Err_Ok; + } + + + /************************************************************************** + * + * @Function: + * tt_size_reset + * + * @Description: + * Reset a TrueType size when resolutions and character dimensions + * have been changed. + * + * @Input: + * size :: + * A handle to the target size object. + */ + FT_LOCAL_DEF( FT_Error ) + tt_size_reset( TT_Size size ) + { + FT_Error error; + TT_Face face = (TT_Face)size->root.face; + FT_Size_Metrics* size_metrics = &size->hinted_metrics; + + + error = tt_size_reset_height( (FT_Size)size ); + if ( error ) + return error; if ( face->header.Flags & 8 ) { @@ -1472,9 +1481,6 @@ TT_Driver driver = (TT_Driver)ttdriver; driver->interpreter_version = TT_INTERPRETER_VERSION_35; -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL driver->interpreter_version = TT_INTERPRETER_VERSION_40; #endif diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.h b/src/3rdparty/freetype/src/truetype/ttobjs.h index 5fa239d43a..40eb37b4c4 100644 --- a/src/3rdparty/freetype/src/truetype/ttobjs.h +++ b/src/3rdparty/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ * * Objects manager (specification). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -162,8 +162,6 @@ FT_BEGIN_HEADER FT_Long end; /* where does it end? */ FT_UInt opc; /* function #, or instruction code */ FT_Bool active; /* is it active? */ - FT_Bool inline_delta; /* is function that defines inline delta? */ - FT_ULong sph_fdef_flags; /* flags to identify special functions */ } TT_DefRecord, *TT_DefArray; @@ -391,8 +389,10 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size, - FT_Bool only_height ); + tt_size_reset_height( FT_Size size ); + + FT_LOCAL( FT_Error ) + tt_size_reset( TT_Size size ); /************************************************************************** diff --git a/src/3rdparty/freetype/src/truetype/ttpload.c b/src/3rdparty/freetype/src/truetype/ttpload.c index 6982c717ab..54a64c7b46 100644 --- a/src/3rdparty/freetype/src/truetype/ttpload.c +++ b/src/3rdparty/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (body). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -180,10 +180,11 @@ FT_LOCAL_DEF( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ) + tt_face_get_location( FT_Face face, /* TT_Face */ + FT_UInt gindex, + FT_ULong *asize ) { + TT_Face ttface = (TT_Face)face; FT_ULong pos1, pos2; FT_Byte* p; FT_Byte* p_limit; @@ -191,12 +192,12 @@ pos1 = pos2 = 0; - if ( gindex < face->num_locations ) + if ( gindex < ttface->num_locations ) { - if ( face->header.Index_To_Loc_Format != 0 ) + if ( ttface->header.Index_To_Loc_Format != 0 ) { - p = face->glyph_locations + gindex * 4; - p_limit = face->glyph_locations + face->num_locations * 4; + p = ttface->glyph_locations + gindex * 4; + p_limit = ttface->glyph_locations + ttface->num_locations * 4; pos1 = FT_NEXT_ULONG( p ); pos2 = pos1; @@ -206,8 +207,8 @@ } else { - p = face->glyph_locations + gindex * 2; - p_limit = face->glyph_locations + face->num_locations * 2; + p = ttface->glyph_locations + gindex * 2; + p_limit = ttface->glyph_locations + ttface->num_locations * 2; pos1 = FT_NEXT_USHORT( p ); pos2 = pos1; @@ -221,30 +222,30 @@ } /* Check broken location data. */ - if ( pos1 > face->glyf_len ) + if ( pos1 > ttface->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" " too large offset (0x%08lx) found for glyph index %d,\n", pos1, gindex )); FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - face->glyf_len )); + ttface->glyf_len )); *asize = 0; return 0; } - if ( pos2 > face->glyf_len ) + if ( pos2 > ttface->glyf_len ) { /* We try to sanitize the last `loca' entry. */ - if ( gindex == face->num_locations - 2 ) + if ( gindex == ttface->num_locations - 2 ) { FT_TRACE1(( "tt_face_get_location:" " too large size (%ld bytes) found for glyph index %d,\n", pos2 - pos1, gindex )); FT_TRACE1(( " " " truncating at the end of `glyf' table to %ld bytes\n", - face->glyf_len - pos1 )); - pos2 = face->glyf_len; + ttface->glyf_len - pos1 )); + pos2 = ttface->glyf_len; } else { @@ -253,7 +254,7 @@ pos2, gindex + 1 )); FT_TRACE1(( " " " exceeding the end of `glyf' table (0x%08lx)\n", - face->glyf_len )); + ttface->glyf_len )); *asize = 0; return 0; } @@ -268,9 +269,9 @@ /* We get (intentionally) a wrong, non-zero result in case the */ /* `glyf' table is missing. */ if ( pos2 >= pos1 ) - *asize = (FT_UInt)( pos2 - pos1 ); + *asize = (FT_ULong)( pos2 - pos1 ); else - *asize = (FT_UInt)( face->glyf_len - pos1 ); + *asize = (FT_ULong)( ttface->glyf_len - pos1 ); return pos1; } diff --git a/src/3rdparty/freetype/src/truetype/ttpload.h b/src/3rdparty/freetype/src/truetype/ttpload.h index fa5d96ed35..ed229fa461 100644 --- a/src/3rdparty/freetype/src/truetype/ttpload.h +++ b/src/3rdparty/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ * * TrueType-specific tables loader (specification). * - * Copyright (C) 1996-2022 by + * Copyright (C) 1996-2023 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -31,9 +31,9 @@ FT_BEGIN_HEADER FT_Stream stream ); FT_LOCAL( FT_ULong ) - tt_face_get_location( TT_Face face, - FT_UInt gindex, - FT_UInt *asize ); + tt_face_get_location( FT_Face face, + FT_UInt gindex, + FT_ULong *asize ); FT_LOCAL( void ) tt_face_done_loca( TT_Face face ); diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.c b/src/3rdparty/freetype/src/truetype/ttsubpix.c deleted file mode 100644 index 2438d3a2a2..0000000000 --- a/src/3rdparty/freetype/src/truetype/ttsubpix.c +++ /dev/null @@ -1,1013 +0,0 @@ -/**************************************************************************** - * - * ttsubpix.c - * - * TrueType Subpixel Hinting. - * - * Copyright (C) 2010-2022 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - -#include <freetype/internal/ftdebug.h> -#include <freetype/internal/ftcalc.h> -#include <freetype/internal/ftstream.h> -#include <freetype/internal/sfnt.h> -#include <freetype/tttags.h> -#include <freetype/ftoutln.h> -#include <freetype/ftdriver.h> - -#include "ttsubpix.h" - - -#if defined( TT_USE_BYTECODE_INTERPRETER ) && \ - defined( TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY ) - - /************************************************************************** - * - * These rules affect how the TT Interpreter does hinting, with the - * goal of doing subpixel hinting by (in general) ignoring x moves. - * Some of these rules are fixes that go above and beyond the - * stated techniques in the MS whitepaper on Cleartype, due to - * artifacts in many glyphs. So, these rules make some glyphs render - * better than they do in the MS rasterizer. - * - * "" string or 0 int/char indicates to apply to all glyphs. - * "-" used as dummy placeholders, but any non-matching string works. - * - * Some of this could arguably be implemented in fontconfig, however: - * - * - Fontconfig can't set things on a glyph-by-glyph basis. - * - The tweaks that happen here are very low-level, from an average - * user's point of view and are best implemented in the hinter. - * - * The goal is to make the subpixel hinting techniques as generalized - * as possible across all fonts to prevent the need for extra rules such - * as these. - * - * The rule structure is designed so that entirely new rules can easily - * be added when a new compatibility feature is discovered. - * - * The rule structures could also use some enhancement to handle ranges. - * - * ****************** WORK IN PROGRESS ******************* - */ - - /* These are `classes' of fonts that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define FAMILY_CLASS_RULES_SIZE 7 - - static const SPH_Font_Class FAMILY_CLASS_Rules - [FAMILY_CLASS_RULES_SIZE] = - { - { "MS Legacy Fonts", - { "Aharoni", - "Andale Mono", - "Andalus", - "Angsana New", - "AngsanaUPC", - "Arabic Transparent", - "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Batang", - "Browallia New", - "BrowalliaUPC", - "Comic Sans MS", - "Cordia New", - "CordiaUPC", - "Courier New", - "DFKai-SB", - "David Transparent", - "David", - "DilleniaUPC", - "Estrangelo Edessa", - "EucrosiaUPC", - "FangSong_GB2312", - "Fixed Miriam Transparent", - "FrankRuehl", - "Franklin Gothic Medium", - "FreesiaUPC", - "Garamond", - "Gautami", - "Georgia", - "Gulim", - "Impact", - "IrisUPC", - "JasmineUPC", - "KaiTi_GB2312", - "KodchiangUPC", - "Latha", - "Levenim MT", - "LilyUPC", - "Lucida Console", - "Lucida Sans Unicode", - "MS Gothic", - "MS Mincho", - "MV Boli", - "Mangal", - "Marlett", - "Microsoft Sans Serif", - "Mingliu", - "Miriam Fixed", - "Miriam Transparent", - "Miriam", - "Narkisim", - "Palatino Linotype", - "Raavi", - "Rod Transparent", - "Rod", - "Shruti", - "SimHei", - "Simplified Arabic Fixed", - "Simplified Arabic", - "Simsun", - "Sylfaen", - "Symbol", - "Tahoma", - "Times New Roman", - "Traditional Arabic", - "Trebuchet MS", - "Tunga", - "Verdana", - "Webdings", - "Wingdings", - "", - }, - }, - { "Core MS Legacy Fonts", - { "Arial Black", - "Arial Narrow", - "Arial Unicode MS", - "Arial", - "Comic Sans MS", - "Courier New", - "Garamond", - "Georgia", - "Impact", - "Lucida Console", - "Lucida Sans Unicode", - "Microsoft Sans Serif", - "Palatino Linotype", - "Tahoma", - "Times New Roman", - "Trebuchet MS", - "Verdana", - "", - }, - }, - { "Apple Legacy Fonts", - { "Geneva", - "Times", - "Monaco", - "Century", - "Chalkboard", - "Lobster", - "Century Gothic", - "Optima", - "Lucida Grande", - "Gill Sans", - "Baskerville", - "Helvetica", - "Helvetica Neue", - "", - }, - }, - { "Legacy Sans Fonts", - { "Andale Mono", - "Arial Unicode MS", - "Arial", - "Century Gothic", - "Comic Sans MS", - "Franklin Gothic Medium", - "Geneva", - "Lucida Console", - "Lucida Grande", - "Lucida Sans Unicode", - "Lucida Sans Typewriter", - "Microsoft Sans Serif", - "Monaco", - "Tahoma", - "Trebuchet MS", - "Verdana", - "", - }, - }, - - { "Misc Legacy Fonts", - { "Dark Courier", "", }, }, - { "Verdana Clones", - { "DejaVu Sans", - "Bitstream Vera Sans", "", }, }, - { "Verdana and Clones", - { "DejaVu Sans", - "Bitstream Vera Sans", - "Verdana", "", }, }, - }; - - - /* Define this to force natural (i.e. not bitmap-compatible) widths. */ - /* The default leans strongly towards natural widths except for a few */ - /* legacy fonts where a selective combination produces nicer results. */ -/* #define FORCE_NATURAL_WIDTHS */ - - - /* Define `classes' of styles that can be grouped together and used in */ - /* rules below. A blank entry "" is required at the end of these! */ -#define STYLE_CLASS_RULES_SIZE 5 - - static const SPH_Font_Class STYLE_CLASS_Rules - [STYLE_CLASS_RULES_SIZE] = - { - { "Regular Class", - { "Regular", - "Book", - "Medium", - "Roman", - "Normal", - "", - }, - }, - { "Regular/Italic Class", - { "Regular", - "Book", - "Medium", - "Italic", - "Oblique", - "Roman", - "Normal", - "", - }, - }, - { "Bold/BoldItalic Class", - { "Bold", - "Bold Italic", - "Black", - "", - }, - }, - { "Bold/Italic/BoldItalic Class", - { "Bold", - "Bold Italic", - "Black", - "Italic", - "Oblique", - "", - }, - }, - { "Regular/Bold Class", - { "Regular", - "Book", - "Medium", - "Normal", - "Roman", - "Bold", - "Black", - "", - }, - }, - }; - - - /* Force special legacy fixes for fonts. */ -#define COMPATIBILITY_MODE_RULES_SIZE 1 - - static const SPH_TweakRule COMPATIBILITY_MODE_Rules - [COMPATIBILITY_MODE_RULES_SIZE] = - { - { "Verdana Clones", 0, "", 0 }, - }; - - - /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting. */ -#define PIXEL_HINTING_RULES_SIZE 2 - - static const SPH_TweakRule PIXEL_HINTING_Rules - [PIXEL_HINTING_RULES_SIZE] = - { - /* these characters are almost always safe */ - { "Courier New", 12, "Italic", 'z' }, - { "Courier New", 11, "Italic", 'z' }, - }; - - - /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ -#define DO_SHPIX_RULES_SIZE 1 - - static const SPH_TweakRule DO_SHPIX_Rules - [DO_SHPIX_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Skip Y moves that start with a point that is not on a Y pixel */ - /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 4 - - static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules - [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* fix vwxyz thinness */ - { "Consolas", 0, "", 0 }, - /* Fix thin middle stems */ - { "Core MS Legacy Fonts", 0, "Regular", 0 }, - /* Cyrillic small letter I */ - { "Legacy Sans Fonts", 0, "", 0 }, - /* Fix artifacts with some Regular & Bold */ - { "Verdana Clones", 0, "", 0 }, - }; - - -#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - /* Fixes < and > */ - { "Courier New", 0, "Regular", 0 }, - }; - - - /* Skip Y moves that start with a point that is not on a Y pixel */ - /* boundary and don't move that point to a Y pixel boundary. */ -#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE 2 - - static const SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules - [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] = - { - /* Maintain thickness of diagonal in 'N' */ - { "Times New Roman", 0, "Regular/Bold Class", 'N' }, - { "Georgia", 0, "Regular/Bold Class", 'N' }, - }; - - - /* Skip Y moves that move a point off a Y pixel boundary. */ -#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 1 - - static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules - [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - -#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - static const SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions - [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Round moves that don't move a point to a Y pixel boundary. */ -#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 2 - - static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules - [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = - { - /* Droid font instructions don't snap Y to pixels */ - { "Droid Sans", 0, "Regular/Italic Class", 0 }, - { "Droid Sans Mono", 0, "", 0 }, - }; - - -#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 - - static const SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions - [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Allow a Direct_Move along X freedom vector if matched. */ -#define ALLOW_X_DMOVE_RULES_SIZE 1 - - static const SPH_TweakRule ALLOW_X_DMOVE_Rules - [ALLOW_X_DMOVE_RULES_SIZE] = - { - /* Fixes vanishing diagonal in 4 */ - { "Verdana", 0, "Regular", '4' }, - }; - - - /* Return MS rasterizer version 35 if matched. */ -#define RASTERIZER_35_RULES_SIZE 8 - - static const SPH_TweakRule RASTERIZER_35_Rules - [RASTERIZER_35_RULES_SIZE] = - { - /* This seems to be the only way to make these look good */ - { "Times New Roman", 0, "Regular", 'i' }, - { "Times New Roman", 0, "Regular", 'j' }, - { "Times New Roman", 0, "Regular", 'm' }, - { "Times New Roman", 0, "Regular", 'r' }, - { "Times New Roman", 0, "Regular", 'a' }, - { "Times New Roman", 0, "Regular", 'n' }, - { "Times New Roman", 0, "Regular", 'p' }, - { "Times", 0, "", 0 }, - }; - - - /* Don't round to the subpixel grid. Round to pixel grid. */ -#define NORMAL_ROUND_RULES_SIZE 1 - - static const SPH_TweakRule NORMAL_ROUND_Rules - [NORMAL_ROUND_RULES_SIZE] = - { - /* Fix serif thickness for certain ppems */ - /* Can probably be generalized somehow */ - { "Courier New", 0, "", 0 }, - }; - - - /* Skip IUP instructions if matched. */ -#define SKIP_IUP_RULES_SIZE 1 - - static const SPH_TweakRule SKIP_IUP_Rules - [SKIP_IUP_RULES_SIZE] = - { - { "Arial", 13, "Regular", 'a' }, - }; - - - /* Skip MIAP Twilight hack if matched. */ -#define MIAP_HACK_RULES_SIZE 1 - - static const SPH_TweakRule MIAP_HACK_Rules - [MIAP_HACK_RULES_SIZE] = - { - { "Geneva", 12, "", 0 }, - }; - - - /* Skip DELTAP instructions if matched. */ -#define ALWAYS_SKIP_DELTAP_RULES_SIZE 23 - - static const SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules - [ALWAYS_SKIP_DELTAP_RULES_SIZE] = - { - { "Georgia", 0, "Regular", 'k' }, - /* fix various problems with e in different versions */ - { "Trebuchet MS", 14, "Regular", 'e' }, - { "Trebuchet MS", 13, "Regular", 'e' }, - { "Trebuchet MS", 15, "Regular", 'e' }, - { "Trebuchet MS", 0, "Italic", 'v' }, - { "Trebuchet MS", 0, "Italic", 'w' }, - { "Trebuchet MS", 0, "Regular", 'Y' }, - { "Arial", 11, "Regular", 's' }, - /* prevent problems with '3' and others */ - { "Verdana", 10, "Regular", 0 }, - { "Verdana", 9, "Regular", 0 }, - /* Cyrillic small letter short I */ - { "Legacy Sans Fonts", 0, "", 0x438 }, - { "Legacy Sans Fonts", 0, "", 0x439 }, - { "Arial", 10, "Regular", '6' }, - { "Arial", 0, "Bold/BoldItalic Class", 'a' }, - /* Make horizontal stems consistent with the rest */ - { "Arial", 24, "Bold", 'a' }, - { "Arial", 25, "Bold", 'a' }, - { "Arial", 24, "Bold", 's' }, - { "Arial", 25, "Bold", 's' }, - { "Arial", 34, "Bold", 's' }, - { "Arial", 35, "Bold", 's' }, - { "Arial", 36, "Bold", 's' }, - { "Arial", 25, "Regular", 's' }, - { "Arial", 26, "Regular", 's' }, - }; - - - /* Always do DELTAP instructions if matched. */ -#define ALWAYS_DO_DELTAP_RULES_SIZE 1 - - static const SPH_TweakRule ALWAYS_DO_DELTAP_Rules - [ALWAYS_DO_DELTAP_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Don't allow ALIGNRP after IUP. */ -#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules - [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "-", 0, "", 0 }, - }; - - - /* Don't allow DELTAP after IUP. */ -#define NO_DELTAP_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules - [NO_DELTAP_AFTER_IUP_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - - /* Don't allow CALL after IUP. */ -#define NO_CALL_AFTER_IUP_RULES_SIZE 1 - - static const SPH_TweakRule NO_CALL_AFTER_IUP_Rules - [NO_CALL_AFTER_IUP_RULES_SIZE] = - { - /* Prevent creation of dents in outline */ - { "-", 0, "", 0 }, - }; - - - /* De-embolden these glyphs slightly. */ -#define DEEMBOLDEN_RULES_SIZE 9 - - static const SPH_TweakRule DEEMBOLDEN_Rules - [DEEMBOLDEN_RULES_SIZE] = - { - { "Courier New", 0, "Bold", 'A' }, - { "Courier New", 0, "Bold", 'W' }, - { "Courier New", 0, "Bold", 'w' }, - { "Courier New", 0, "Bold", 'M' }, - { "Courier New", 0, "Bold", 'X' }, - { "Courier New", 0, "Bold", 'K' }, - { "Courier New", 0, "Bold", 'x' }, - { "Courier New", 0, "Bold", 'z' }, - { "Courier New", 0, "Bold", 'v' }, - }; - - - /* Embolden these glyphs slightly. */ -#define EMBOLDEN_RULES_SIZE 2 - - static const SPH_TweakRule EMBOLDEN_Rules - [EMBOLDEN_RULES_SIZE] = - { - { "Courier New", 0, "Regular", 0 }, - { "Courier New", 0, "Italic", 0 }, - }; - - - /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */ - /* similar to Windows XP. */ -#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12 - - static const SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules - [TIMES_NEW_ROMAN_HACK_RULES_SIZE] = - { - { "Times New Roman", 16, "Italic", '2' }, - { "Times New Roman", 16, "Italic", '5' }, - { "Times New Roman", 16, "Italic", '7' }, - { "Times New Roman", 16, "Regular", '2' }, - { "Times New Roman", 16, "Regular", '5' }, - { "Times New Roman", 16, "Regular", '7' }, - { "Times New Roman", 17, "Italic", '2' }, - { "Times New Roman", 17, "Italic", '5' }, - { "Times New Roman", 17, "Italic", '7' }, - { "Times New Roman", 17, "Regular", '2' }, - { "Times New Roman", 17, "Regular", '5' }, - { "Times New Roman", 17, "Regular", '7' }, - }; - - - /* This fudges distance on 2 to get rid of the vanishing stem issue. */ - /* A real solution to this is certainly welcome. */ -#define COURIER_NEW_2_HACK_RULES_SIZE 15 - - static const SPH_TweakRule COURIER_NEW_2_HACK_Rules - [COURIER_NEW_2_HACK_RULES_SIZE] = - { - { "Courier New", 10, "Regular", '2' }, - { "Courier New", 11, "Regular", '2' }, - { "Courier New", 12, "Regular", '2' }, - { "Courier New", 13, "Regular", '2' }, - { "Courier New", 14, "Regular", '2' }, - { "Courier New", 15, "Regular", '2' }, - { "Courier New", 16, "Regular", '2' }, - { "Courier New", 17, "Regular", '2' }, - { "Courier New", 18, "Regular", '2' }, - { "Courier New", 19, "Regular", '2' }, - { "Courier New", 20, "Regular", '2' }, - { "Courier New", 21, "Regular", '2' }, - { "Courier New", 22, "Regular", '2' }, - { "Courier New", 23, "Regular", '2' }, - { "Courier New", 24, "Regular", '2' }, - }; - - -#ifndef FORCE_NATURAL_WIDTHS - - /* Use compatible widths with these glyphs. Compatible widths is always */ - /* on when doing B/W TrueType instructing, but is used selectively here, */ - /* typically on glyphs with 3 or more vertical stems. */ -#define COMPATIBLE_WIDTHS_RULES_SIZE 38 - - static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "Arial Unicode MS", 12, "Regular Class", 'm' }, - { "Arial Unicode MS", 14, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 10, "Regular Class", 0x448 }, - { "Arial", 11, "Regular Class", 'm' }, - { "Arial", 12, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 12, "Regular Class", 0x448 }, - { "Arial", 13, "Regular Class", 0x448 }, - { "Arial", 14, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Arial", 14, "Regular Class", 0x448 }, - { "Arial", 15, "Regular Class", 0x448 }, - { "Arial", 17, "Regular Class", 'm' }, - { "DejaVu Sans", 15, "Regular Class", 0 }, - { "Microsoft Sans Serif", 11, "Regular Class", 0 }, - { "Microsoft Sans Serif", 12, "Regular Class", 0 }, - { "Segoe UI", 11, "Regular Class", 0 }, - { "Monaco", 0, "Regular Class", 0 }, - { "Segoe UI", 12, "Regular Class", 'm' }, - { "Segoe UI", 14, "Regular Class", 'm' }, - { "Tahoma", 11, "Regular Class", 0 }, - { "Times New Roman", 16, "Regular Class", 'c' }, - { "Times New Roman", 16, "Regular Class", 'm' }, - { "Times New Roman", 16, "Regular Class", 'o' }, - { "Times New Roman", 16, "Regular Class", 'w' }, - { "Trebuchet MS", 11, "Regular Class", 0 }, - { "Trebuchet MS", 12, "Regular Class", 0 }, - { "Trebuchet MS", 14, "Regular Class", 0 }, - { "Trebuchet MS", 15, "Regular Class", 0 }, - { "Ubuntu", 12, "Regular Class", 'm' }, - /* Cyrillic small letter sha */ - { "Verdana", 10, "Regular Class", 0x448 }, - { "Verdana", 11, "Regular Class", 0x448 }, - { "Verdana and Clones", 12, "Regular Class", 'i' }, - { "Verdana and Clones", 12, "Regular Class", 'j' }, - { "Verdana and Clones", 12, "Regular Class", 'l' }, - { "Verdana and Clones", 12, "Regular Class", 'm' }, - { "Verdana and Clones", 13, "Regular Class", 'i' }, - { "Verdana and Clones", 13, "Regular Class", 'j' }, - { "Verdana and Clones", 13, "Regular Class", 'l' }, - { "Verdana and Clones", 14, "Regular Class", 'm' }, - }; - - - /* Scaling slightly in the x-direction prior to hinting results in */ - /* more visually pleasing glyphs in certain cases. */ - /* This sometimes needs to be coordinated with compatible width rules. */ - /* A value of 1000 corresponds to a scaled value of 1.0. */ - -#define X_SCALING_RULES_SIZE 50 - - static const SPH_ScaleRule X_SCALING_Rules[X_SCALING_RULES_SIZE] = - { - { "DejaVu Sans", 12, "Regular Class", 'm', 950 }, - { "Verdana and Clones", 12, "Regular Class", 'a', 1100 }, - { "Verdana and Clones", 13, "Regular Class", 'a', 1050 }, - { "Arial", 11, "Regular Class", 'm', 975 }, - { "Arial", 12, "Regular Class", 'm', 1050 }, - /* Cyrillic small letter el */ - { "Arial", 13, "Regular Class", 0x43B, 950 }, - { "Arial", 13, "Regular Class", 'o', 950 }, - { "Arial", 13, "Regular Class", 'e', 950 }, - { "Arial", 14, "Regular Class", 'm', 950 }, - /* Cyrillic small letter el */ - { "Arial", 15, "Regular Class", 0x43B, 925 }, - { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 }, - { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 }, - { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 }, - { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 }, - { "DejaVu Sans", 12, "Regular Class", 'l', 975 }, - { "DejaVu Sans", 12, "Regular Class", 'i', 975 }, - { "DejaVu Sans", 12, "Regular Class", 'j', 975 }, - { "DejaVu Sans", 13, "Regular Class", 'l', 950 }, - { "DejaVu Sans", 13, "Regular Class", 'i', 950 }, - { "DejaVu Sans", 13, "Regular Class", 'j', 950 }, - { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 }, - { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 }, - { "Georgia", 10, "", 0, 1050 }, - { "Georgia", 11, "", 0, 1100 }, - { "Georgia", 12, "", 0, 1025 }, - { "Georgia", 13, "", 0, 1050 }, - { "Georgia", 16, "", 0, 1050 }, - { "Georgia", 17, "", 0, 1030 }, - { "Liberation Sans", 12, "Regular Class", 'm', 1100 }, - { "Lucida Grande", 11, "Regular Class", 'm', 1100 }, - { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 }, - { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 }, - { "Segoe UI", 12, "Regular Class", 'H', 1050 }, - { "Segoe UI", 12, "Regular Class", 'm', 1050 }, - { "Segoe UI", 14, "Regular Class", 'm', 1050 }, - { "Tahoma", 11, "Regular Class", 'i', 975 }, - { "Tahoma", 11, "Regular Class", 'l', 975 }, - { "Tahoma", 11, "Regular Class", 'j', 900 }, - { "Tahoma", 11, "Regular Class", 'm', 918 }, - { "Verdana", 10, "Regular/Italic Class", 0, 1100 }, - { "Verdana", 12, "Regular Class", 'm', 975 }, - { "Verdana", 12, "Regular/Italic Class", 0, 1050 }, - { "Verdana", 13, "Regular/Italic Class", 'i', 950 }, - { "Verdana", 13, "Regular/Italic Class", 'j', 950 }, - { "Verdana", 13, "Regular/Italic Class", 'l', 950 }, - { "Verdana", 16, "Regular Class", 0, 1050 }, - { "Verdana", 9, "Regular/Italic Class", 0, 1050 }, - { "Times New Roman", 16, "Regular Class", 'm', 918 }, - { "Trebuchet MS", 11, "Regular Class", 'm', 800 }, - { "Trebuchet MS", 12, "Regular Class", 'm', 800 }, - }; - -#else - -#define COMPATIBLE_WIDTHS_RULES_SIZE 1 - - static const SPH_TweakRule COMPATIBLE_WIDTHS_Rules - [COMPATIBLE_WIDTHS_RULES_SIZE] = - { - { "-", 0, "", 0 }, - }; - - -#define X_SCALING_RULES_SIZE 1 - - static const SPH_ScaleRule X_SCALING_Rules - [X_SCALING_RULES_SIZE] = - { - { "-", 0, "", 0, 1000 }, - }; - -#endif /* FORCE_NATURAL_WIDTHS */ - - - static FT_Bool - is_member_of_family_class( const FT_String* detected_font_name, - const FT_String* rule_font_name ) - { - FT_UInt i, j; - - - /* Does font name match rule family? */ - if ( ft_strcmp( detected_font_name, rule_font_name ) == 0 ) - return TRUE; - - /* Is font name a wildcard ""? */ - if ( ft_strcmp( rule_font_name, "" ) == 0 ) - return TRUE; - - /* Is font name contained in a class list? */ - for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) - { - if ( ft_strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) - { - for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) - { - if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j], - detected_font_name ) == 0 ) - return TRUE; - } - } - } - - return FALSE; - } - - - static FT_Bool - is_member_of_style_class( const FT_String* detected_font_style, - const FT_String* rule_font_style ) - { - FT_UInt i, j; - - - /* Does font style match rule style? */ - if ( ft_strcmp( detected_font_style, rule_font_style ) == 0 ) - return TRUE; - - /* Is font style a wildcard ""? */ - if ( ft_strcmp( rule_font_style, "" ) == 0 ) - return TRUE; - - /* Is font style contained in a class list? */ - for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) - { - if ( ft_strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) - { - for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) - { - if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) - continue; - if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j], - detected_font_style ) == 0 ) - return TRUE; - } - } - } - - return FALSE; - } - - - FT_LOCAL_DEF( FT_Bool ) - sph_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_TweakRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class ( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return TRUE; - } - - return FALSE; - } - - - static FT_UInt - scale_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_ScaleRule* rule, - FT_UInt num_rules ) - { - FT_UInt i; - - - /* rule checks may be able to be optimized further */ - for ( i = 0; i < num_rules; i++ ) - { - if ( family && - ( is_member_of_family_class ( family, rule[i].family ) ) ) - if ( rule[i].ppem == 0 || - rule[i].ppem == ppem ) - if ( style && - is_member_of_style_class( style, rule[i].style ) ) - if ( rule[i].glyph == 0 || - FT_Get_Char_Index( (FT_Face)face, - rule[i].glyph ) == glyph_index ) - return rule[i].scale; - } - - return 1000; - } - - - FT_LOCAL_DEF( FT_UInt ) - sph_test_tweak_x_scaling( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index ) - { - return scale_test_tweak( face, family, ppem, style, glyph_index, - X_SCALING_Rules, X_SCALING_RULES_SIZE ); - } - - -#define TWEAK_RULES( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules, x##_RULES_SIZE ) ) \ - loader->exec->sph_tweak_flags |= SPH_TWEAK_##x - -#define TWEAK_RULES_EXCEPTIONS( x ) \ - if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ - x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ - loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x - - - FT_LOCAL_DEF( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ) - { - TT_Face face = loader->face; - FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics->x_ppem; - FT_String* style = face->root.style_name; - - - /* don't apply rules if style isn't set */ - if ( !face->root.style_name ) - return; - -#ifdef SPH_DEBUG_MORE_VERBOSE - printf( "%s,%d,%s,%c=%d ", - family, ppem, style, glyph_index, glyph_index ); -#endif - - TWEAK_RULES( PIXEL_HINTING ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ) - { - loader->exec->ignore_x_mode = FALSE; - return; - } - - TWEAK_RULES( ALLOW_X_DMOVE ); - TWEAK_RULES( ALWAYS_DO_DELTAP ); - TWEAK_RULES( ALWAYS_SKIP_DELTAP ); - TWEAK_RULES( DEEMBOLDEN ); - TWEAK_RULES( DO_SHPIX ); - TWEAK_RULES( EMBOLDEN ); - TWEAK_RULES( MIAP_HACK ); - TWEAK_RULES( NORMAL_ROUND ); - TWEAK_RULES( NO_ALIGNRP_AFTER_IUP ); - TWEAK_RULES( NO_CALL_AFTER_IUP ); - TWEAK_RULES( NO_DELTAP_AFTER_IUP ); - TWEAK_RULES( RASTERIZER_35 ); - TWEAK_RULES( SKIP_IUP ); - - TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES ); - - TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP ); - - TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES ); - - TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES ); - TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES ); - - if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) - { - if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 ) - { - loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - loader->exec->size->cvt_ready = -1; - - tt_size_ready_bytecode( - loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - else - loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35; - } - else - { - if ( loader->exec->rasterizer_version != - SPH_OPTION_SET_RASTERIZER_VERSION ) - { - loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - loader->exec->size->cvt_ready = -1; - - tt_size_ready_bytecode( - loader->exec->size, - FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); - } - else - loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; - } - - if ( IS_HINTED( loader->load_flags ) ) - { - TWEAK_RULES( TIMES_NEW_ROMAN_HACK ); - TWEAK_RULES( COURIER_NEW_2_HACK ); - } - - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) ) - loader->exec->face->sph_compatibility_mode = TRUE; - - - if ( IS_HINTED( loader->load_flags ) ) - { - if ( sph_test_tweak( face, family, ppem, style, glyph_index, - COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) ) - loader->exec->compatible_widths |= TRUE; - } - } - -#else /* !(TT_USE_BYTECODE_INTERPRETER && */ - /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ - - /* ANSI C doesn't like empty source files */ - typedef int _tt_subpix_dummy; - -#endif /* !(TT_USE_BYTECODE_INTERPRETER && */ - /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ - - -/* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.h b/src/3rdparty/freetype/src/truetype/ttsubpix.h deleted file mode 100644 index 181f83810c..0000000000 --- a/src/3rdparty/freetype/src/truetype/ttsubpix.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** - * - * ttsubpix.h - * - * TrueType Subpixel Hinting. - * - * Copyright (C) 2010-2022 by - * David Turner, Robert Wilhelm, and Werner Lemberg. - * - * This file is part of the FreeType project, and may only be used, - * modified, and distributed under the terms of the FreeType project - * license, LICENSE.TXT. By continuing to use, modify, or distribute - * this file you indicate that you have read the license and - * understand and accept it fully. - * - */ - - -#ifndef TTSUBPIX_H_ -#define TTSUBPIX_H_ - -#include "ttobjs.h" -#include "ttinterp.h" - - -FT_BEGIN_HEADER - - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - - /************************************************************************** - * - * ID flags to identify special functions at FDEF and runtime. - * - */ -#define SPH_FDEF_INLINE_DELTA_1 0x0000001 -#define SPH_FDEF_INLINE_DELTA_2 0x0000002 -#define SPH_FDEF_DIAGONAL_STROKE 0x0000004 -#define SPH_FDEF_VACUFORM_ROUND_1 0x0000008 -#define SPH_FDEF_TTFAUTOHINT_1 0x0000010 -#define SPH_FDEF_SPACING_1 0x0000020 -#define SPH_FDEF_SPACING_2 0x0000040 -#define SPH_FDEF_TYPEMAN_STROKES 0x0000080 -#define SPH_FDEF_TYPEMAN_DIAGENDCTRL 0x0000100 - - - /************************************************************************** - * - * Tweak flags that are set for each glyph by the below rules. - * - */ -#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001UL -#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000002UL -#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000004UL -#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000008UL -#define SPH_TWEAK_DEEMBOLDEN 0x0000010UL -#define SPH_TWEAK_DO_SHPIX 0x0000020UL -#define SPH_TWEAK_EMBOLDEN 0x0000040UL -#define SPH_TWEAK_MIAP_HACK 0x0000080UL -#define SPH_TWEAK_NORMAL_ROUND 0x0000100UL -#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0000200UL -#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0000400UL -#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0000800UL -#define SPH_TWEAK_PIXEL_HINTING 0x0001000UL -#define SPH_TWEAK_RASTERIZER_35 0x0002000UL -#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0004000UL -#define SPH_TWEAK_SKIP_IUP 0x0008000UL -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0010000UL -#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0020000UL -#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0040000UL -#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP 0x0080000UL - - - FT_LOCAL( FT_Bool ) - sph_test_tweak( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index, - const SPH_TweakRule* rule, - FT_UInt num_rules ); - - FT_LOCAL( FT_UInt ) - sph_test_tweak_x_scaling( TT_Face face, - const FT_String* family, - FT_UInt ppem, - const FT_String* style, - FT_UInt glyph_index ); - - FT_LOCAL( void ) - sph_set_tweaks( TT_Loader loader, - FT_UInt glyph_index ); - - - /* These macros are defined absent a method for setting them */ -#define SPH_OPTION_BITMAP_WIDTHS FALSE -#define SPH_OPTION_SET_SUBPIXEL TRUE -#define SPH_OPTION_SET_GRAYSCALE FALSE -#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE -#define SPH_OPTION_SET_RASTERIZER_VERSION 38 - -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - - -FT_END_HEADER - -#endif /* TTSUBPIX_H_ */ - - -/* END */ |