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