• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 )
cff_parser_init(CFF_Parser parser,FT_UInt code,void * object,FT_Library library)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
cff_parse_integer(FT_Byte * start,FT_Byte * limit)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
cff_parse_real(FT_Byte * start,FT_Byte * limit,FT_Long power_ten,FT_Long * scaling)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
cff_parse_num(FT_Byte ** d)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
cff_parse_fixed(FT_Byte ** d)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
cff_parse_fixed_scaled(FT_Byte ** d,FT_Long scaling)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
cff_parse_fixed_dynamic(FT_Byte ** d,FT_Long * scaling)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
cff_parse_font_matrix(CFF_Parser parser)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
cff_parse_font_bbox(CFF_Parser parser)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
cff_parse_private_dict(CFF_Parser parser)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
cff_parse_cid_ros(CFF_Parser parser)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
FT_Destroy_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler * clazz)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
FT_Create_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler ** output_class)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 )
cff_parser_run(CFF_Parser parser,FT_Byte * start,FT_Byte * limit)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 */
1113