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 )
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_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
cff_parse_real(FT_Byte * start,FT_Byte * limit,FT_Long power_ten,FT_Long * scaling)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
cff_parse_num(FT_Byte ** d)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
do_fixed(FT_Byte ** d,FT_Long scaling)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
cff_parse_fixed(FT_Byte ** d)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
cff_parse_fixed_scaled(FT_Byte ** d,FT_Long scaling)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
cff_parse_fixed_dynamic(FT_Byte ** d,FT_Long * scaling)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
cff_parse_font_matrix(CFF_Parser parser)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
cff_parse_font_bbox(CFF_Parser parser)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
cff_parse_private_dict(CFF_Parser parser)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
cff_parse_cid_ros(CFF_Parser parser)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
FT_Destroy_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler * clazz)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
FT_Create_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler ** output_class)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 )
cff_parser_run(CFF_Parser parser,FT_Byte * start,FT_Byte * limit)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