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