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