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