PageRenderTime 75ms CodeModel.GetById 17ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 1ms

/src/freetype/src/cff/cffparse.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1112 lines | 801 code | 231 blank | 80 comment | 117 complexity | 64e2113637bcf711232cd640d5fc8153 MD5 | raw file
   1/***************************************************************************/
   2/*                                                                         */
   3/*  cffparse.c                                                             */
   4/*                                                                         */
   5/*    CFF token stream parser (body)                                       */
   6/*                                                                         */
   7/*  Copyright 1996-2004, 2007-2011 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
  24#include "cfferrs.h"
  25#include "cffpic.h"
  26
  27
  28  /*************************************************************************/
  29  /*                                                                       */
  30  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  31  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  32  /* messages during execution.                                            */
  33  /*                                                                       */
  34#undef  FT_COMPONENT
  35#define FT_COMPONENT  trace_cffparse
  36
  37
  38  FT_LOCAL_DEF( void )
  39  cff_parser_init( CFF_Parser  parser,
  40                   FT_UInt     code,
  41                   void*       object,
  42                   FT_Library  library)
  43  {
  44    FT_MEM_ZERO( parser, sizeof ( *parser ) );
  45
  46    parser->top         = parser->stack;
  47    parser->object_code = code;
  48    parser->object      = object;
  49    parser->library     = library;
  50  }
  51
  52
  53  /* read an integer */
  54  static FT_Long
  55  cff_parse_integer( FT_Byte*  start,
  56                     FT_Byte*  limit )
  57  {
  58    FT_Byte*  p   = start;
  59    FT_Int    v   = *p++;
  60    FT_Long   val = 0;
  61
  62
  63    if ( v == 28 )
  64    {
  65      if ( p + 2 > limit )
  66        goto Bad;
  67
  68      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
  69      p  += 2;
  70    }
  71    else if ( v == 29 )
  72    {
  73      if ( p + 4 > limit )
  74        goto Bad;
  75
  76      val = ( (FT_Long)p[0] << 24 ) |
  77            ( (FT_Long)p[1] << 16 ) |
  78            ( (FT_Long)p[2] <<  8 ) |
  79                       p[3];
  80      p += 4;
  81    }
  82    else if ( v < 247 )
  83    {
  84      val = v - 139;
  85    }
  86    else if ( v < 251 )
  87    {
  88      if ( p + 1 > limit )
  89        goto Bad;
  90
  91      val = ( v - 247 ) * 256 + p[0] + 108;
  92      p++;
  93    }
  94    else
  95    {
  96      if ( p + 1 > limit )
  97        goto Bad;
  98
  99      val = -( v - 251 ) * 256 - p[0] - 108;
 100      p++;
 101    }
 102
 103  Exit:
 104    return val;
 105
 106  Bad:
 107    val = 0;
 108    goto Exit;
 109  }
 110
 111
 112  static const FT_Long power_tens[] =
 113  {
 114    1L,
 115    10L,
 116    100L,
 117    1000L,
 118    10000L,
 119    100000L,
 120    1000000L,
 121    10000000L,
 122    100000000L,
 123    1000000000L
 124  };
 125
 126
 127  /* read a real */
 128  static FT_Fixed
 129  cff_parse_real( FT_Byte*  start,
 130                  FT_Byte*  limit,
 131                  FT_Long   power_ten,
 132                  FT_Long*  scaling )
 133  {
 134    FT_Byte*  p = start;
 135    FT_UInt   nib;
 136    FT_UInt   phase;
 137
 138    FT_Long   result, number, exponent;
 139    FT_Int    sign = 0, exponent_sign = 0;
 140    FT_Long   exponent_add, integer_length, fraction_length;
 141
 142
 143    if ( scaling )
 144      *scaling = 0;
 145
 146    result = 0;
 147
 148    number   = 0;
 149    exponent = 0;
 150
 151    exponent_add    = 0;
 152    integer_length  = 0;
 153    fraction_length = 0;
 154
 155    /* First of all, read the integer part. */
 156    phase = 4;
 157
 158    for (;;)
 159    {
 160      /* If we entered this iteration with phase == 4, we need to */
 161      /* read a new byte.  This also skips past the initial 0x1E. */
 162      if ( phase )
 163      {
 164        p++;
 165
 166        /* Make sure we don't read past the end. */
 167        if ( p >= limit )
 168          goto Exit;
 169      }
 170
 171      /* Get the nibble. */
 172      nib   = ( p[0] >> phase ) & 0xF;
 173      phase = 4 - phase;
 174
 175      if ( nib == 0xE )
 176        sign = 1;
 177      else if ( nib > 9 )
 178        break;
 179      else
 180      {
 181        /* Increase exponent if we can't add the digit. */
 182        if ( number >= 0xCCCCCCCL )
 183          exponent_add++;
 184        /* Skip leading zeros. */
 185        else if ( nib || number )
 186        {
 187          integer_length++;
 188          number = number * 10 + nib;
 189        }
 190      }
 191    }
 192
 193    /* Read fraction part, if any. */
 194    if ( nib == 0xa )
 195      for (;;)
 196      {
 197        /* If we entered this iteration with phase == 4, we need */
 198        /* to read a new byte.                                   */
 199        if ( phase )
 200        {
 201          p++;
 202
 203          /* Make sure we don't read past the end. */
 204          if ( p >= limit )
 205            goto Exit;
 206        }
 207
 208        /* Get the nibble. */
 209        nib   = ( p[0] >> phase ) & 0xF;
 210        phase = 4 - phase;
 211        if ( nib >= 10 )
 212          break;
 213
 214        /* Skip leading zeros if possible. */
 215        if ( !nib && !number )
 216          exponent_add--;
 217        /* Only add digit if we don't overflow. */
 218        else if ( number < 0xCCCCCCCL && fraction_length < 9 )
 219        {
 220          fraction_length++;
 221          number = number * 10 + nib;
 222        }
 223      }
 224
 225    /* Read exponent, if any. */
 226    if ( nib == 12 )
 227    {
 228      exponent_sign = 1;
 229      nib           = 11;
 230    }
 231
 232    if ( nib == 11 )
 233    {
 234      for (;;)
 235      {
 236        /* If we entered this iteration with phase == 4, */
 237        /* we need to read a new byte.                   */
 238        if ( phase )
 239        {
 240          p++;
 241
 242          /* Make sure we don't read past the end. */
 243          if ( p >= limit )
 244            goto Exit;
 245        }
 246
 247        /* Get the nibble. */
 248        nib   = ( p[0] >> phase ) & 0xF;
 249        phase = 4 - phase;
 250        if ( nib >= 10 )
 251          break;
 252
 253        exponent = exponent * 10 + nib;
 254
 255        /* Arbitrarily limit exponent. */
 256        if ( exponent > 1000 )
 257          goto Exit;
 258      }
 259
 260      if ( exponent_sign )
 261        exponent = -exponent;
 262    }
 263
 264    /* We don't check `power_ten' and `exponent_add'. */
 265    exponent += power_ten + exponent_add;
 266
 267    if ( scaling )
 268    {
 269      /* Only use `fraction_length'. */
 270      fraction_length += integer_length;
 271      exponent        += integer_length;
 272
 273      if ( fraction_length <= 5 )
 274      {
 275        if ( number > 0x7FFFL )
 276        {
 277          result   = FT_DivFix( number, 10 );
 278          *scaling = exponent - fraction_length + 1;
 279        }
 280        else
 281        {
 282          if ( exponent > 0 )
 283          {
 284            FT_Long  new_fraction_length, shift;
 285
 286
 287            /* Make `scaling' as small as possible. */
 288            new_fraction_length = FT_MIN( exponent, 5 );
 289            exponent           -= new_fraction_length;
 290            shift               = new_fraction_length - fraction_length;
 291
 292            number *= power_tens[shift];
 293            if ( number > 0x7FFFL )
 294            {
 295              number   /= 10;
 296              exponent += 1;
 297            }
 298          }
 299          else
 300            exponent -= fraction_length;
 301
 302          result   = number << 16;
 303          *scaling = exponent;
 304        }
 305      }
 306      else
 307      {
 308        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
 309        {
 310          result   = FT_DivFix( number, power_tens[fraction_length - 4] );
 311          *scaling = exponent - 4;
 312        }
 313        else
 314        {
 315          result   = FT_DivFix( number, power_tens[fraction_length - 5] );
 316          *scaling = exponent - 5;
 317        }
 318      }
 319    }
 320    else
 321    {
 322      integer_length  += exponent;
 323      fraction_length -= exponent;
 324
 325      /* Check for overflow and underflow. */
 326      if ( FT_ABS( integer_length ) > 5 )
 327        goto Exit;
 328
 329      /* Remove non-significant digits. */
 330      if ( integer_length < 0 )
 331      {
 332        number          /= power_tens[-integer_length];
 333        fraction_length += integer_length;
 334      }
 335
 336      /* this can only happen if exponent was non-zero */
 337      if ( fraction_length == 10 )
 338      {
 339        number          /= 10;
 340        fraction_length -= 1;
 341      }
 342
 343      /* Convert into 16.16 format. */
 344      if ( fraction_length > 0 )
 345      {
 346        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
 347          goto Exit;
 348
 349        result = FT_DivFix( number, power_tens[fraction_length] );
 350      }
 351      else
 352      {
 353        number *= power_tens[-fraction_length];
 354
 355        if ( number > 0x7FFFL )
 356          goto Exit;
 357
 358        result = number << 16;
 359      }
 360    }
 361
 362    if ( sign )
 363      result = -result;
 364
 365  Exit:
 366    return result;
 367  }
 368
 369
 370  /* read a number, either integer or real */
 371  static FT_Long
 372  cff_parse_num( FT_Byte**  d )
 373  {
 374    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
 375                     :   cff_parse_integer( d[0], d[1] );
 376  }
 377
 378
 379  /* read a floating point number, either integer or real */
 380  static FT_Fixed
 381  cff_parse_fixed( FT_Byte**  d )
 382  {
 383    return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
 384                     : cff_parse_integer( d[0], d[1] ) << 16;
 385  }
 386
 387
 388  /* read a floating point number, either integer or real, */
 389  /* but return `10^scaling' times the number read in      */
 390  static FT_Fixed
 391  cff_parse_fixed_scaled( FT_Byte**  d,
 392                          FT_Long    scaling )
 393  {
 394    return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
 395                     : ( cff_parse_integer( d[0], d[1] ) *
 396                           power_tens[scaling] ) << 16;
 397  }
 398
 399
 400  /* read a floating point number, either integer or real,     */
 401  /* and return it as precise as possible -- `scaling' returns */
 402  /* the scaling factor (as a power of 10)                     */
 403  static FT_Fixed
 404  cff_parse_fixed_dynamic( FT_Byte**  d,
 405                           FT_Long*   scaling )
 406  {
 407    FT_ASSERT( scaling );
 408
 409    if ( **d == 30 )
 410      return cff_parse_real( d[0], d[1], 0, scaling );
 411    else
 412    {
 413      FT_Long  number;
 414      FT_Int   integer_length;
 415
 416
 417      number = cff_parse_integer( d[0], d[1] );
 418
 419      if ( number > 0x7FFFL )
 420      {
 421        for ( integer_length = 5; integer_length < 10; integer_length++ )
 422          if ( number < power_tens[integer_length] )
 423            break;
 424
 425        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
 426        {
 427          *scaling = integer_length - 4;
 428          return FT_DivFix( number, power_tens[integer_length - 4] );
 429        }
 430        else
 431        {
 432          *scaling = integer_length - 5;
 433          return FT_DivFix( number, power_tens[integer_length - 5] );
 434        }
 435      }
 436      else
 437      {
 438        *scaling = 0;
 439        return number << 16;
 440      }
 441    }
 442  }
 443
 444
 445  static FT_Error
 446  cff_parse_font_matrix( CFF_Parser  parser )
 447  {
 448    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
 449    FT_Matrix*       matrix = &dict->font_matrix;
 450    FT_Vector*       offset = &dict->font_offset;
 451    FT_ULong*        upm    = &dict->units_per_em;
 452    FT_Byte**        data   = parser->stack;
 453    FT_Error         error  = CFF_Err_Stack_Underflow;
 454
 455
 456    if ( parser->top >= parser->stack + 6 )
 457    {
 458      FT_Long  scaling;
 459
 460
 461      error = CFF_Err_Ok;
 462
 463      dict->has_font_matrix = TRUE;
 464
 465      /* We expect a well-formed font matrix, this is, the matrix elements */
 466      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
 467      /* loss of precision, we use the magnitude of element `xx' to scale  */
 468      /* all other elements.  The scaling factor is then contained in the  */
 469      /* `units_per_em' value.                                             */
 470
 471      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
 472
 473      scaling = -scaling;
 474
 475      if ( scaling < 0 || scaling > 9 )
 476      {
 477        /* Return default matrix in case of unlikely values. */
 478
 479        FT_TRACE1(( "cff_parse_font_matrix:"
 480                    " strange scaling value for xx element (%d),\n"
 481                    "                      "
 482                    " using default matrix\n", scaling ));
 483
 484        matrix->xx = 0x10000L;
 485        matrix->yx = 0;
 486        matrix->xy = 0;
 487        matrix->yy = 0x10000L;
 488        offset->x  = 0;
 489        offset->y  = 0;
 490        *upm       = 1;
 491
 492        goto Exit;
 493      }
 494
 495      matrix->yx = cff_parse_fixed_scaled( data++, scaling );
 496      matrix->xy = cff_parse_fixed_scaled( data++, scaling );
 497      matrix->yy = cff_parse_fixed_scaled( data++, scaling );
 498      offset->x  = cff_parse_fixed_scaled( data++, scaling );
 499      offset->y  = cff_parse_fixed_scaled( data,   scaling );
 500
 501      *upm = power_tens[scaling];
 502
 503      FT_TRACE4(( " [%f %f %f %f %f %f]\n",
 504                  (double)matrix->xx / *upm / 65536,
 505                  (double)matrix->xy / *upm / 65536,
 506                  (double)matrix->yx / *upm / 65536,
 507                  (double)matrix->yy / *upm / 65536,
 508                  (double)offset->x  / *upm / 65536,
 509                  (double)offset->y  / *upm / 65536 ));
 510    }
 511
 512  Exit:
 513    return error;
 514  }
 515
 516
 517  static FT_Error
 518  cff_parse_font_bbox( CFF_Parser  parser )
 519  {
 520    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 521    FT_BBox*         bbox = &dict->font_bbox;
 522    FT_Byte**        data = parser->stack;
 523    FT_Error         error;
 524
 525
 526    error = CFF_Err_Stack_Underflow;
 527
 528    if ( parser->top >= parser->stack + 4 )
 529    {
 530      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
 531      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
 532      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
 533      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
 534      error = CFF_Err_Ok;
 535
 536      FT_TRACE4(( " [%d %d %d %d]\n",
 537                  bbox->xMin / 65536,
 538                  bbox->yMin / 65536,
 539                  bbox->xMax / 65536,
 540                  bbox->yMax / 65536 ));
 541    }
 542
 543    return error;
 544  }
 545
 546
 547  static FT_Error
 548  cff_parse_private_dict( CFF_Parser  parser )
 549  {
 550    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 551    FT_Byte**        data = parser->stack;
 552    FT_Error         error;
 553
 554
 555    error = CFF_Err_Stack_Underflow;
 556
 557    if ( parser->top >= parser->stack + 2 )
 558    {
 559      dict->private_size   = cff_parse_num( data++ );
 560      dict->private_offset = cff_parse_num( data   );
 561      FT_TRACE4(( " %lu %lu\n",
 562                  dict->private_size, dict->private_offset ));
 563
 564      error = CFF_Err_Ok;
 565    }
 566
 567    return error;
 568  }
 569
 570
 571  static FT_Error
 572  cff_parse_cid_ros( CFF_Parser  parser )
 573  {
 574    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
 575    FT_Byte**        data = parser->stack;
 576    FT_Error         error;
 577
 578
 579    error = CFF_Err_Stack_Underflow;
 580
 581    if ( parser->top >= parser->stack + 3 )
 582    {
 583      dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
 584      dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
 585      if ( **data == 30 )
 586        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
 587      dict->cid_supplement = cff_parse_num( data );
 588      if ( dict->cid_supplement < 0 )
 589        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
 590                   dict->cid_supplement ));
 591      error = CFF_Err_Ok;
 592
 593      FT_TRACE4(( " %d %d %d\n",
 594                  dict->cid_registry,
 595                  dict->cid_ordering,
 596                  dict->cid_supplement ));
 597    }
 598
 599    return error;
 600  }
 601
 602
 603#define CFF_FIELD_NUM( code, name, id )             \
 604          CFF_FIELD( code, name, id, cff_kind_num )
 605#define CFF_FIELD_FIXED( code, name, id )             \
 606          CFF_FIELD( code, name, id, cff_kind_fixed )
 607#define CFF_FIELD_FIXED_1000( code, name, id )                 \
 608          CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
 609#define CFF_FIELD_STRING( code, name, id )             \
 610          CFF_FIELD( code, name, id, cff_kind_string )
 611#define CFF_FIELD_BOOL( code, name, id )             \
 612          CFF_FIELD( code, name, id, cff_kind_bool )
 613
 614#define CFFCODE_TOPDICT  0x1000
 615#define CFFCODE_PRIVATE  0x2000
 616
 617
 618#ifndef FT_CONFIG_OPTION_PIC
 619
 620
 621#undef  CFF_FIELD
 622#undef  CFF_FIELD_DELTA
 623
 624
 625#ifndef FT_DEBUG_LEVEL_TRACE
 626
 627
 628#define CFF_FIELD_CALLBACK( code, name, id ) \
 629          {                                  \
 630            cff_kind_callback,               \
 631            code | CFFCODE,                  \
 632            0, 0,                            \
 633            cff_parse_ ## name,              \
 634            0, 0                             \
 635          },
 636
 637#define CFF_FIELD( code, name, id, kind ) \
 638          {                               \
 639            kind,                         \
 640            code | CFFCODE,               \
 641            FT_FIELD_OFFSET( name ),      \
 642            FT_FIELD_SIZE( name ),        \
 643            0, 0, 0                       \
 644          },
 645
 646#define CFF_FIELD_DELTA( code, name, max, id ) \
 647          {                                    \
 648            cff_kind_delta,                    \
 649            code | CFFCODE,                    \
 650            FT_FIELD_OFFSET( name ),           \
 651            FT_FIELD_SIZE_DELTA( name ),       \
 652            0,                                 \
 653            max,                               \
 654            FT_FIELD_OFFSET( num_ ## name )    \
 655          },
 656
 657  static const CFF_Field_Handler  cff_field_handlers[] =
 658  {
 659
 660#include "cfftoken.h"
 661
 662    { 0, 0, 0, 0, 0, 0, 0 }
 663  };
 664
 665
 666#else /* FT_DEBUG_LEVEL_TRACE */
 667
 668
 669
 670#define CFF_FIELD_CALLBACK( code, name, id ) \
 671          {                                  \
 672            cff_kind_callback,               \
 673            code | CFFCODE,                  \
 674            0, 0,                            \
 675            cff_parse_ ## name,              \
 676            0, 0,                            \
 677            id                               \
 678          },
 679
 680#define CFF_FIELD( code, name, id, kind ) \
 681          {                               \
 682            kind,                         \
 683            code | CFFCODE,               \
 684            FT_FIELD_OFFSET( name ),      \
 685            FT_FIELD_SIZE( name ),        \
 686            0, 0, 0,                      \
 687            id                            \
 688          },
 689
 690#define CFF_FIELD_DELTA( code, name, max, id ) \
 691          {                                    \
 692            cff_kind_delta,                    \
 693            code | CFFCODE,                    \
 694            FT_FIELD_OFFSET( name ),           \
 695            FT_FIELD_SIZE_DELTA( name ),       \
 696            0,                                 \
 697            max,                               \
 698            FT_FIELD_OFFSET( num_ ## name ),   \
 699            id                                 \
 700          },
 701
 702  static const CFF_Field_Handler  cff_field_handlers[] =
 703  {
 704
 705#include "cfftoken.h"
 706
 707    { 0, 0, 0, 0, 0, 0, 0, 0 }
 708  };
 709
 710
 711#endif /* FT_DEBUG_LEVEL_TRACE */
 712
 713
 714#else /* FT_CONFIG_OPTION_PIC */
 715
 716
 717  void
 718  FT_Destroy_Class_cff_field_handlers( FT_Library          library,
 719                                       CFF_Field_Handler*  clazz )
 720  {
 721    FT_Memory  memory = library->memory;
 722
 723
 724    if ( clazz )
 725      FT_FREE( clazz );
 726  }
 727
 728
 729  FT_Error
 730  FT_Create_Class_cff_field_handlers( FT_Library           library,
 731                                      CFF_Field_Handler**  output_class )
 732  {
 733    CFF_Field_Handler*  clazz;
 734    FT_Error            error;
 735    FT_Memory           memory = library->memory;
 736
 737    int  i = 0;
 738
 739
 740#undef CFF_FIELD
 741#define CFF_FIELD( code, name, id, kind ) i++;
 742#undef CFF_FIELD_DELTA
 743#define CFF_FIELD_DELTA( code, name, max, id ) i++;
 744#undef CFF_FIELD_CALLBACK
 745#define CFF_FIELD_CALLBACK( code, name, id ) i++;
 746
 747#include "cfftoken.h"
 748
 749    i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
 750
 751    if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
 752      return error;
 753
 754    i = 0;
 755
 756
 757#ifndef FT_DEBUG_LEVEL_TRACE
 758
 759
 760#undef CFF_FIELD_CALLBACK
 761#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
 762          clazz[i].kind         = cff_kind_callback;   \
 763          clazz[i].code         = code_ | CFFCODE;     \
 764          clazz[i].offset       = 0;                   \
 765          clazz[i].size         = 0;                   \
 766          clazz[i].reader       = cff_parse_ ## name_; \
 767          clazz[i].array_max    = 0;                   \
 768          clazz[i].count_offset = 0;                   \
 769          i++;
 770
 771#undef  CFF_FIELD
 772#define CFF_FIELD( code_, name_, id_, kind_ )               \
 773          clazz[i].kind         = kind_;                    \
 774          clazz[i].code         = code_ | CFFCODE;          \
 775          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
 776          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
 777          clazz[i].reader       = 0;                        \
 778          clazz[i].array_max    = 0;                        \
 779          clazz[i].count_offset = 0;                        \
 780          i++;                                              \
 781
 782#undef  CFF_FIELD_DELTA
 783#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
 784          clazz[i].kind         = cff_kind_delta;                   \
 785          clazz[i].code         = code_ | CFFCODE;                  \
 786          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
 787          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
 788          clazz[i].reader       = 0;                                \
 789          clazz[i].array_max    = max_;                             \
 790          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
 791          i++;
 792
 793#include "cfftoken.h"
 794
 795    clazz[i].kind         = 0;
 796    clazz[i].code         = 0;
 797    clazz[i].offset       = 0;
 798    clazz[i].size         = 0;
 799    clazz[i].reader       = 0;
 800    clazz[i].array_max    = 0;
 801    clazz[i].count_offset = 0;
 802
 803
 804#else /* FT_DEBUG_LEVEL_TRACE */
 805
 806
 807#undef CFF_FIELD_CALLBACK
 808#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
 809          clazz[i].kind         = cff_kind_callback;   \
 810          clazz[i].code         = code_ | CFFCODE;     \
 811          clazz[i].offset       = 0;                   \
 812          clazz[i].size         = 0;                   \
 813          clazz[i].reader       = cff_parse_ ## name_; \
 814          clazz[i].array_max    = 0;                   \
 815          clazz[i].count_offset = 0;                   \
 816          clazz[i].id           = id_;                 \
 817          i++;
 818
 819#undef  CFF_FIELD
 820#define CFF_FIELD( code_, name_, id_, kind_ )               \
 821          clazz[i].kind         = kind_;                    \
 822          clazz[i].code         = code_ | CFFCODE;          \
 823          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
 824          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
 825          clazz[i].reader       = 0;                        \
 826          clazz[i].array_max    = 0;                        \
 827          clazz[i].count_offset = 0;                        \
 828          clazz[i].id           = id_;                      \
 829          i++;                                              \
 830
 831#undef  CFF_FIELD_DELTA
 832#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
 833          clazz[i].kind         = cff_kind_delta;                   \
 834          clazz[i].code         = code_ | CFFCODE;                  \
 835          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
 836          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
 837          clazz[i].reader       = 0;                                \
 838          clazz[i].array_max    = max_;                             \
 839          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
 840          clazz[i].id           = id_;                              \
 841          i++;
 842
 843#include "cfftoken.h"
 844
 845    clazz[i].kind         = 0;
 846    clazz[i].code         = 0;
 847    clazz[i].offset       = 0;
 848    clazz[i].size         = 0;
 849    clazz[i].reader       = 0;
 850    clazz[i].array_max    = 0;
 851    clazz[i].count_offset = 0;
 852    clazz[i].id           = 0;
 853
 854
 855#endif /* FT_DEBUG_LEVEL_TRACE */
 856
 857
 858    *output_class = clazz;
 859
 860    return CFF_Err_Ok;
 861  }
 862
 863
 864#endif /* FT_CONFIG_OPTION_PIC */
 865
 866
 867  FT_LOCAL_DEF( FT_Error )
 868  cff_parser_run( CFF_Parser  parser,
 869                  FT_Byte*    start,
 870                  FT_Byte*    limit )
 871  {
 872    FT_Byte*    p       = start;
 873    FT_Error    error   = CFF_Err_Ok;
 874    FT_Library  library = parser->library;
 875    FT_UNUSED( library );
 876
 877
 878    parser->top    = parser->stack;
 879    parser->start  = start;
 880    parser->limit  = limit;
 881    parser->cursor = start;
 882
 883    while ( p < limit )
 884    {
 885      FT_UInt  v = *p;
 886
 887
 888      if ( v >= 27 && v != 31 )
 889      {
 890        /* it's a number; we will push its position on the stack */
 891        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
 892          goto Stack_Overflow;
 893
 894        *parser->top ++ = p;
 895
 896        /* now, skip it */
 897        if ( v == 30 )
 898        {
 899          /* skip real number */
 900          p++;
 901          for (;;)
 902          {
 903            /* An unterminated floating point number at the */
 904            /* end of a dictionary is invalid but harmless. */
 905            if ( p >= limit )
 906              goto Exit;
 907            v = p[0] >> 4;
 908            if ( v == 15 )
 909              break;
 910            v = p[0] & 0xF;
 911            if ( v == 15 )
 912              break;
 913            p++;
 914          }
 915        }
 916        else if ( v == 28 )
 917          p += 2;
 918        else if ( v == 29 )
 919          p += 4;
 920        else if ( v > 246 )
 921          p += 1;
 922      }
 923      else
 924      {
 925        /* This is not a number, hence it's an operator.  Compute its code */
 926        /* and look for it in our current list.                            */
 927
 928        FT_UInt                   code;
 929        FT_UInt                   num_args = (FT_UInt)
 930                                             ( parser->top - parser->stack );
 931        const CFF_Field_Handler*  field;
 932
 933
 934        *parser->top = p;
 935        code = v;
 936        if ( v == 12 )
 937        {
 938          /* two byte operator */
 939          p++;
 940          if ( p >= limit )
 941            goto Syntax_Error;
 942
 943          code = 0x100 | p[0];
 944        }
 945        code = code | parser->object_code;
 946
 947        for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
 948        {
 949          if ( field->code == (FT_Int)code )
 950          {
 951            /* we found our field's handler; read it */
 952            FT_Long   val;
 953            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
 954
 955
 956#ifdef FT_DEBUG_LEVEL_TRACE
 957            FT_TRACE4(( "  %s", field->id ));
 958#endif
 959
 960            /* check that we have enough arguments -- except for */
 961            /* delta encoded arrays, which can be empty          */
 962            if ( field->kind != cff_kind_delta && num_args < 1 )
 963              goto Stack_Underflow;
 964
 965            switch ( field->kind )
 966            {
 967            case cff_kind_bool:
 968            case cff_kind_string:
 969            case cff_kind_num:
 970              val = cff_parse_num( parser->stack );
 971              goto Store_Number;
 972
 973            case cff_kind_fixed:
 974              val = cff_parse_fixed( parser->stack );
 975              goto Store_Number;
 976
 977            case cff_kind_fixed_thousand:
 978              val = cff_parse_fixed_scaled( parser->stack, 3 );
 979
 980            Store_Number:
 981              switch ( field->size )
 982              {
 983              case (8 / FT_CHAR_BIT):
 984                *(FT_Byte*)q = (FT_Byte)val;
 985                break;
 986
 987              case (16 / FT_CHAR_BIT):
 988                *(FT_Short*)q = (FT_Short)val;
 989                break;
 990
 991              case (32 / FT_CHAR_BIT):
 992                *(FT_Int32*)q = (FT_Int)val;
 993                break;
 994
 995              default:  /* for 64-bit systems */
 996                *(FT_Long*)q = val;
 997              }
 998
 999#ifdef FT_DEBUG_LEVEL_TRACE
1000              switch ( field->kind )
1001              {
1002              case cff_kind_bool:
1003                FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1004                break;
1005
1006              case cff_kind_string:
1007                FT_TRACE4(( " %ld (SID)\n", val ));
1008                break;
1009
1010              case cff_kind_num:
1011                FT_TRACE4(( " %ld\n", val ));
1012                break;
1013
1014              case cff_kind_fixed:
1015                FT_TRACE4(( " %f\n", (double)val / 65536 ));
1016                break;
1017
1018              case cff_kind_fixed_thousand:
1019                FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1020
1021              default:
1022                ; /* never reached */
1023              }
1024#endif
1025
1026              break;
1027
1028            case cff_kind_delta:
1029              {
1030                FT_Byte*   qcount = (FT_Byte*)parser->object +
1031                                      field->count_offset;
1032
1033                FT_Byte**  data = parser->stack;
1034
1035
1036                if ( num_args > field->array_max )
1037                  num_args = field->array_max;
1038
1039                FT_TRACE4(( " [" ));
1040
1041                /* store count */
1042                *qcount = (FT_Byte)num_args;
1043
1044                val = 0;
1045                while ( num_args > 0 )
1046                {
1047                  val += cff_parse_num( data++ );
1048                  switch ( field->size )
1049                  {
1050                  case (8 / FT_CHAR_BIT):
1051                    *(FT_Byte*)q = (FT_Byte)val;
1052                    break;
1053
1054                  case (16 / FT_CHAR_BIT):
1055                    *(FT_Short*)q = (FT_Short)val;
1056                    break;
1057
1058                  case (32 / FT_CHAR_BIT):
1059                    *(FT_Int32*)q = (FT_Int)val;
1060                    break;
1061
1062                  default:  /* for 64-bit systems */
1063                    *(FT_Long*)q = val;
1064                  }
1065
1066                  FT_TRACE4(( " %ld", val ));
1067
1068                  q += field->size;
1069                  num_args--;
1070                }
1071
1072                FT_TRACE4(( "]\n" ));
1073              }
1074              break;
1075
1076            default:  /* callback */
1077              error = field->reader( parser );
1078              if ( error )
1079                goto Exit;
1080            }
1081            goto Found;
1082          }
1083        }
1084
1085        /* this is an unknown operator, or it is unsupported; */
1086        /* we will ignore it for now.                         */
1087
1088      Found:
1089        /* clear stack */
1090        parser->top = parser->stack;
1091      }
1092      p++;
1093    }
1094
1095  Exit:
1096    return error;
1097
1098  Stack_Overflow:
1099    error = CFF_Err_Invalid_Argument;
1100    goto Exit;
1101
1102  Stack_Underflow:
1103    error = CFF_Err_Invalid_Argument;
1104    goto Exit;
1105
1106  Syntax_Error:
1107    error = CFF_Err_Invalid_Argument;
1108    goto Exit;
1109  }
1110
1111
1112/* END */