1 /****************************************************************************
2 *
3 * ttinterp.c
4 *
5 * TrueType bytecode interpreter (body).
6 *
7 * Copyright (C) 1996-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */
20 /* issues; many thanks! */
21
22
23 #include <ft2build.h>
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_CALC_H
26 #include FT_TRIGONOMETRY_H
27 #include FT_SYSTEM_H
3701 },
3702 };
3703 FT_UShort opcode_patterns = 9;
3704 FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3705 FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
3706 FT_UShort i;
3707 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
3708
3709
3710 /* FDEF is only allowed in `prep' or `fpgm' */
3711 if ( exc->curRange == tt_coderange_glyph )
3712 {
3713 exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
3714 return;
3715 }
3716
3717 /* some font programs are broken enough to redefine functions! */
3718 /* We will then parse the current table. */
3719
3720 rec = exc->FDefs;
3721 limit = rec + exc->numFDefs;
3722 n = (FT_ULong)args[0];
3723
3724 for ( ; rec < limit; rec++ )
3725 {
3726 if ( rec->opc == n )
3727 break;
3728 }
3729
3730 if ( rec == limit )
3731 {
3732 /* check that there is enough room for new functions */
3733 if ( exc->numFDefs >= exc->maxFDefs )
3734 {
3735 exc->error = FT_THROW( Too_Many_Function_Defs );
3736 return;
3737 }
3738 exc->numFDefs++;
3739 }
3740
3741 /* Although FDEF takes unsigned 32-bit integer, */
3948 *
3949 * CALL[]: CALL function
3950 * Opcode range: 0x2B
3951 * Stack: uint32? -->
3952 */
3953 static void
3954 Ins_CALL( TT_ExecContext exc,
3955 FT_Long* args )
3956 {
3957 FT_ULong F;
3958 TT_CallRec* pCrec;
3959 TT_DefRecord* def;
3960
3961
3962 /* first of all, check the index */
3963
3964 F = (FT_ULong)args[0];
3965 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
3966 goto Fail;
3967
3968 /* Except for some old Apple fonts, all functions in a TrueType */
3969 /* font are defined in increasing order, starting from 0. This */
3970 /* means that we normally have */
3971 /* */
3972 /* exc->maxFunc+1 == exc->numFDefs */
3973 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
3974 /* */
3975 /* If this isn't true, we need to look up the function table. */
3976
3977 def = exc->FDefs + F;
3978 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
3979 {
3980 /* look up the FDefs table */
3981 TT_DefRecord* limit;
3982
3983
3984 def = exc->FDefs;
3985 limit = def + exc->numFDefs;
3986
3987 while ( def < limit && def->opc != F )
4045 {
4046 FT_ULong F;
4047 TT_CallRec* pCrec;
4048 TT_DefRecord* def;
4049
4050
4051 /* first of all, check the index */
4052 F = (FT_ULong)args[1];
4053 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
4054 goto Fail;
4055
4056 /* Except for some old Apple fonts, all functions in a TrueType */
4057 /* font are defined in increasing order, starting from 0. This */
4058 /* means that we normally have */
4059 /* */
4060 /* exc->maxFunc+1 == exc->numFDefs */
4061 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
4062 /* */
4063 /* If this isn't true, we need to look up the function table. */
4064
4065 def = exc->FDefs + F;
4066 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
4067 {
4068 /* look up the FDefs table */
4069 TT_DefRecord* limit;
4070
4071
4072 def = exc->FDefs;
4073 limit = def + exc->numFDefs;
4074
4075 while ( def < limit && def->opc != F )
4076 def++;
4077
4078 if ( def == limit )
4079 goto Fail;
4080 }
4081
4082 /* check that the function is active */
4083 if ( !def->active )
4084 goto Fail;
4085
4086 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
4087 if ( SUBPIXEL_HINTING_INFINALITY &&
4088 exc->ignore_x_mode &&
4089 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
4090 goto Fail;
4091 else
4092 exc->sph_in_func_flags = def->sph_fdef_flags;
4093 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
4133 * Stack: Eint8 -->
4134 */
4135 static void
4136 Ins_IDEF( TT_ExecContext exc,
4137 FT_Long* args )
4138 {
4139 TT_DefRecord* def;
4140 TT_DefRecord* limit;
4141
4142
4143 /* we enable IDEF only in `prep' or `fpgm' */
4144 if ( exc->curRange == tt_coderange_glyph )
4145 {
4146 exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
4147 return;
4148 }
4149
4150 /* First of all, look for the same function in our table */
4151
4152 def = exc->IDefs;
4153 limit = def + exc->numIDefs;
4154
4155 for ( ; def < limit; def++ )
4156 if ( def->opc == (FT_ULong)args[0] )
4157 break;
4158
4159 if ( def == limit )
4160 {
4161 /* check that there is enough room for a new instruction */
4162 if ( exc->numIDefs >= exc->maxIDefs )
4163 {
4164 exc->error = FT_THROW( Too_Many_Instruction_Defs );
4165 return;
4166 }
4167 exc->numIDefs++;
4168 }
4169
4170 /* opcode must be unsigned 8-bit integer */
4171 if ( 0 > args[0] || args[0] > 0x00FF )
4172 {
4173 exc->error = FT_THROW( Too_Many_Instruction_Defs );
6329 cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
6330
6331 /* single width test */
6332
6333 delta = SUB_LONG( cvt_dist, exc->GS.single_width_value );
6334 if ( delta < 0 )
6335 delta = NEG_LONG( delta );
6336
6337 if ( delta < exc->GS.single_width_cutin )
6338 {
6339 if ( cvt_dist >= 0 )
6340 cvt_dist = exc->GS.single_width_value;
6341 else
6342 cvt_dist = -exc->GS.single_width_value;
6343 }
6344
6345 /* UNDOCUMENTED! The MS rasterizer does that with */
6346 /* twilight points (confirmed by Greg Hitchcock) */
6347 if ( exc->GS.gep1 == 0 )
6348 {
6349 exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
6350 TT_MulFix14( cvt_dist,
6351 exc->GS.freeVector.x );
6352 exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
6353 TT_MulFix14( cvt_dist,
6354 exc->GS.freeVector.y );
6355 exc->zp1.cur[point] = exc->zp1.org[point];
6356 }
6357
6358 org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
6359 cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
6360
6361 /* auto-flip test */
6362
6363 if ( exc->GS.auto_flip )
6364 {
6365 if ( ( org_dist ^ cvt_dist ) < 0 )
6366 cvt_dist = NEG_LONG( cvt_dist );
6367 }
6368
6369 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
6370 if ( SUBPIXEL_HINTING_INFINALITY &&
6371 exc->ignore_x_mode &&
6372 exc->GS.freeVector.y != 0 &&
6373 ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
6374 {
7698 * GETDATA[]: no idea what this is good for
7699 * Opcode range: 0x92
7700 * Stack: --> 17
7701 *
7702 * XXX: UNDOCUMENTED! There is no documentation from Apple for this
7703 * very weird bytecode instruction.
7704 */
7705 static void
7706 Ins_GETDATA( FT_Long* args )
7707 {
7708 args[0] = 17;
7709 }
7710
7711 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
7712
7713
7714 static void
7715 Ins_UNKNOWN( TT_ExecContext exc )
7716 {
7717 TT_DefRecord* def = exc->IDefs;
7718 TT_DefRecord* limit = def + exc->numIDefs;
7719
7720
7721 for ( ; def < limit; def++ )
7722 {
7723 if ( (FT_Byte)def->opc == exc->opcode && def->active )
7724 {
7725 TT_CallRec* call;
7726
7727
7728 if ( exc->callTop >= exc->callSize )
7729 {
7730 exc->error = FT_THROW( Stack_Overflow );
7731 return;
7732 }
7733
7734 call = exc->callStack + exc->callTop++;
7735
7736 call->Caller_Range = exc->curRange;
7737 call->Caller_IP = exc->IP + 1;
7738 call->Cur_Count = 1;
7850 /* Set up loop detectors. We restrict the number of LOOPCALL loops */
7851 /* and the number of JMPR, JROT, and JROF calls with a negative */
7852 /* argument to values that depend on various parameters like the */
7853 /* size of the CVT table or the number of points in the current */
7854 /* glyph (if applicable). */
7855 /* */
7856 /* The idea is that in real-world bytecode you either iterate over */
7857 /* all CVT entries (in the `prep' table), or over all points (or */
7858 /* contours, in the `glyf' table) of a glyph, and such iterations */
7859 /* don't happen very often. */
7860 exc->loopcall_counter = 0;
7861 exc->neg_jump_counter = 0;
7862
7863 /* The maximum values are heuristic. */
7864 if ( exc->pts.n_points )
7865 exc->loopcall_counter_max = FT_MAX( 50,
7866 10 * exc->pts.n_points ) +
7867 FT_MAX( 50,
7868 exc->cvtSize / 10 );
7869 else
7870 exc->loopcall_counter_max = 300 + 8 * exc->cvtSize;
7871
7872 /* as a protection against an unreasonable number of CVT entries */
7873 /* we assume at most 100 control values per glyph for the counter */
7874 if ( exc->loopcall_counter_max >
7875 100 * (FT_ULong)exc->face->root.num_glyphs )
7876 exc->loopcall_counter_max = 100 * (FT_ULong)exc->face->root.num_glyphs;
7877
7878 FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL"
7879 " to %d\n", exc->loopcall_counter_max ));
7880
7881 exc->neg_jump_counter_max = exc->loopcall_counter_max;
7882 FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps"
7883 " to %d\n", exc->neg_jump_counter_max ));
7884
7885 /* set PPEM and CVT functions */
7886 exc->tt_metrics.ratio = 0;
7887 if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
7888 {
7889 /* non-square pixels, use the stretched routines */
7890 exc->func_cur_ppem = Current_Ppem_Stretched;
8550 Ins_MIRP( exc, args );
8551 else if ( opcode >= 0xC0 )
8552 Ins_MDRP( exc, args );
8553 else if ( opcode >= 0xB8 )
8554 Ins_PUSHW( exc, args );
8555 else if ( opcode >= 0xB0 )
8556 Ins_PUSHB( exc, args );
8557 else
8558 Ins_UNKNOWN( exc );
8559 }
8560 }
8561
8562 if ( exc->error )
8563 {
8564 switch ( exc->error )
8565 {
8566 /* looking for redefined instructions */
8567 case FT_ERR( Invalid_Opcode ):
8568 {
8569 TT_DefRecord* def = exc->IDefs;
8570 TT_DefRecord* limit = def + exc->numIDefs;
8571
8572
8573 for ( ; def < limit; def++ )
8574 {
8575 if ( def->active && exc->opcode == (FT_Byte)def->opc )
8576 {
8577 TT_CallRec* callrec;
8578
8579
8580 if ( exc->callTop >= exc->callSize )
8581 {
8582 exc->error = FT_THROW( Invalid_Reference );
8583 goto LErrorLabel_;
8584 }
8585
8586 callrec = &exc->callStack[exc->callTop];
8587
8588 callrec->Caller_Range = exc->curRange;
8589 callrec->Caller_IP = exc->IP + 1;
8590 callrec->Cur_Count = 1;
|
1 /****************************************************************************
2 *
3 * ttinterp.c
4 *
5 * TrueType bytecode interpreter (body).
6 *
7 * Copyright (C) 1996-2020 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */
20 /* issues; many thanks! */
21
22
23 #include <ft2build.h>
24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_CALC_H
26 #include FT_TRIGONOMETRY_H
27 #include FT_SYSTEM_H
3701 },
3702 };
3703 FT_UShort opcode_patterns = 9;
3704 FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3705 FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
3706 FT_UShort i;
3707 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
3708
3709
3710 /* FDEF is only allowed in `prep' or `fpgm' */
3711 if ( exc->curRange == tt_coderange_glyph )
3712 {
3713 exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
3714 return;
3715 }
3716
3717 /* some font programs are broken enough to redefine functions! */
3718 /* We will then parse the current table. */
3719
3720 rec = exc->FDefs;
3721 limit = FT_OFFSET( rec, exc->numFDefs );
3722 n = (FT_ULong)args[0];
3723
3724 for ( ; rec < limit; rec++ )
3725 {
3726 if ( rec->opc == n )
3727 break;
3728 }
3729
3730 if ( rec == limit )
3731 {
3732 /* check that there is enough room for new functions */
3733 if ( exc->numFDefs >= exc->maxFDefs )
3734 {
3735 exc->error = FT_THROW( Too_Many_Function_Defs );
3736 return;
3737 }
3738 exc->numFDefs++;
3739 }
3740
3741 /* Although FDEF takes unsigned 32-bit integer, */
3948 *
3949 * CALL[]: CALL function
3950 * Opcode range: 0x2B
3951 * Stack: uint32? -->
3952 */
3953 static void
3954 Ins_CALL( TT_ExecContext exc,
3955 FT_Long* args )
3956 {
3957 FT_ULong F;
3958 TT_CallRec* pCrec;
3959 TT_DefRecord* def;
3960
3961
3962 /* first of all, check the index */
3963
3964 F = (FT_ULong)args[0];
3965 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
3966 goto Fail;
3967
3968 if ( !exc->FDefs )
3969 goto Fail;
3970
3971 /* Except for some old Apple fonts, all functions in a TrueType */
3972 /* font are defined in increasing order, starting from 0. This */
3973 /* means that we normally have */
3974 /* */
3975 /* exc->maxFunc+1 == exc->numFDefs */
3976 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
3977 /* */
3978 /* If this isn't true, we need to look up the function table. */
3979
3980 def = exc->FDefs + F;
3981 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
3982 {
3983 /* look up the FDefs table */
3984 TT_DefRecord* limit;
3985
3986
3987 def = exc->FDefs;
3988 limit = def + exc->numFDefs;
3989
3990 while ( def < limit && def->opc != F )
4048 {
4049 FT_ULong F;
4050 TT_CallRec* pCrec;
4051 TT_DefRecord* def;
4052
4053
4054 /* first of all, check the index */
4055 F = (FT_ULong)args[1];
4056 if ( BOUNDSL( F, exc->maxFunc + 1 ) )
4057 goto Fail;
4058
4059 /* Except for some old Apple fonts, all functions in a TrueType */
4060 /* font are defined in increasing order, starting from 0. This */
4061 /* means that we normally have */
4062 /* */
4063 /* exc->maxFunc+1 == exc->numFDefs */
4064 /* exc->FDefs[n].opc == n for n in 0..exc->maxFunc */
4065 /* */
4066 /* If this isn't true, we need to look up the function table. */
4067
4068 def = FT_OFFSET( exc->FDefs, F );
4069 if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
4070 {
4071 /* look up the FDefs table */
4072 TT_DefRecord* limit;
4073
4074
4075 def = exc->FDefs;
4076 limit = FT_OFFSET( def, exc->numFDefs );
4077
4078 while ( def < limit && def->opc != F )
4079 def++;
4080
4081 if ( def == limit )
4082 goto Fail;
4083 }
4084
4085 /* check that the function is active */
4086 if ( !def->active )
4087 goto Fail;
4088
4089 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
4090 if ( SUBPIXEL_HINTING_INFINALITY &&
4091 exc->ignore_x_mode &&
4092 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
4093 goto Fail;
4094 else
4095 exc->sph_in_func_flags = def->sph_fdef_flags;
4096 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
4136 * Stack: Eint8 -->
4137 */
4138 static void
4139 Ins_IDEF( TT_ExecContext exc,
4140 FT_Long* args )
4141 {
4142 TT_DefRecord* def;
4143 TT_DefRecord* limit;
4144
4145
4146 /* we enable IDEF only in `prep' or `fpgm' */
4147 if ( exc->curRange == tt_coderange_glyph )
4148 {
4149 exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
4150 return;
4151 }
4152
4153 /* First of all, look for the same function in our table */
4154
4155 def = exc->IDefs;
4156 limit = FT_OFFSET( def, exc->numIDefs );
4157
4158 for ( ; def < limit; def++ )
4159 if ( def->opc == (FT_ULong)args[0] )
4160 break;
4161
4162 if ( def == limit )
4163 {
4164 /* check that there is enough room for a new instruction */
4165 if ( exc->numIDefs >= exc->maxIDefs )
4166 {
4167 exc->error = FT_THROW( Too_Many_Instruction_Defs );
4168 return;
4169 }
4170 exc->numIDefs++;
4171 }
4172
4173 /* opcode must be unsigned 8-bit integer */
4174 if ( 0 > args[0] || args[0] > 0x00FF )
4175 {
4176 exc->error = FT_THROW( Too_Many_Instruction_Defs );
6332 cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
6333
6334 /* single width test */
6335
6336 delta = SUB_LONG( cvt_dist, exc->GS.single_width_value );
6337 if ( delta < 0 )
6338 delta = NEG_LONG( delta );
6339
6340 if ( delta < exc->GS.single_width_cutin )
6341 {
6342 if ( cvt_dist >= 0 )
6343 cvt_dist = exc->GS.single_width_value;
6344 else
6345 cvt_dist = -exc->GS.single_width_value;
6346 }
6347
6348 /* UNDOCUMENTED! The MS rasterizer does that with */
6349 /* twilight points (confirmed by Greg Hitchcock) */
6350 if ( exc->GS.gep1 == 0 )
6351 {
6352 exc->zp1.org[point].x = ADD_LONG(
6353 exc->zp0.org[exc->GS.rp0].x,
6354 TT_MulFix14( cvt_dist,
6355 exc->GS.freeVector.x ) );
6356 exc->zp1.org[point].y = ADD_LONG(
6357 exc->zp0.org[exc->GS.rp0].y,
6358 TT_MulFix14( cvt_dist,
6359 exc->GS.freeVector.y ) );
6360 exc->zp1.cur[point] = exc->zp1.org[point];
6361 }
6362
6363 org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
6364 cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
6365
6366 /* auto-flip test */
6367
6368 if ( exc->GS.auto_flip )
6369 {
6370 if ( ( org_dist ^ cvt_dist ) < 0 )
6371 cvt_dist = NEG_LONG( cvt_dist );
6372 }
6373
6374 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
6375 if ( SUBPIXEL_HINTING_INFINALITY &&
6376 exc->ignore_x_mode &&
6377 exc->GS.freeVector.y != 0 &&
6378 ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
6379 {
7703 * GETDATA[]: no idea what this is good for
7704 * Opcode range: 0x92
7705 * Stack: --> 17
7706 *
7707 * XXX: UNDOCUMENTED! There is no documentation from Apple for this
7708 * very weird bytecode instruction.
7709 */
7710 static void
7711 Ins_GETDATA( FT_Long* args )
7712 {
7713 args[0] = 17;
7714 }
7715
7716 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
7717
7718
7719 static void
7720 Ins_UNKNOWN( TT_ExecContext exc )
7721 {
7722 TT_DefRecord* def = exc->IDefs;
7723 TT_DefRecord* limit = FT_OFFSET( def, exc->numIDefs );
7724
7725
7726 for ( ; def < limit; def++ )
7727 {
7728 if ( (FT_Byte)def->opc == exc->opcode && def->active )
7729 {
7730 TT_CallRec* call;
7731
7732
7733 if ( exc->callTop >= exc->callSize )
7734 {
7735 exc->error = FT_THROW( Stack_Overflow );
7736 return;
7737 }
7738
7739 call = exc->callStack + exc->callTop++;
7740
7741 call->Caller_Range = exc->curRange;
7742 call->Caller_IP = exc->IP + 1;
7743 call->Cur_Count = 1;
7855 /* Set up loop detectors. We restrict the number of LOOPCALL loops */
7856 /* and the number of JMPR, JROT, and JROF calls with a negative */
7857 /* argument to values that depend on various parameters like the */
7858 /* size of the CVT table or the number of points in the current */
7859 /* glyph (if applicable). */
7860 /* */
7861 /* The idea is that in real-world bytecode you either iterate over */
7862 /* all CVT entries (in the `prep' table), or over all points (or */
7863 /* contours, in the `glyf' table) of a glyph, and such iterations */
7864 /* don't happen very often. */
7865 exc->loopcall_counter = 0;
7866 exc->neg_jump_counter = 0;
7867
7868 /* The maximum values are heuristic. */
7869 if ( exc->pts.n_points )
7870 exc->loopcall_counter_max = FT_MAX( 50,
7871 10 * exc->pts.n_points ) +
7872 FT_MAX( 50,
7873 exc->cvtSize / 10 );
7874 else
7875 exc->loopcall_counter_max = 300 + 22 * exc->cvtSize;
7876
7877 /* as a protection against an unreasonable number of CVT entries */
7878 /* we assume at most 100 control values per glyph for the counter */
7879 if ( exc->loopcall_counter_max >
7880 100 * (FT_ULong)exc->face->root.num_glyphs )
7881 exc->loopcall_counter_max = 100 * (FT_ULong)exc->face->root.num_glyphs;
7882
7883 FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL"
7884 " to %d\n", exc->loopcall_counter_max ));
7885
7886 exc->neg_jump_counter_max = exc->loopcall_counter_max;
7887 FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps"
7888 " to %d\n", exc->neg_jump_counter_max ));
7889
7890 /* set PPEM and CVT functions */
7891 exc->tt_metrics.ratio = 0;
7892 if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
7893 {
7894 /* non-square pixels, use the stretched routines */
7895 exc->func_cur_ppem = Current_Ppem_Stretched;
8555 Ins_MIRP( exc, args );
8556 else if ( opcode >= 0xC0 )
8557 Ins_MDRP( exc, args );
8558 else if ( opcode >= 0xB8 )
8559 Ins_PUSHW( exc, args );
8560 else if ( opcode >= 0xB0 )
8561 Ins_PUSHB( exc, args );
8562 else
8563 Ins_UNKNOWN( exc );
8564 }
8565 }
8566
8567 if ( exc->error )
8568 {
8569 switch ( exc->error )
8570 {
8571 /* looking for redefined instructions */
8572 case FT_ERR( Invalid_Opcode ):
8573 {
8574 TT_DefRecord* def = exc->IDefs;
8575 TT_DefRecord* limit = FT_OFFSET( def, exc->numIDefs );
8576
8577
8578 for ( ; def < limit; def++ )
8579 {
8580 if ( def->active && exc->opcode == (FT_Byte)def->opc )
8581 {
8582 TT_CallRec* callrec;
8583
8584
8585 if ( exc->callTop >= exc->callSize )
8586 {
8587 exc->error = FT_THROW( Invalid_Reference );
8588 goto LErrorLabel_;
8589 }
8590
8591 callrec = &exc->callStack[exc->callTop];
8592
8593 callrec->Caller_Range = exc->curRange;
8594 callrec->Caller_IP = exc->IP + 1;
8595 callrec->Cur_Count = 1;
|