< prev index next >

src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c

Print this page


   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;


< prev index next >