1 /****************************************************************************
   2  *
   3  * cffparse.c
   4  *
   5  *   CFF token stream parser (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 #include <ft2build.h>
  20 #include "cffparse.h"
  21 #include FT_INTERNAL_STREAM_H
  22 #include FT_INTERNAL_DEBUG_H
  23 #include FT_INTERNAL_CALC_H
  24 #include FT_INTERNAL_POSTSCRIPT_AUX_H
  25 #include FT_LIST_H
  26 
  27 #include "cfferrs.h"
  28 #include "cffload.h"
  29 
  30 
  31   /**************************************************************************
  32    *
  33    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  34    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  35    * messages during execution.
  36    */
  37 #undef  FT_COMPONENT
  38 #define FT_COMPONENT  cffparse
  39 
  40 
  41   FT_LOCAL_DEF( FT_Error )
  42   cff_parser_init( CFF_Parser  parser,
  43                    FT_UInt     code,
  44                    void*       object,
  45                    FT_Library  library,
  46                    FT_UInt     stackSize,
  47                    FT_UShort   num_designs,
  48                    FT_UShort   num_axes )
  49   {
  50     FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
  51     FT_Error   error;                       /* for FT_NEW_ARRAY */
  52 
  53 
  54     FT_ZERO( parser );
  55 
  56 #if 0
  57     parser->top         = parser->stack;
  58 #endif
  59     parser->object_code = code;
  60     parser->object      = object;
  61     parser->library     = library;
  62     parser->num_designs = num_designs;
  63     parser->num_axes    = num_axes;
  64 
  65     /* allocate the stack buffer */
  66     if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
  67     {
  68       FT_FREE( parser->stack );
  69       goto Exit;
  70     }
  71 
  72     parser->stackSize = stackSize;
  73     parser->top       = parser->stack;    /* empty stack */
  74 
  75   Exit:
  76     return error;
  77   }
  78 
  79 
  80 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  81   static void
  82   finalize_t2_strings( FT_Memory  memory,
  83                        void*      data,
  84                        void*      user )
  85   {
  86     CFF_T2_String  t2 = (CFF_T2_String)data;
  87 
  88 
  89     FT_UNUSED( user );
  90 
  91     memory->free( memory, t2->start );
  92     memory->free( memory, data );
  93   }
  94 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
  95 
  96 
  97   FT_LOCAL_DEF( void )
  98   cff_parser_done( CFF_Parser  parser )
  99   {
 100     FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
 101 
 102 
 103     FT_FREE( parser->stack );
 104 
 105 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 106     FT_List_Finalize( &parser->t2_strings,
 107                       finalize_t2_strings,
 108                       memory,
 109                       NULL );
 110 #endif
 111   }
 112 
 113 
 114   /* Assuming `first >= last'. */
 115 
 116   static FT_Error
 117   cff_parser_within_limits( CFF_Parser  parser,
 118                             FT_Byte*    first,
 119                             FT_Byte*    last )
 120   {
 121 #ifndef CFF_CONFIG_OPTION_OLD_ENGINE
 122 
 123     /* Fast path for regular FreeType builds with the "new" engine; */
 124     /*   `first >= parser->start' can be assumed.                   */
 125 
 126     FT_UNUSED( first );
 127 
 128     return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
 129 
 130 #else /* CFF_CONFIG_OPTION_OLD_ENGINE */
 131 
 132     FT_ListNode  node;
 133 
 134 
 135     if ( first >= parser->start &&
 136          last  <  parser->limit )
 137       return FT_Err_Ok;
 138 
 139     node = parser->t2_strings.head;
 140 
 141     while ( node )
 142     {
 143       CFF_T2_String  t2 = (CFF_T2_String)node->data;
 144 
 145 
 146       if ( first >= t2->start &&
 147            last  <  t2->limit )
 148         return FT_Err_Ok;
 149 
 150       node = node->next;
 151     }
 152 
 153     return FT_THROW( Invalid_Argument );
 154 
 155 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
 156   }
 157 
 158 
 159   /* read an integer */
 160   static FT_Long
 161   cff_parse_integer( CFF_Parser  parser,
 162                      FT_Byte*    start )
 163   {
 164     FT_Byte*  p   = start;
 165     FT_Int    v   = *p++;
 166     FT_Long   val = 0;
 167 
 168 
 169     if ( v == 28 )
 170     {
 171       if ( cff_parser_within_limits( parser, p, p + 1 ) )
 172         goto Bad;
 173 
 174       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
 175     }
 176     else if ( v == 29 )
 177     {
 178       if ( cff_parser_within_limits( parser, p, p + 3 ) )
 179         goto Bad;
 180 
 181       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
 182                        ( (FT_ULong)p[1] << 16 ) |
 183                        ( (FT_ULong)p[2] <<  8 ) |
 184                          (FT_ULong)p[3]         );
 185     }
 186     else if ( v < 247 )
 187     {
 188       val = v - 139;
 189     }
 190     else if ( v < 251 )
 191     {
 192       if ( cff_parser_within_limits( parser, p, p ) )
 193         goto Bad;
 194 
 195       val = ( v - 247 ) * 256 + p[0] + 108;
 196     }
 197     else
 198     {
 199       if ( cff_parser_within_limits( parser, p, p ) )
 200         goto Bad;
 201 
 202       val = -( v - 251 ) * 256 - p[0] - 108;
 203     }
 204 
 205   Exit:
 206     return val;
 207 
 208   Bad:
 209     val = 0;
 210     FT_TRACE4(( "!!!END OF DATA:!!!" ));
 211     goto Exit;
 212   }
 213 
 214 
 215   static const FT_Long power_tens[] =
 216   {
 217     1L,
 218     10L,
 219     100L,
 220     1000L,
 221     10000L,
 222     100000L,
 223     1000000L,
 224     10000000L,
 225     100000000L,
 226     1000000000L
 227   };
 228 
 229   /* maximum values allowed for multiplying      */
 230   /* with the corresponding `power_tens' element */
 231   static const FT_Long power_ten_limits[] =
 232   {
 233     FT_LONG_MAX / 1L,
 234     FT_LONG_MAX / 10L,
 235     FT_LONG_MAX / 100L,
 236     FT_LONG_MAX / 1000L,
 237     FT_LONG_MAX / 10000L,
 238     FT_LONG_MAX / 100000L,
 239     FT_LONG_MAX / 1000000L,
 240     FT_LONG_MAX / 10000000L,
 241     FT_LONG_MAX / 100000000L,
 242     FT_LONG_MAX / 1000000000L,
 243   };
 244 
 245 
 246   /* read a real */
 247   static FT_Fixed
 248   cff_parse_real( CFF_Parser  parser,
 249                   FT_Byte*    start,
 250                   FT_Long     power_ten,
 251                   FT_Long*    scaling )
 252   {
 253     FT_Byte*  p = start;
 254     FT_Int    nib;
 255     FT_UInt   phase;
 256 
 257     FT_Long   result, number, exponent;
 258     FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
 259     FT_Long   exponent_add, integer_length, fraction_length;
 260 
 261 
 262     if ( scaling )
 263       *scaling = 0;
 264 
 265     result = 0;
 266 
 267     number   = 0;
 268     exponent = 0;
 269 
 270     exponent_add    = 0;
 271     integer_length  = 0;
 272     fraction_length = 0;
 273 
 274     /* First of all, read the integer part. */
 275     phase = 4;
 276 
 277     for (;;)
 278     {
 279       /* If we entered this iteration with phase == 4, we need to */
 280       /* read a new byte.  This also skips past the initial 0x1E. */
 281       if ( phase )
 282       {
 283         p++;
 284 
 285         /* Make sure we don't read past the end. */
 286         if ( cff_parser_within_limits( parser, p, p ) )
 287           goto Bad;
 288       }
 289 
 290       /* Get the nibble. */
 291       nib   = (FT_Int)( p[0] >> phase ) & 0xF;
 292       phase = 4 - phase;
 293 
 294       if ( nib == 0xE )
 295         sign = 1;
 296       else if ( nib > 9 )
 297         break;
 298       else
 299       {
 300         /* Increase exponent if we can't add the digit. */
 301         if ( number >= 0xCCCCCCCL )
 302           exponent_add++;
 303         /* Skip leading zeros. */
 304         else if ( nib || number )
 305         {
 306           integer_length++;
 307           number = number * 10 + nib;
 308         }
 309       }
 310     }
 311 
 312     /* Read fraction part, if any. */
 313     if ( nib == 0xA )
 314       for (;;)
 315       {
 316         /* If we entered this iteration with phase == 4, we need */
 317         /* to read a new byte.                                   */
 318         if ( phase )
 319         {
 320           p++;
 321 
 322           /* Make sure we don't read past the end. */
 323           if ( cff_parser_within_limits( parser, p, p ) )
 324             goto Bad;
 325         }
 326 
 327         /* Get the nibble. */
 328         nib   = ( p[0] >> phase ) & 0xF;
 329         phase = 4 - phase;
 330         if ( nib >= 10 )
 331           break;
 332 
 333         /* Skip leading zeros if possible. */
 334         if ( !nib && !number )
 335           exponent_add--;
 336         /* Only add digit if we don't overflow. */
 337         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
 338         {
 339           fraction_length++;
 340           number = number * 10 + nib;
 341         }
 342       }
 343 
 344     /* Read exponent, if any. */
 345     if ( nib == 12 )
 346     {
 347       exponent_sign = 1;
 348       nib           = 11;
 349     }
 350 
 351     if ( nib == 11 )
 352     {
 353       for (;;)
 354       {
 355         /* If we entered this iteration with phase == 4, */
 356         /* we need to read a new byte.                   */
 357         if ( phase )
 358         {
 359           p++;
 360 
 361           /* Make sure we don't read past the end. */
 362           if ( cff_parser_within_limits( parser, p, p ) )
 363             goto Bad;
 364         }
 365 
 366         /* Get the nibble. */
 367         nib   = ( p[0] >> phase ) & 0xF;
 368         phase = 4 - phase;
 369         if ( nib >= 10 )
 370           break;
 371 
 372         /* Arbitrarily limit exponent. */
 373         if ( exponent > 1000 )
 374           have_overflow = 1;
 375         else
 376           exponent = exponent * 10 + nib;
 377       }
 378 
 379       if ( exponent_sign )
 380         exponent = -exponent;
 381     }
 382 
 383     if ( !number )
 384       goto Exit;
 385 
 386     if ( have_overflow )
 387     {
 388       if ( exponent_sign )
 389         goto Underflow;
 390       else
 391         goto Overflow;
 392     }
 393 
 394     /* We don't check `power_ten' and `exponent_add'. */
 395     exponent += power_ten + exponent_add;
 396 
 397     if ( scaling )
 398     {
 399       /* Only use `fraction_length'. */
 400       fraction_length += integer_length;
 401       exponent        += integer_length;
 402 
 403       if ( fraction_length <= 5 )
 404       {
 405         if ( number > 0x7FFFL )
 406         {
 407           result   = FT_DivFix( number, 10 );
 408           *scaling = exponent - fraction_length + 1;
 409         }
 410         else
 411         {
 412           if ( exponent > 0 )
 413           {
 414             FT_Long  new_fraction_length, shift;
 415 
 416 
 417             /* Make `scaling' as small as possible. */
 418             new_fraction_length = FT_MIN( exponent, 5 );
 419             shift               = new_fraction_length - fraction_length;
 420 
 421             if ( shift > 0 )
 422             {
 423               exponent -= new_fraction_length;
 424               number   *= power_tens[shift];
 425               if ( number > 0x7FFFL )
 426               {
 427                 number   /= 10;
 428                 exponent += 1;
 429               }
 430             }
 431             else
 432               exponent -= fraction_length;
 433           }
 434           else
 435             exponent -= fraction_length;
 436 
 437           result   = (FT_Long)( (FT_ULong)number << 16 );
 438           *scaling = exponent;
 439         }
 440       }
 441       else
 442       {
 443         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
 444         {
 445           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
 446           *scaling = exponent - 4;
 447         }
 448         else
 449         {
 450           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
 451           *scaling = exponent - 5;
 452         }
 453       }
 454     }
 455     else
 456     {
 457       integer_length  += exponent;
 458       fraction_length -= exponent;
 459 
 460       if ( integer_length > 5 )
 461         goto Overflow;
 462       if ( integer_length < -5 )
 463         goto Underflow;
 464 
 465       /* Remove non-significant digits. */
 466       if ( integer_length < 0 )
 467       {
 468         number          /= power_tens[-integer_length];
 469         fraction_length += integer_length;
 470       }
 471 
 472       /* this can only happen if exponent was non-zero */
 473       if ( fraction_length == 10 )
 474       {
 475         number          /= 10;
 476         fraction_length -= 1;
 477       }
 478 
 479       /* Convert into 16.16 format. */
 480       if ( fraction_length > 0 )
 481       {
 482         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
 483           goto Exit;
 484 
 485         result = FT_DivFix( number, power_tens[fraction_length] );
 486       }
 487       else
 488       {
 489         number *= power_tens[-fraction_length];
 490 
 491         if ( number > 0x7FFFL )
 492           goto Overflow;
 493 
 494         result = (FT_Long)( (FT_ULong)number << 16 );
 495       }
 496     }
 497 
 498   Exit:
 499     if ( sign )
 500       result = -result;
 501 
 502     return result;
 503 
 504   Overflow:
 505     result = 0x7FFFFFFFL;
 506     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
 507     goto Exit;
 508 
 509   Underflow:
 510     result = 0;
 511     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
 512     goto Exit;
 513 
 514   Bad:
 515     result = 0;
 516     FT_TRACE4(( "!!!END OF DATA:!!!" ));
 517     goto Exit;
 518   }
 519 
 520 
 521   /* read a number, either integer or real */
 522   FT_LOCAL_DEF( FT_Long )
 523   cff_parse_num( CFF_Parser  parser,
 524                  FT_Byte**   d )
 525   {
 526     if ( **d == 30 )
 527     {
 528       /* binary-coded decimal is truncated to integer */
 529       return cff_parse_real( parser, *d, 0, NULL ) >> 16;
 530     }
 531 
 532     else if ( **d == 255 )
 533     {
 534       /* 16.16 fixed point is used internally for CFF2 blend results. */
 535       /* Since these are trusted values, a limit check is not needed. */
 536 
 537       /* After the 255, 4 bytes give the number.                 */
 538       /* The blend value is converted to integer, with rounding; */
 539       /* due to the right-shift we don't need the lowest byte.   */
 540 #if 0
 541       return (FT_Short)(
 542                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
 543                    ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
 544                    ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
 545                      (FT_UInt32)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
 546 #else
 547       return (FT_Short)(
 548                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
 549                    ( (FT_UInt32)*( d[0] + 2 ) <<  8 ) |
 550                      (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
 551 #endif
 552     }
 553 
 554     else
 555       return cff_parse_integer( parser, *d );
 556   }
 557 
 558 
 559   /* read a floating point number, either integer or real */
 560   static FT_Fixed
 561   do_fixed( CFF_Parser  parser,
 562             FT_Byte**   d,
 563             FT_Long     scaling )
 564   {
 565     if ( **d == 30 )
 566       return cff_parse_real( parser, *d, scaling, NULL );
 567     else
 568     {
 569       FT_Long  val = cff_parse_integer( parser, *d );
 570 
 571 
 572       if ( scaling )
 573       {
 574         if ( FT_ABS( val ) > power_ten_limits[scaling] )
 575         {
 576           val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
 577           goto Overflow;
 578         }
 579 
 580         val *= power_tens[scaling];
 581       }
 582 
 583       if ( val > 0x7FFF )
 584       {
 585         val = 0x7FFFFFFFL;
 586         goto Overflow;
 587       }
 588       else if ( val < -0x7FFF )
 589       {
 590         val = -0x7FFFFFFFL;
 591         goto Overflow;
 592       }
 593 
 594       return (FT_Long)( (FT_ULong)val << 16 );
 595 
 596     Overflow:
 597       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
 598       return val;
 599     }
 600   }
 601 
 602 
 603   /* read a floating point number, either integer or real */
 604   static FT_Fixed
 605   cff_parse_fixed( CFF_Parser  parser,
 606                    FT_Byte**   d )
 607   {
 608     return do_fixed( parser, d, 0 );
 609   }
 610 
 611 
 612   /* read a floating point number, either integer or real, */
 613   /* but return `10^scaling' times the number read in      */
 614   static FT_Fixed
 615   cff_parse_fixed_scaled( CFF_Parser  parser,
 616                           FT_Byte**   d,
 617                           FT_Long     scaling )
 618   {
 619     return do_fixed( parser, d, scaling );
 620   }
 621 
 622 
 623   /* read a floating point number, either integer or real,     */
 624   /* and return it as precise as possible -- `scaling' returns */
 625   /* the scaling factor (as a power of 10)                     */
 626   static FT_Fixed
 627   cff_parse_fixed_dynamic( CFF_Parser  parser,
 628                            FT_Byte**   d,
 629                            FT_Long*    scaling )
 630   {
 631     FT_ASSERT( scaling );
 632 
 633     if ( **d == 30 )
 634       return cff_parse_real( parser, *d, 0, scaling );
 635     else
 636     {
 637       FT_Long  number;
 638       FT_Int   integer_length;
 639 
 640 
 641       number = cff_parse_integer( parser, d[0] );
 642 
 643       if ( number > 0x7FFFL )
 644       {
 645         for ( integer_length = 5; integer_length < 10; integer_length++ )
 646           if ( number < power_tens[integer_length] )
 647             break;
 648 
 649         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
 650         {
 651           *scaling = integer_length - 4;
 652           return FT_DivFix( number, power_tens[integer_length - 4] );
 653         }
 654         else
 655         {
 656           *scaling = integer_length - 5;
 657           return FT_DivFix( number, power_tens[integer_length - 5] );
 658         }
 659       }
 660       else
 661       {
 662         *scaling = 0;
 663         return (FT_Long)( (FT_ULong)number << 16 );
 664       }
 665     }
 666   }
 667 
 668 
 669   static FT_Error
 670   cff_parse_font_matrix( CFF_Parser  parser )
 671   {
 672     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
 673     FT_Matrix*       matrix = &dict->font_matrix;
 674     FT_Vector*       offset = &dict->font_offset;
 675     FT_ULong*        upm    = &dict->units_per_em;
 676     FT_Byte**        data   = parser->stack;
 677 
 678 
 679     if ( parser->top >= parser->stack + 6 )
 680     {
 681       FT_Fixed  values[6];
 682       FT_Long   scalings[6];
 683 
 684       FT_Long  min_scaling, max_scaling;
 685       int      i;
 686 
 687 
 688       dict->has_font_matrix = TRUE;
 689 
 690       /* We expect a well-formed font matrix, this is, the matrix elements */
 691       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
 692       /* loss of precision, we use the magnitude of the largest matrix     */
 693       /* element to scale all other elements.  The scaling factor is then  */
 694       /* contained in the `units_per_em' value.                            */
 695 
 696       max_scaling = FT_LONG_MIN;
 697       min_scaling = FT_LONG_MAX;
 698 
 699       for ( i = 0; i < 6; i++ )
 700       {
 701         values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
 702         if ( values[i] )
 703         {
 704           if ( scalings[i] > max_scaling )
 705             max_scaling = scalings[i];
 706           if ( scalings[i] < min_scaling )
 707             min_scaling = scalings[i];
 708         }
 709       }
 710 
 711       if ( max_scaling < -9                  ||
 712            max_scaling > 0                   ||
 713            ( max_scaling - min_scaling ) < 0 ||
 714            ( max_scaling - min_scaling ) > 9 )
 715       {
 716         FT_TRACE1(( "cff_parse_font_matrix:"
 717                     " strange scaling values (minimum %d, maximum %d),\n"
 718                     "                      "
 719                     " using default matrix\n", min_scaling, max_scaling ));
 720         goto Unlikely;
 721       }
 722 
 723       for ( i = 0; i < 6; i++ )
 724       {
 725         FT_Fixed  value = values[i];
 726         FT_Long   divisor, half_divisor;
 727 
 728 
 729         if ( !value )
 730           continue;
 731 
 732         divisor      = power_tens[max_scaling - scalings[i]];
 733         half_divisor = divisor >> 1;
 734 
 735         if ( value < 0 )
 736         {
 737           if ( FT_LONG_MIN + half_divisor < value )
 738             values[i] = ( value - half_divisor ) / divisor;
 739           else
 740             values[i] = FT_LONG_MIN / divisor;
 741         }
 742         else
 743         {
 744           if ( FT_LONG_MAX - half_divisor > value )
 745             values[i] = ( value + half_divisor ) / divisor;
 746           else
 747             values[i] = FT_LONG_MAX / divisor;
 748         }
 749       }
 750 
 751       matrix->xx = values[0];
 752       matrix->yx = values[1];
 753       matrix->xy = values[2];
 754       matrix->yy = values[3];
 755       offset->x  = values[4];
 756       offset->y  = values[5];
 757 
 758       *upm = (FT_ULong)power_tens[-max_scaling];
 759 
 760       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
 761                   (double)matrix->xx / *upm / 65536,
 762                   (double)matrix->xy / *upm / 65536,
 763                   (double)matrix->yx / *upm / 65536,
 764                   (double)matrix->yy / *upm / 65536,
 765                   (double)offset->x  / *upm / 65536,
 766                   (double)offset->y  / *upm / 65536 ));
 767 
 768       if ( !FT_Matrix_Check( matrix ) )
 769       {
 770         FT_TRACE1(( "cff_parse_font_matrix:"
 771                     " degenerate values, using default matrix\n" ));
 772         goto Unlikely;
 773       }
 774 
 775       return FT_Err_Ok;
 776     }
 777     else
 778       return FT_THROW( Stack_Underflow );
 779 
 780   Unlikely:
 781     /* Return default matrix in case of unlikely values. */
 782 
 783     matrix->xx = 0x10000L;
 784     matrix->yx = 0;
 785     matrix->xy = 0;
 786     matrix->yy = 0x10000L;
 787     offset->x  = 0;
 788     offset->y  = 0;
 789     *upm       = 1;
 790 
 791     return FT_Err_Ok;
 792   }
 793 
 794 
 795   static FT_Error
 796   cff_parse_font_bbox( CFF_Parser  parser )
 797   {
 798     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 799     FT_BBox*         bbox = &dict->font_bbox;
 800     FT_Byte**        data = parser->stack;
 801     FT_Error         error;
 802 
 803 
 804     error = FT_ERR( Stack_Underflow );
 805 
 806     if ( parser->top >= parser->stack + 4 )
 807     {
 808       bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
 809       bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
 810       bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
 811       bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
 812       error = FT_Err_Ok;
 813 
 814       FT_TRACE4(( " [%d %d %d %d]\n",
 815                   bbox->xMin / 65536,
 816                   bbox->yMin / 65536,
 817                   bbox->xMax / 65536,
 818                   bbox->yMax / 65536 ));
 819     }
 820 
 821     return error;
 822   }
 823 
 824 
 825   static FT_Error
 826   cff_parse_private_dict( CFF_Parser  parser )
 827   {
 828     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 829     FT_Byte**        data = parser->stack;
 830     FT_Error         error;
 831 
 832 
 833     error = FT_ERR( Stack_Underflow );
 834 
 835     if ( parser->top >= parser->stack + 2 )
 836     {
 837       FT_Long  tmp;
 838 
 839 
 840       tmp = cff_parse_num( parser, data++ );
 841       if ( tmp < 0 )
 842       {
 843         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
 844         error = FT_THROW( Invalid_File_Format );
 845         goto Fail;
 846       }
 847       dict->private_size = (FT_ULong)tmp;
 848 
 849       tmp = cff_parse_num( parser, data );
 850       if ( tmp < 0 )
 851       {
 852         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
 853         error = FT_THROW( Invalid_File_Format );
 854         goto Fail;
 855       }
 856       dict->private_offset = (FT_ULong)tmp;
 857 
 858       FT_TRACE4(( " %lu %lu\n",
 859                   dict->private_size, dict->private_offset ));
 860 
 861       error = FT_Err_Ok;
 862     }
 863 
 864   Fail:
 865     return error;
 866   }
 867 
 868 
 869   /* The `MultipleMaster' operator comes before any  */
 870   /* top DICT operators that contain T2 charstrings. */
 871 
 872   static FT_Error
 873   cff_parse_multiple_master( CFF_Parser  parser )
 874   {
 875     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 876     FT_Error         error;
 877 
 878 
 879 #ifdef FT_DEBUG_LEVEL_TRACE
 880     /* beautify tracing message */
 881     if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 )
 882       FT_TRACE1(( "Multiple Master CFFs not supported yet,"
 883                   " handling first master design only\n" ));
 884     else
 885       FT_TRACE1(( " (not supported yet,"
 886                   " handling first master design only)\n" ));
 887 #endif
 888 
 889     error = FT_ERR( Stack_Underflow );
 890 
 891     /* currently, we handle only the first argument */
 892     if ( parser->top >= parser->stack + 5 )
 893     {
 894       FT_Long  num_designs = cff_parse_num( parser, parser->stack );
 895 
 896 
 897       if ( num_designs > 16 || num_designs < 2 )
 898       {
 899         FT_ERROR(( "cff_parse_multiple_master:"
 900                    " Invalid number of designs\n" ));
 901         error = FT_THROW( Invalid_File_Format );
 902       }
 903       else
 904       {
 905         dict->num_designs   = (FT_UShort)num_designs;
 906         dict->num_axes      = (FT_UShort)( parser->top - parser->stack - 4 );
 907 
 908         parser->num_designs = dict->num_designs;
 909         parser->num_axes    = dict->num_axes;
 910 
 911         error = FT_Err_Ok;
 912       }
 913     }
 914 
 915     return error;
 916   }
 917 
 918 
 919   static FT_Error
 920   cff_parse_cid_ros( CFF_Parser  parser )
 921   {
 922     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 923     FT_Byte**        data = parser->stack;
 924     FT_Error         error;
 925 
 926 
 927     error = FT_ERR( Stack_Underflow );
 928 
 929     if ( parser->top >= parser->stack + 3 )
 930     {
 931       dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
 932       dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
 933       if ( **data == 30 )
 934         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
 935       dict->cid_supplement = cff_parse_num( parser, data );
 936       if ( dict->cid_supplement < 0 )
 937         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
 938                    dict->cid_supplement ));
 939       error = FT_Err_Ok;
 940 
 941       FT_TRACE4(( " %d %d %d\n",
 942                   dict->cid_registry,
 943                   dict->cid_ordering,
 944                   dict->cid_supplement ));
 945     }
 946 
 947     return error;
 948   }
 949 
 950 
 951   static FT_Error
 952   cff_parse_vsindex( CFF_Parser  parser )
 953   {
 954     /* vsindex operator can only be used in a Private DICT */
 955     CFF_Private  priv = (CFF_Private)parser->object;
 956     FT_Byte**    data = parser->stack;
 957     CFF_Blend    blend;
 958     FT_Error     error;
 959 
 960 
 961     if ( !priv || !priv->subfont )
 962     {
 963       error = FT_THROW( Invalid_File_Format );
 964       goto Exit;
 965     }
 966 
 967     blend = &priv->subfont->blend;
 968 
 969     if ( blend->usedBV )
 970     {
 971       FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
 972       error = FT_THROW( Syntax_Error );
 973       goto Exit;
 974     }
 975 
 976     priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
 977 
 978     FT_TRACE4(( " %d\n", priv->vsindex ));
 979 
 980     error = FT_Err_Ok;
 981 
 982   Exit:
 983     return error;
 984   }
 985 
 986 
 987   static FT_Error
 988   cff_parse_blend( CFF_Parser  parser )
 989   {
 990     /* blend operator can only be used in a Private DICT */
 991     CFF_Private  priv = (CFF_Private)parser->object;
 992     CFF_SubFont  subFont;
 993     CFF_Blend    blend;
 994     FT_UInt      numBlends;
 995     FT_Error     error;
 996 
 997 
 998     if ( !priv || !priv->subfont )
 999     {
1000       error = FT_THROW( Invalid_File_Format );
1001       goto Exit;
1002     }
1003 
1004     subFont = priv->subfont;
1005     blend   = &subFont->blend;
1006 
1007     if ( cff_blend_check_vector( blend,
1008                                  priv->vsindex,
1009                                  subFont->lenNDV,
1010                                  subFont->NDV ) )
1011     {
1012       error = cff_blend_build_vector( blend,
1013                                       priv->vsindex,
1014                                       subFont->lenNDV,
1015                                       subFont->NDV );
1016       if ( error )
1017         goto Exit;
1018     }
1019 
1020     numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
1021     if ( numBlends > parser->stackSize )
1022     {
1023       FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
1024       error = FT_THROW( Invalid_File_Format );
1025       goto Exit;
1026     }
1027 
1028     FT_TRACE4(( "   %d value%s blended\n",
1029                 numBlends,
1030                 numBlends == 1 ? "" : "s" ));
1031 
1032     error = cff_blend_doBlend( subFont, parser, numBlends );
1033 
1034     blend->usedBV = TRUE;
1035 
1036   Exit:
1037     return error;
1038   }
1039 
1040 
1041   /* maxstack operator increases parser and operand stacks for CFF2 */
1042   static FT_Error
1043   cff_parse_maxstack( CFF_Parser  parser )
1044   {
1045     /* maxstack operator can only be used in a Top DICT */
1046     CFF_FontRecDict  dict  = (CFF_FontRecDict)parser->object;
1047     FT_Byte**        data  = parser->stack;
1048     FT_Error         error = FT_Err_Ok;
1049 
1050 
1051     if ( !dict )
1052     {
1053       error = FT_THROW( Invalid_File_Format );
1054       goto Exit;
1055     }
1056 
1057     dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
1058     if ( dict->maxstack > CFF2_MAX_STACK )
1059       dict->maxstack = CFF2_MAX_STACK;
1060     if ( dict->maxstack < CFF2_DEFAULT_STACK )
1061       dict->maxstack = CFF2_DEFAULT_STACK;
1062 
1063     FT_TRACE4(( " %d\n", dict->maxstack ));
1064 
1065   Exit:
1066     return error;
1067   }
1068 
1069 
1070 #define CFF_FIELD_NUM( code, name, id )             \
1071           CFF_FIELD( code, name, id, cff_kind_num )
1072 #define CFF_FIELD_FIXED( code, name, id )             \
1073           CFF_FIELD( code, name, id, cff_kind_fixed )
1074 #define CFF_FIELD_FIXED_1000( code, name, id )                 \
1075           CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
1076 #define CFF_FIELD_STRING( code, name, id )             \
1077           CFF_FIELD( code, name, id, cff_kind_string )
1078 #define CFF_FIELD_BOOL( code, name, id )             \
1079           CFF_FIELD( code, name, id, cff_kind_bool )
1080 
1081 
1082 #undef  CFF_FIELD
1083 #undef  CFF_FIELD_DELTA
1084 
1085 
1086 #ifndef FT_DEBUG_LEVEL_TRACE
1087 
1088 
1089 #define CFF_FIELD_CALLBACK( code, name, id ) \
1090           {                                  \
1091             cff_kind_callback,               \
1092             code | CFFCODE,                  \
1093             0, 0,                            \
1094             cff_parse_ ## name,              \
1095             0, 0                             \
1096           },
1097 
1098 #define CFF_FIELD_BLEND( code, id ) \
1099           {                         \
1100             cff_kind_blend,         \
1101             code | CFFCODE,         \
1102             0, 0,                   \
1103             cff_parse_blend,        \
1104             0, 0                    \
1105           },
1106 
1107 #define CFF_FIELD( code, name, id, kind ) \
1108           {                               \
1109             kind,                         \
1110             code | CFFCODE,               \
1111             FT_FIELD_OFFSET( name ),      \
1112             FT_FIELD_SIZE( name ),        \
1113             0, 0, 0                       \
1114           },
1115 
1116 #define CFF_FIELD_DELTA( code, name, max, id ) \
1117           {                                    \
1118             cff_kind_delta,                    \
1119             code | CFFCODE,                    \
1120             FT_FIELD_OFFSET( name ),           \
1121             FT_FIELD_SIZE_DELTA( name ),       \
1122             0,                                 \
1123             max,                               \
1124             FT_FIELD_OFFSET( num_ ## name )    \
1125           },
1126 
1127   static const CFF_Field_Handler  cff_field_handlers[] =
1128   {
1129 
1130 #include "cfftoken.h"
1131 
1132     { 0, 0, 0, 0, 0, 0, 0 }
1133   };
1134 
1135 
1136 #else /* FT_DEBUG_LEVEL_TRACE */
1137 
1138 
1139 
1140 #define CFF_FIELD_CALLBACK( code, name, id ) \
1141           {                                  \
1142             cff_kind_callback,               \
1143             code | CFFCODE,                  \
1144             0, 0,                            \
1145             cff_parse_ ## name,              \
1146             0, 0,                            \
1147             id                               \
1148           },
1149 
1150 #define CFF_FIELD_BLEND( code, id ) \
1151           {                         \
1152             cff_kind_blend,         \
1153             code | CFFCODE,         \
1154             0, 0,                   \
1155             cff_parse_blend,        \
1156             0, 0,                   \
1157             id                      \
1158           },
1159 
1160 #define CFF_FIELD( code, name, id, kind ) \
1161           {                               \
1162             kind,                         \
1163             code | CFFCODE,               \
1164             FT_FIELD_OFFSET( name ),      \
1165             FT_FIELD_SIZE( name ),        \
1166             0, 0, 0,                      \
1167             id                            \
1168           },
1169 
1170 #define CFF_FIELD_DELTA( code, name, max, id ) \
1171           {                                    \
1172             cff_kind_delta,                    \
1173             code | CFFCODE,                    \
1174             FT_FIELD_OFFSET( name ),           \
1175             FT_FIELD_SIZE_DELTA( name ),       \
1176             0,                                 \
1177             max,                               \
1178             FT_FIELD_OFFSET( num_ ## name ),   \
1179             id                                 \
1180           },
1181 
1182   static const CFF_Field_Handler  cff_field_handlers[] =
1183   {
1184 
1185 #include "cfftoken.h"
1186 
1187     { 0, 0, 0, 0, 0, 0, 0, 0 }
1188   };
1189 
1190 
1191 #endif /* FT_DEBUG_LEVEL_TRACE */
1192 
1193 
1194   FT_LOCAL_DEF( FT_Error )
1195   cff_parser_run( CFF_Parser  parser,
1196                   FT_Byte*    start,
1197                   FT_Byte*    limit )
1198   {
1199     FT_Byte*  p     = start;
1200     FT_Error  error = FT_Err_Ok;
1201 
1202 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1203     PSAux_Service  psaux;
1204 
1205     FT_Library  library = parser->library;
1206     FT_Memory   memory  = library->memory;
1207 #endif
1208 
1209     parser->top    = parser->stack;
1210     parser->start  = start;
1211     parser->limit  = limit;
1212     parser->cursor = start;
1213 
1214     while ( p < limit )
1215     {
1216       FT_UInt  v = *p;
1217 
1218 
1219       /* Opcode 31 is legacy MM T2 operator, not a number.      */
1220       /* Opcode 255 is reserved and should not appear in fonts; */
1221       /* it is used internally for CFF2 blends.                 */
1222       if ( v >= 27 && v != 31 && v != 255 )
1223       {
1224         /* it's a number; we will push its position on the stack */
1225         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1226           goto Stack_Overflow;
1227 
1228         *parser->top++ = p;
1229 
1230         /* now, skip it */
1231         if ( v == 30 )
1232         {
1233           /* skip real number */
1234           p++;
1235           for (;;)
1236           {
1237             /* An unterminated floating point number at the */
1238             /* end of a dictionary is invalid but harmless. */
1239             if ( p >= limit )
1240               goto Exit;
1241             v = p[0] >> 4;
1242             if ( v == 15 )
1243               break;
1244             v = p[0] & 0xF;
1245             if ( v == 15 )
1246               break;
1247             p++;
1248           }
1249         }
1250         else if ( v == 28 )
1251           p += 2;
1252         else if ( v == 29 )
1253           p += 4;
1254         else if ( v > 246 )
1255           p += 1;
1256       }
1257 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1258       else if ( v == 31 )
1259       {
1260         /* a Type 2 charstring */
1261 
1262         CFF_Decoder  decoder;
1263         CFF_FontRec  cff_rec;
1264         FT_Byte*     charstring_base;
1265         FT_ULong     charstring_len;
1266 
1267         FT_Fixed*     stack;
1268         FT_ListNode   node;
1269         CFF_T2_String t2;
1270         size_t        t2_size;
1271         FT_Byte*      q;
1272 
1273 
1274         charstring_base = ++p;
1275 
1276         /* search `endchar' operator */
1277         for (;;)
1278         {
1279           if ( p >= limit )
1280             goto Exit;
1281           if ( *p == 14 )
1282             break;
1283           p++;
1284         }
1285 
1286         charstring_len = (FT_ULong)( p - charstring_base ) + 1;
1287 
1288         /* construct CFF_Decoder object */
1289         FT_ZERO( &decoder );
1290         FT_ZERO( &cff_rec );
1291 
1292         cff_rec.top_font.font_dict.num_designs = parser->num_designs;
1293         cff_rec.top_font.font_dict.num_axes    = parser->num_axes;
1294         decoder.cff                            = &cff_rec;
1295 
1296         psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" );
1297         if ( !psaux )
1298         {
1299           FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" ));
1300           error = FT_THROW( Missing_Module );
1301           goto Exit;
1302         }
1303 
1304         error = psaux->cff_decoder_funcs->parse_charstrings_old(
1305                   &decoder, charstring_base, charstring_len, 1 );
1306         if ( error )
1307           goto Exit;
1308 
1309         /* Now copy the stack data in the temporary decoder object,    */
1310         /* converting it back to charstring number representations     */
1311         /* (this is ugly, I know).                                     */
1312 
1313         node = (FT_ListNode)memory->alloc( memory,
1314                                            sizeof ( FT_ListNodeRec ) );
1315         if ( !node )
1316           goto Out_Of_Memory_Error;
1317 
1318         FT_List_Add( &parser->t2_strings, node );
1319 
1320         t2 = (CFF_T2_String)memory->alloc( memory,
1321                                            sizeof ( CFF_T2_StringRec ) );
1322         if ( !t2 )
1323           goto Out_Of_Memory_Error;
1324 
1325         node->data = t2;
1326 
1327         /* `5' is the conservative upper bound of required bytes per stack */
1328         /* element.                                                        */
1329 
1330         t2_size = 5 * ( decoder.top - decoder.stack );
1331 
1332         q = (FT_Byte*)memory->alloc( memory, t2_size );
1333         if ( !q )
1334           goto Out_Of_Memory_Error;
1335 
1336         t2->start = q;
1337         t2->limit = q + t2_size;
1338 
1339         stack = decoder.stack;
1340 
1341         while ( stack < decoder.top )
1342         {
1343           FT_ULong  num;
1344           FT_Bool   neg;
1345 
1346 
1347           if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1348             goto Stack_Overflow;
1349 
1350           *parser->top++ = q;
1351 
1352           if ( *stack < 0 )
1353           {
1354             num = (FT_ULong)NEG_LONG( *stack );
1355             neg = 1;
1356           }
1357           else
1358           {
1359             num = (FT_ULong)*stack;
1360             neg = 0;
1361           }
1362 
1363           if ( num & 0xFFFFU )
1364           {
1365             if ( neg )
1366               num = (FT_ULong)-num;
1367 
1368             *q++ = 255;
1369             *q++ = ( num & 0xFF000000U ) >> 24;
1370             *q++ = ( num & 0x00FF0000U ) >> 16;
1371             *q++ = ( num & 0x0000FF00U ) >>  8;
1372             *q++ =   num & 0x000000FFU;
1373           }
1374           else
1375           {
1376             num >>= 16;
1377 
1378             if ( neg )
1379             {
1380               if ( num <= 107 )
1381                 *q++ = (FT_Byte)( 139 - num );
1382               else if ( num <= 1131 )
1383               {
1384                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
1385                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1386               }
1387               else
1388               {
1389                 num = (FT_ULong)-num;
1390 
1391                 *q++ = 28;
1392                 *q++ = (FT_Byte)( num >> 8 );
1393                 *q++ = (FT_Byte)( num & 0xFF );
1394               }
1395             }
1396             else
1397             {
1398               if ( num <= 107 )
1399                 *q++ = (FT_Byte)( num + 139 );
1400               else if ( num <= 1131 )
1401               {
1402                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
1403                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1404               }
1405               else
1406               {
1407                 *q++ = 28;
1408                 *q++ = (FT_Byte)( num >> 8 );
1409                 *q++ = (FT_Byte)( num & 0xFF );
1410               }
1411             }
1412           }
1413 
1414           stack++;
1415         }
1416       }
1417 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
1418       else
1419       {
1420         /* This is not a number, hence it's an operator.  Compute its code */
1421         /* and look for it in our current list.                            */
1422 
1423         FT_UInt                   code;
1424         FT_UInt                   num_args;
1425         const CFF_Field_Handler*  field;
1426 
1427 
1428         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1429           goto Stack_Overflow;
1430 
1431         num_args     = (FT_UInt)( parser->top - parser->stack );
1432         *parser->top = p;
1433         code         = v;
1434 
1435         if ( v == 12 )
1436         {
1437           /* two byte operator */
1438           p++;
1439           if ( p >= limit )
1440             goto Syntax_Error;
1441 
1442           code = 0x100 | p[0];
1443         }
1444         code = code | parser->object_code;
1445 
1446         for ( field = cff_field_handlers; field->kind; field++ )
1447         {
1448           if ( field->code == (FT_Int)code )
1449           {
1450             /* we found our field's handler; read it */
1451             FT_Long   val;
1452             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
1453 
1454 
1455 #ifdef FT_DEBUG_LEVEL_TRACE
1456             FT_TRACE4(( "  %s", field->id ));
1457 #endif
1458 
1459             /* check that we have enough arguments -- except for */
1460             /* delta encoded arrays, which can be empty          */
1461             if ( field->kind != cff_kind_delta && num_args < 1 )
1462               goto Stack_Underflow;
1463 
1464             switch ( field->kind )
1465             {
1466             case cff_kind_bool:
1467             case cff_kind_string:
1468             case cff_kind_num:
1469               val = cff_parse_num( parser, parser->stack );
1470               goto Store_Number;
1471 
1472             case cff_kind_fixed:
1473               val = cff_parse_fixed( parser, parser->stack );
1474               goto Store_Number;
1475 
1476             case cff_kind_fixed_thousand:
1477               val = cff_parse_fixed_scaled( parser, parser->stack, 3 );
1478 
1479             Store_Number:
1480               switch ( field->size )
1481               {
1482               case (8 / FT_CHAR_BIT):
1483                 *(FT_Byte*)q = (FT_Byte)val;
1484                 break;
1485 
1486               case (16 / FT_CHAR_BIT):
1487                 *(FT_Short*)q = (FT_Short)val;
1488                 break;
1489 
1490               case (32 / FT_CHAR_BIT):
1491                 *(FT_Int32*)q = (FT_Int)val;
1492                 break;
1493 
1494               default:  /* for 64-bit systems */
1495                 *(FT_Long*)q = val;
1496               }
1497 
1498 #ifdef FT_DEBUG_LEVEL_TRACE
1499               switch ( field->kind )
1500               {
1501               case cff_kind_bool:
1502                 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1503                 break;
1504 
1505               case cff_kind_string:
1506                 FT_TRACE4(( " %ld (SID)\n", val ));
1507                 break;
1508 
1509               case cff_kind_num:
1510                 FT_TRACE4(( " %ld\n", val ));
1511                 break;
1512 
1513               case cff_kind_fixed:
1514                 FT_TRACE4(( " %f\n", (double)val / 65536 ));
1515                 break;
1516 
1517               case cff_kind_fixed_thousand:
1518                 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1519 
1520               default:
1521                 ; /* never reached */
1522               }
1523 #endif
1524 
1525               break;
1526 
1527             case cff_kind_delta:
1528               {
1529                 FT_Byte*   qcount = (FT_Byte*)parser->object +
1530                                       field->count_offset;
1531 
1532                 FT_Byte**  data = parser->stack;
1533 
1534 
1535                 if ( num_args > field->array_max )
1536                   num_args = field->array_max;
1537 
1538                 FT_TRACE4(( " [" ));
1539 
1540                 /* store count */
1541                 *qcount = (FT_Byte)num_args;
1542 
1543                 val = 0;
1544                 while ( num_args > 0 )
1545                 {
1546                   val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
1547                   switch ( field->size )
1548                   {
1549                   case (8 / FT_CHAR_BIT):
1550                     *(FT_Byte*)q = (FT_Byte)val;
1551                     break;
1552 
1553                   case (16 / FT_CHAR_BIT):
1554                     *(FT_Short*)q = (FT_Short)val;
1555                     break;
1556 
1557                   case (32 / FT_CHAR_BIT):
1558                     *(FT_Int32*)q = (FT_Int)val;
1559                     break;
1560 
1561                   default:  /* for 64-bit systems */
1562                     *(FT_Long*)q = val;
1563                   }
1564 
1565                   FT_TRACE4(( " %ld", val ));
1566 
1567                   q += field->size;
1568                   num_args--;
1569                 }
1570 
1571                 FT_TRACE4(( "]\n" ));
1572               }
1573               break;
1574 
1575             default:  /* callback or blend */
1576               error = field->reader( parser );
1577               if ( error )
1578                 goto Exit;
1579             }
1580             goto Found;
1581           }
1582         }
1583 
1584         /* this is an unknown operator, or it is unsupported; */
1585         /* we will ignore it for now.                         */
1586 
1587       Found:
1588         /* clear stack */
1589         /* TODO: could clear blend stack here,       */
1590         /*       but we don't have access to subFont */
1591         if ( field->kind != cff_kind_blend )
1592           parser->top = parser->stack;
1593       }
1594       p++;
1595     } /* while ( p < limit ) */
1596 
1597   Exit:
1598     return error;
1599 
1600 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1601   Out_Of_Memory_Error:
1602     error = FT_THROW( Out_Of_Memory );
1603     goto Exit;
1604 #endif
1605 
1606   Stack_Overflow:
1607     error = FT_THROW( Invalid_Argument );
1608     goto Exit;
1609 
1610   Stack_Underflow:
1611     error = FT_THROW( Invalid_Argument );
1612     goto Exit;
1613 
1614   Syntax_Error:
1615     error = FT_THROW( Invalid_Argument );
1616     goto Exit;
1617   }
1618 
1619 
1620 /* END */