diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-06-09 17:30:54 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-06-09 17:30:54 +0300 |
commit | da6e958319e95fe564d3b30c931492dd666bfaff (patch) | |
tree | 16ac1556a573daeba5c9c4b795f86aa166ffe467 /src/3rdparty/freetype/src/truetype/ttinterp.c | |
parent | 29400a683f96867133b28299c0d0bd6bcf40df35 (diff) | |
parent | a96fc76fa78f3500266b3a34016f9e1bd29b319c (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.11' into tqtc/lts-5.15-opensourcev5.15.11-lts-lgpl
Change-Id: Iac056a5e9f59fc8d1929171c18039aeb45be22b8
Diffstat (limited to 'src/3rdparty/freetype/src/truetype/ttinterp.c')
-rw-r--r-- | src/3rdparty/freetype/src/truetype/ttinterp.c | 245 |
1 files changed, 129 insertions, 116 deletions
diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.c b/src/3rdparty/freetype/src/truetype/ttinterp.c index 0c3cb10ae8..e16565c3a5 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-2020 by + * Copyright (C) 1996-2022 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, @@ -251,6 +251,14 @@ FT_FREE( exec->stack ); exec->stackSize = 0; + /* free glyf cvt working area */ + FT_FREE( exec->glyfCvt ); + exec->glyfCvtSize = 0; + + /* free glyf storage working area */ + FT_FREE( exec->glyfStorage ); + exec->glyfStoreSize = 0; + /* free call stack */ FT_FREE( exec->callStack ); exec->callSize = 0; @@ -270,64 +278,6 @@ /************************************************************************** * * @Function: - * Init_Context - * - * @Description: - * Initializes a context object. - * - * @Input: - * memory :: - * A handle to the parent memory object. - * - * @InOut: - * exec :: - * A handle to the target execution context. - * - * @Return: - * FreeType error code. 0 means success. - */ - static FT_Error - Init_Context( TT_ExecContext exec, - FT_Memory memory ) - { - FT_Error error; - - - FT_TRACE1(( "Init_Context: new object at %p\n", (void *)exec )); - - exec->memory = memory; - exec->callSize = 32; - - if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) - goto Fail_Memory; - - /* all values in the context are set to 0 already, but this is */ - /* here as a remainder */ - exec->maxPoints = 0; - exec->maxContours = 0; - - exec->stackSize = 0; - exec->glyphSize = 0; - - exec->stack = NULL; - exec->glyphIns = NULL; - - exec->face = NULL; - exec->size = NULL; - - return FT_Err_Ok; - - Fail_Memory: - FT_ERROR(( "Init_Context: not enough memory for %p\n", (void *)exec )); - TT_Done_Context( exec ); - - return error; - } - - - /************************************************************************** - * - * @Function: * Update_Max * * @Description: @@ -367,7 +317,7 @@ if ( *size < new_max ) { - if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) + if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) return error; *size = new_max; } @@ -400,6 +350,8 @@ * * @Note: * Only the glyph loader and debugger should call this function. + * + * Note that not all members of `TT_ExecContext` get initialized. */ FT_LOCAL_DEF( FT_Error ) TT_Load_Context( TT_ExecContext exec, @@ -464,13 +416,13 @@ if ( error ) return error; - tmp = exec->glyphSize; + tmp = (FT_ULong)exec->glyphSize; error = Update_Max( exec->memory, &tmp, sizeof ( FT_Byte ), (void*)&exec->glyphIns, maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UShort)tmp; + exec->glyphSize = (FT_UInt)tmp; if ( error ) return error; @@ -609,19 +561,19 @@ memory = driver->root.root.memory; - /* allocate object */ + /* allocate object and zero everything inside */ if ( FT_NEW( exec ) ) goto Fail; - /* initialize it; in case of error this deallocates `exec' too */ - error = Init_Context( exec, memory ); - if ( error ) - goto Fail; + /* create callStack here, other allocations delayed */ + exec->memory = memory; + exec->callSize = 32; - return exec; + if ( FT_QNEW_ARRAY( exec->callStack, exec->callSize ) ) + FT_FREE( exec ); Fail: - return NULL; + return exec; } @@ -1572,11 +1524,36 @@ } + 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->error = Update_Max( exc->memory, + &exc->glyfCvtSize, + sizeof ( FT_Long ), + (void*)&exc->glyfCvt, + exc->cvtSize ); + if ( exc->error ) + return; + + FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize ); + exc->cvt = exc->glyfCvt; + } + } + + FT_CALLBACK_DEF( void ) Write_CVT( TT_ExecContext exc, FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = value; } @@ -1586,6 +1563,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) ); } @@ -1595,6 +1576,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value ); } @@ -1604,6 +1589,10 @@ FT_ULong idx, FT_F26Dot6 value ) { + Modify_CVT_Check( exc ); + if ( exc->error ) + return; + exc->cvt[idx] = ADD_LONG( exc->cvt[idx], FT_DivFix( value, Current_Ratio( exc ) ) ); } @@ -3125,7 +3114,30 @@ ARRAY_BOUND_ERROR; } else + { + /* TT_RunIns sets origStorage and restores storage to origStorage */ + /* when done. */ + if ( exc->iniRange == tt_coderange_glyph && + exc->storage == exc->origStorage ) + { + FT_ULong tmp = (FT_ULong)exc->glyfStoreSize; + + + exc->error = Update_Max( exc->memory, + &tmp, + sizeof ( FT_Long ), + (void*)&exc->glyfStorage, + exc->storeSize ); + exc->glyfStoreSize = (FT_UShort)tmp; + if ( exc->error ) + return; + + FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize ); + exc->storage = exc->glyfStorage; + } + exc->storage[I] = args[1]; + } } @@ -3525,7 +3537,7 @@ return; } - exc->IP += args[0]; + exc->IP = ADD_LONG( exc->IP, args[0] ); if ( exc->IP < 0 || ( exc->callTop > 0 && exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) @@ -3697,7 +3709,7 @@ /* FDEF is only allowed in `prep' or `fpgm' */ - if ( exc->curRange == tt_coderange_glyph ) + if ( exc->iniRange == tt_coderange_glyph ) { exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); return; @@ -3771,7 +3783,7 @@ if ( opcode_pointer[i] == opcode_size[i] ) { - FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n", + FT_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n", i, n, exc->face->root.family_name, exc->face->root.style_name )); @@ -4133,7 +4145,7 @@ /* we enable IDEF only in `prep' or `fpgm' */ - if ( exc->curRange == tt_coderange_glyph ) + if ( exc->iniRange == tt_coderange_glyph ) { exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); return; @@ -4362,7 +4374,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -4991,9 +5003,9 @@ #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING_INFINALITY && - exc->ignore_x_mode && - FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + ( D < 0 ? NEG_LONG( D ) : D ) == 64 ) D += 1; #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ @@ -5050,7 +5062,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -5074,7 +5086,7 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ + C = B; /* counter-clockwise rotation */ B = A; A = NEG_LONG( C ); } @@ -5248,16 +5260,21 @@ } } - exc->GS.instruct_control &= ~(FT_Byte)Kf; - exc->GS.instruct_control |= (FT_Byte)L; + /* INSTCTRL should only be used in the CVT program */ + if ( exc->iniRange == tt_coderange_cvt ) + { + exc->GS.instruct_control &= ~(FT_Byte)Kf; + exc->GS.instruct_control |= (FT_Byte)L; + } - if ( K == 3 ) + /* 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 ); + exc->ignore_x_mode = !FT_BOOL( L == 4 ); #endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL @@ -5268,6 +5285,8 @@ exc->backward_compatibility = !FT_BOOL( L == 4 ); #endif } + else if ( exc->pedantic_hinting ) + exc->error = FT_THROW( Invalid_Reference ); } @@ -7743,35 +7762,6 @@ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - exc->iup_called = FALSE; -#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - -#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - /* - * Toggle backward compatibility according to what font wants, except - * when - * - * 1) we have a `tricky' font that heavily relies on the interpreter to - * render glyphs correctly, for example DFKai-SB, or - * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. - * - * In those cases, backward compatibility needs to be turned off to get - * correct rendering. The rendering is then completely up to the - * font's programming. - * - */ - if ( SUBPIXEL_HINTING_MINIMAL && - exc->subpixel_hinting_lean && - !FT_IS_TRICKY( &exc->face->root ) ) - exc->backward_compatibility = !( exc->GS.instruct_control & 4 ); - else - exc->backward_compatibility = FALSE; - - exc->iupx_called = FALSE; - exc->iupy_called = FALSE; -#endif - /* We restrict the number of twilight points to a reasonable, */ /* heuristic value to avoid slow execution of malformed bytecode. */ num_twilight_points = FT_MAX( 30, @@ -7781,8 +7771,8 @@ if ( num_twilight_points > 0xFFFFU ) num_twilight_points = 0xFFFFU; - FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" - " from %d to the more reasonable value %ld\n", + FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" )); + FT_TRACE5(( " from %d to the more reasonable value %ld\n", exc->twilight.n_points, num_twilight_points )); exc->twilight.n_points = (FT_UShort)num_twilight_points; @@ -7842,14 +7832,28 @@ 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; +#endif + do { exc->opcode = exc->code[exc->IP]; #ifdef FT_DEBUG_LEVEL_TRACE + if ( ft_trace_levels[trace_ttinterp] >= 6 ) { FT_Long cnt = FT_MIN( 8, exc->top ); FT_Long n; @@ -8566,8 +8570,10 @@ /* 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 ) - return FT_THROW( Execution_Too_Long ); + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) { + exc->error = FT_THROW( Execution_Too_Long ); + goto LErrorLabel_; + } LSuiteLabel_: if ( exc->IP >= exc->codeSize ) @@ -8586,6 +8592,10 @@ FT_TRACE4(( " %ld instruction%s executed\n", ins_counter, ins_counter == 1 ? "" : "s" )); + + exc->cvt = exc->origCvt; + exc->storage = exc->origStorage; + return FT_Err_Ok; LErrorCodeOverflow_: @@ -8595,6 +8605,9 @@ 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; } |