• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cffparse.c                                                             */
4 /*                                                                         */
5 /*    CFF token stream parser (body)                                       */
6 /*                                                                         */
7 /*  Copyright 1996-2017 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 #include "cffgload.h"
27 #include "cffload.h"
28 
29 
30   /*************************************************************************/
31   /*                                                                       */
32   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
33   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
34   /* messages during execution.                                            */
35   /*                                                                       */
36 #undef  FT_COMPONENT
37 #define FT_COMPONENT  trace_cffparse
38 
39 
40   FT_LOCAL_DEF( FT_Error )
cff_parser_init(CFF_Parser parser,FT_UInt code,void * object,FT_Library library,FT_UInt stackSize,FT_UShort num_designs,FT_UShort num_axes)41   cff_parser_init( CFF_Parser  parser,
42                    FT_UInt     code,
43                    void*       object,
44                    FT_Library  library,
45                    FT_UInt     stackSize,
46                    FT_UShort   num_designs,
47                    FT_UShort   num_axes )
48   {
49     FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
50     FT_Error   error;                       /* for FT_NEW_ARRAY */
51 
52 
53     FT_ZERO( parser );
54 
55 #if 0
56     parser->top         = parser->stack;
57 #endif
58     parser->object_code = code;
59     parser->object      = object;
60     parser->library     = library;
61     parser->num_designs = num_designs;
62     parser->num_axes    = num_axes;
63 
64     /* allocate the stack buffer */
65     if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
66     {
67       FT_FREE( parser->stack );
68       goto Exit;
69     }
70 
71     parser->stackSize = stackSize;
72     parser->top       = parser->stack;    /* empty stack */
73 
74   Exit:
75     return error;
76   }
77 
78 
79   FT_LOCAL_DEF( void )
cff_parser_done(CFF_Parser parser)80   cff_parser_done( CFF_Parser  parser )
81   {
82     FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
83 
84 
85     FT_FREE( parser->stack );
86   }
87 
88 
89   /* read an integer */
90   static FT_Long
cff_parse_integer(FT_Byte * start,FT_Byte * limit)91   cff_parse_integer( FT_Byte*  start,
92                      FT_Byte*  limit )
93   {
94     FT_Byte*  p   = start;
95     FT_Int    v   = *p++;
96     FT_Long   val = 0;
97 
98 
99     if ( v == 28 )
100     {
101       if ( p + 2 > limit )
102         goto Bad;
103 
104       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
105     }
106     else if ( v == 29 )
107     {
108       if ( p + 4 > limit )
109         goto Bad;
110 
111       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
112                        ( (FT_ULong)p[1] << 16 ) |
113                        ( (FT_ULong)p[2] <<  8 ) |
114                          (FT_ULong)p[3]         );
115     }
116     else if ( v < 247 )
117     {
118       val = v - 139;
119     }
120     else if ( v < 251 )
121     {
122       if ( p + 1 > limit )
123         goto Bad;
124 
125       val = ( v - 247 ) * 256 + p[0] + 108;
126     }
127     else
128     {
129       if ( p + 1 > limit )
130         goto Bad;
131 
132       val = -( v - 251 ) * 256 - p[0] - 108;
133     }
134 
135   Exit:
136     return val;
137 
138   Bad:
139     val = 0;
140     FT_TRACE4(( "!!!END OF DATA:!!!" ));
141     goto Exit;
142   }
143 
144 
145   static const FT_Long power_tens[] =
146   {
147     1L,
148     10L,
149     100L,
150     1000L,
151     10000L,
152     100000L,
153     1000000L,
154     10000000L,
155     100000000L,
156     1000000000L
157   };
158 
159 
160   /* read a real */
161   static FT_Fixed
cff_parse_real(FT_Byte * start,FT_Byte * limit,FT_Long power_ten,FT_Long * scaling)162   cff_parse_real( FT_Byte*  start,
163                   FT_Byte*  limit,
164                   FT_Long   power_ten,
165                   FT_Long*  scaling )
166   {
167     FT_Byte*  p = start;
168     FT_Int    nib;
169     FT_UInt   phase;
170 
171     FT_Long   result, number, exponent;
172     FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
173     FT_Long   exponent_add, integer_length, fraction_length;
174 
175 
176     if ( scaling )
177       *scaling = 0;
178 
179     result = 0;
180 
181     number   = 0;
182     exponent = 0;
183 
184     exponent_add    = 0;
185     integer_length  = 0;
186     fraction_length = 0;
187 
188     /* First of all, read the integer part. */
189     phase = 4;
190 
191     for (;;)
192     {
193       /* If we entered this iteration with phase == 4, we need to */
194       /* read a new byte.  This also skips past the initial 0x1E. */
195       if ( phase )
196       {
197         p++;
198 
199         /* Make sure we don't read past the end. */
200         if ( p >= limit )
201           goto Bad;
202       }
203 
204       /* Get the nibble. */
205       nib   = (FT_Int)( p[0] >> phase ) & 0xF;
206       phase = 4 - phase;
207 
208       if ( nib == 0xE )
209         sign = 1;
210       else if ( nib > 9 )
211         break;
212       else
213       {
214         /* Increase exponent if we can't add the digit. */
215         if ( number >= 0xCCCCCCCL )
216           exponent_add++;
217         /* Skip leading zeros. */
218         else if ( nib || number )
219         {
220           integer_length++;
221           number = number * 10 + nib;
222         }
223       }
224     }
225 
226     /* Read fraction part, if any. */
227     if ( nib == 0xA )
228       for (;;)
229       {
230         /* If we entered this iteration with phase == 4, we need */
231         /* to read a new byte.                                   */
232         if ( phase )
233         {
234           p++;
235 
236           /* Make sure we don't read past the end. */
237           if ( p >= limit )
238             goto Bad;
239         }
240 
241         /* Get the nibble. */
242         nib   = ( p[0] >> phase ) & 0xF;
243         phase = 4 - phase;
244         if ( nib >= 10 )
245           break;
246 
247         /* Skip leading zeros if possible. */
248         if ( !nib && !number )
249           exponent_add--;
250         /* Only add digit if we don't overflow. */
251         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
252         {
253           fraction_length++;
254           number = number * 10 + nib;
255         }
256       }
257 
258     /* Read exponent, if any. */
259     if ( nib == 12 )
260     {
261       exponent_sign = 1;
262       nib           = 11;
263     }
264 
265     if ( nib == 11 )
266     {
267       for (;;)
268       {
269         /* If we entered this iteration with phase == 4, */
270         /* we need to read a new byte.                   */
271         if ( phase )
272         {
273           p++;
274 
275           /* Make sure we don't read past the end. */
276           if ( p >= limit )
277             goto Bad;
278         }
279 
280         /* Get the nibble. */
281         nib   = ( p[0] >> phase ) & 0xF;
282         phase = 4 - phase;
283         if ( nib >= 10 )
284           break;
285 
286         /* Arbitrarily limit exponent. */
287         if ( exponent > 1000 )
288           have_overflow = 1;
289         else
290           exponent = exponent * 10 + nib;
291       }
292 
293       if ( exponent_sign )
294         exponent = -exponent;
295     }
296 
297     if ( !number )
298       goto Exit;
299 
300     if ( have_overflow )
301     {
302       if ( exponent_sign )
303         goto Underflow;
304       else
305         goto Overflow;
306     }
307 
308     /* We don't check `power_ten' and `exponent_add'. */
309     exponent += power_ten + exponent_add;
310 
311     if ( scaling )
312     {
313       /* Only use `fraction_length'. */
314       fraction_length += integer_length;
315       exponent        += integer_length;
316 
317       if ( fraction_length <= 5 )
318       {
319         if ( number > 0x7FFFL )
320         {
321           result   = FT_DivFix( number, 10 );
322           *scaling = exponent - fraction_length + 1;
323         }
324         else
325         {
326           if ( exponent > 0 )
327           {
328             FT_Long  new_fraction_length, shift;
329 
330 
331             /* Make `scaling' as small as possible. */
332             new_fraction_length = FT_MIN( exponent, 5 );
333             shift               = new_fraction_length - fraction_length;
334 
335             if ( shift > 0 )
336             {
337               exponent -= new_fraction_length;
338               number   *= power_tens[shift];
339               if ( number > 0x7FFFL )
340               {
341                 number   /= 10;
342                 exponent += 1;
343               }
344             }
345             else
346               exponent -= fraction_length;
347           }
348           else
349             exponent -= fraction_length;
350 
351           result   = (FT_Long)( (FT_ULong)number << 16 );
352           *scaling = exponent;
353         }
354       }
355       else
356       {
357         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
358         {
359           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
360           *scaling = exponent - 4;
361         }
362         else
363         {
364           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
365           *scaling = exponent - 5;
366         }
367       }
368     }
369     else
370     {
371       integer_length  += exponent;
372       fraction_length -= exponent;
373 
374       if ( integer_length > 5 )
375         goto Overflow;
376       if ( integer_length < -5 )
377         goto Underflow;
378 
379       /* Remove non-significant digits. */
380       if ( integer_length < 0 )
381       {
382         number          /= power_tens[-integer_length];
383         fraction_length += integer_length;
384       }
385 
386       /* this can only happen if exponent was non-zero */
387       if ( fraction_length == 10 )
388       {
389         number          /= 10;
390         fraction_length -= 1;
391       }
392 
393       /* Convert into 16.16 format. */
394       if ( fraction_length > 0 )
395       {
396         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
397           goto Exit;
398 
399         result = FT_DivFix( number, power_tens[fraction_length] );
400       }
401       else
402       {
403         number *= power_tens[-fraction_length];
404 
405         if ( number > 0x7FFFL )
406           goto Overflow;
407 
408         result = (FT_Long)( (FT_ULong)number << 16 );
409       }
410     }
411 
412   Exit:
413     if ( sign )
414       result = -result;
415 
416     return result;
417 
418   Overflow:
419     result = 0x7FFFFFFFL;
420     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
421     goto Exit;
422 
423   Underflow:
424     result = 0;
425     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
426     goto Exit;
427 
428   Bad:
429     result = 0;
430     FT_TRACE4(( "!!!END OF DATA:!!!" ));
431     goto Exit;
432   }
433 
434 
435   /* read a number, either integer or real */
436   FT_LOCAL_DEF( FT_Long )
cff_parse_num(CFF_Parser parser,FT_Byte ** d)437   cff_parse_num( CFF_Parser  parser,
438                  FT_Byte**   d )
439   {
440     if ( **d == 30 )
441     {
442       /* binary-coded decimal is truncated to integer */
443       return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
444     }
445 
446     else if ( **d == 255 )
447     {
448       /* 16.16 fixed point is used internally for CFF2 blend results. */
449       /* Since these are trusted values, a limit check is not needed. */
450 
451       /* After the 255, 4 bytes give the number.                 */
452       /* The blend value is converted to integer, with rounding; */
453       /* due to the right-shift we don't need the lowest byte.   */
454 #if 0
455       return (FT_Short)(
456                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
457                    ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
458                    ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
459                      (FT_UInt32)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
460 #else
461       return (FT_Short)(
462                ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
463                    ( (FT_UInt32)*( d[0] + 2 ) <<  8 ) |
464                      (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
465 #endif
466     }
467 
468     else
469       return cff_parse_integer( *d, parser->limit );
470   }
471 
472 
473   /* read a floating point number, either integer or real */
474   static FT_Fixed
do_fixed(CFF_Parser parser,FT_Byte ** d,FT_Long scaling)475   do_fixed( CFF_Parser  parser,
476             FT_Byte**   d,
477             FT_Long     scaling )
478   {
479     if ( **d == 30 )
480       return cff_parse_real( *d, parser->limit, scaling, NULL );
481     else
482     {
483       FT_Long  val = cff_parse_integer( *d, parser->limit );
484 
485 
486       if ( scaling )
487         val *= power_tens[scaling];
488 
489       if ( val > 0x7FFF )
490       {
491         val = 0x7FFFFFFFL;
492         goto Overflow;
493       }
494       else if ( val < -0x7FFF )
495       {
496         val = -0x7FFFFFFFL;
497         goto Overflow;
498       }
499 
500       return (FT_Long)( (FT_ULong)val << 16 );
501 
502     Overflow:
503       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
504       return val;
505     }
506   }
507 
508 
509   /* read a floating point number, either integer or real */
510   static FT_Fixed
cff_parse_fixed(CFF_Parser parser,FT_Byte ** d)511   cff_parse_fixed( CFF_Parser  parser,
512                    FT_Byte**   d )
513   {
514     return do_fixed( parser, d, 0 );
515   }
516 
517 
518   /* read a floating point number, either integer or real, */
519   /* but return `10^scaling' times the number read in      */
520   static FT_Fixed
cff_parse_fixed_scaled(CFF_Parser parser,FT_Byte ** d,FT_Long scaling)521   cff_parse_fixed_scaled( CFF_Parser  parser,
522                           FT_Byte**   d,
523                           FT_Long     scaling )
524   {
525     return do_fixed( parser, d, scaling );
526   }
527 
528 
529   /* read a floating point number, either integer or real,     */
530   /* and return it as precise as possible -- `scaling' returns */
531   /* the scaling factor (as a power of 10)                     */
532   static FT_Fixed
cff_parse_fixed_dynamic(CFF_Parser parser,FT_Byte ** d,FT_Long * scaling)533   cff_parse_fixed_dynamic( CFF_Parser  parser,
534                            FT_Byte**   d,
535                            FT_Long*    scaling )
536   {
537     FT_ASSERT( scaling );
538 
539     if ( **d == 30 )
540       return cff_parse_real( *d, parser->limit, 0, scaling );
541     else
542     {
543       FT_Long  number;
544       FT_Int   integer_length;
545 
546 
547       number = cff_parse_integer( d[0], d[1] );
548 
549       if ( number > 0x7FFFL )
550       {
551         for ( integer_length = 5; integer_length < 10; integer_length++ )
552           if ( number < power_tens[integer_length] )
553             break;
554 
555         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
556         {
557           *scaling = integer_length - 4;
558           return FT_DivFix( number, power_tens[integer_length - 4] );
559         }
560         else
561         {
562           *scaling = integer_length - 5;
563           return FT_DivFix( number, power_tens[integer_length - 5] );
564         }
565       }
566       else
567       {
568         *scaling = 0;
569         return (FT_Long)( (FT_ULong)number << 16 );
570       }
571     }
572   }
573 
574 
575   static FT_Error
cff_parse_font_matrix(CFF_Parser parser)576   cff_parse_font_matrix( CFF_Parser  parser )
577   {
578     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
579     FT_Matrix*       matrix = &dict->font_matrix;
580     FT_Vector*       offset = &dict->font_offset;
581     FT_ULong*        upm    = &dict->units_per_em;
582     FT_Byte**        data   = parser->stack;
583     FT_Error         error  = FT_ERR( Stack_Underflow );
584 
585 
586     if ( parser->top >= parser->stack + 6 )
587     {
588       FT_Fixed  values[6];
589       FT_Long   scalings[6];
590 
591       FT_Long  min_scaling, max_scaling;
592       int      i;
593 
594 
595       error = FT_Err_Ok;
596 
597       dict->has_font_matrix = TRUE;
598 
599       /* We expect a well-formed font matrix, this is, the matrix elements */
600       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
601       /* loss of precision, we use the magnitude of the largest matrix     */
602       /* element to scale all other elements.  The scaling factor is then  */
603       /* contained in the `units_per_em' value.                            */
604 
605       max_scaling = FT_LONG_MIN;
606       min_scaling = FT_LONG_MAX;
607 
608       for ( i = 0; i < 6; i++ )
609       {
610         values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
611         if ( values[i] )
612         {
613           if ( scalings[i] > max_scaling )
614             max_scaling = scalings[i];
615           if ( scalings[i] < min_scaling )
616             min_scaling = scalings[i];
617         }
618       }
619 
620       if ( max_scaling < -9                  ||
621            max_scaling > 0                   ||
622            ( max_scaling - min_scaling ) < 0 ||
623            ( max_scaling - min_scaling ) > 9 )
624       {
625         /* Return default matrix in case of unlikely values. */
626 
627         FT_TRACE1(( "cff_parse_font_matrix:"
628                     " strange scaling values (minimum %d, maximum %d),\n"
629                     "                      "
630                     " using default matrix\n", min_scaling, max_scaling ));
631 
632         matrix->xx = 0x10000L;
633         matrix->yx = 0;
634         matrix->xy = 0;
635         matrix->yy = 0x10000L;
636         offset->x  = 0;
637         offset->y  = 0;
638         *upm       = 1;
639 
640         goto Exit;
641       }
642 
643       for ( i = 0; i < 6; i++ )
644       {
645         FT_Fixed  value = values[i];
646         FT_Long   divisor, half_divisor;
647 
648 
649         if ( !value )
650           continue;
651 
652         divisor      = power_tens[max_scaling - scalings[i]];
653         half_divisor = divisor >> 1;
654 
655         if ( value < 0 )
656         {
657           if ( FT_LONG_MIN + half_divisor < value )
658             values[i] = ( value - half_divisor ) / divisor;
659           else
660             values[i] = FT_LONG_MIN / divisor;
661         }
662         else
663         {
664           if ( FT_LONG_MAX - half_divisor > value )
665             values[i] = ( value + half_divisor ) / divisor;
666           else
667             values[i] = FT_LONG_MAX / divisor;
668         }
669       }
670 
671       matrix->xx = values[0];
672       matrix->yx = values[1];
673       matrix->xy = values[2];
674       matrix->yy = values[3];
675       offset->x  = values[4];
676       offset->y  = values[5];
677 
678       *upm = (FT_ULong)power_tens[-max_scaling];
679 
680       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
681                   (double)matrix->xx / *upm / 65536,
682                   (double)matrix->xy / *upm / 65536,
683                   (double)matrix->yx / *upm / 65536,
684                   (double)matrix->yy / *upm / 65536,
685                   (double)offset->x  / *upm / 65536,
686                   (double)offset->y  / *upm / 65536 ));
687     }
688 
689   Exit:
690     return error;
691   }
692 
693 
694   static FT_Error
cff_parse_font_bbox(CFF_Parser parser)695   cff_parse_font_bbox( CFF_Parser  parser )
696   {
697     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
698     FT_BBox*         bbox = &dict->font_bbox;
699     FT_Byte**        data = parser->stack;
700     FT_Error         error;
701 
702 
703     error = FT_ERR( Stack_Underflow );
704 
705     if ( parser->top >= parser->stack + 4 )
706     {
707       bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
708       bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
709       bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
710       bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
711       error = FT_Err_Ok;
712 
713       FT_TRACE4(( " [%d %d %d %d]\n",
714                   bbox->xMin / 65536,
715                   bbox->yMin / 65536,
716                   bbox->xMax / 65536,
717                   bbox->yMax / 65536 ));
718     }
719 
720     return error;
721   }
722 
723 
724   static FT_Error
cff_parse_private_dict(CFF_Parser parser)725   cff_parse_private_dict( CFF_Parser  parser )
726   {
727     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
728     FT_Byte**        data = parser->stack;
729     FT_Error         error;
730 
731 
732     error = FT_ERR( Stack_Underflow );
733 
734     if ( parser->top >= parser->stack + 2 )
735     {
736       FT_Long  tmp;
737 
738 
739       tmp = cff_parse_num( parser, data++ );
740       if ( tmp < 0 )
741       {
742         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
743         error = FT_THROW( Invalid_File_Format );
744         goto Fail;
745       }
746       dict->private_size = (FT_ULong)tmp;
747 
748       tmp = cff_parse_num( parser, data );
749       if ( tmp < 0 )
750       {
751         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
752         error = FT_THROW( Invalid_File_Format );
753         goto Fail;
754       }
755       dict->private_offset = (FT_ULong)tmp;
756 
757       FT_TRACE4(( " %lu %lu\n",
758                   dict->private_size, dict->private_offset ));
759 
760       error = FT_Err_Ok;
761     }
762 
763   Fail:
764     return error;
765   }
766 
767 
768   /* The `MultipleMaster' operator comes before any  */
769   /* top DICT operators that contain T2 charstrings. */
770 
771   static FT_Error
cff_parse_multiple_master(CFF_Parser parser)772   cff_parse_multiple_master( CFF_Parser  parser )
773   {
774     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
775     FT_Error         error;
776 
777 
778 #ifdef FT_DEBUG_LEVEL_TRACE
779     /* beautify tracing message */
780     if ( ft_trace_levels[FT_COMPONENT] < 4 )
781       FT_TRACE1(( "Multiple Master CFFs not supported yet,"
782                   " handling first master design only\n" ));
783     else
784       FT_TRACE1(( " (not supported yet,"
785                   " handling first master design only)\n" ));
786 #endif
787 
788     error = FT_ERR( Stack_Underflow );
789 
790     /* currently, we handle only the first argument */
791     if ( parser->top >= parser->stack + 5 )
792     {
793       FT_Long  num_designs = cff_parse_num( parser, parser->stack );
794 
795 
796       if ( num_designs > 16 || num_designs < 2 )
797       {
798         FT_ERROR(( "cff_parse_multiple_master:"
799                    " Invalid number of designs\n" ));
800         error = FT_THROW( Invalid_File_Format );
801       }
802       else
803       {
804         dict->num_designs   = (FT_UShort)num_designs;
805         dict->num_axes      = (FT_UShort)( parser->top - parser->stack - 4 );
806 
807         parser->num_designs = dict->num_designs;
808         parser->num_axes    = dict->num_axes;
809 
810         error = FT_Err_Ok;
811       }
812     }
813 
814     return error;
815   }
816 
817 
818   static FT_Error
cff_parse_cid_ros(CFF_Parser parser)819   cff_parse_cid_ros( CFF_Parser  parser )
820   {
821     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
822     FT_Byte**        data = parser->stack;
823     FT_Error         error;
824 
825 
826     error = FT_ERR( Stack_Underflow );
827 
828     if ( parser->top >= parser->stack + 3 )
829     {
830       dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
831       dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
832       if ( **data == 30 )
833         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
834       dict->cid_supplement = cff_parse_num( parser, data );
835       if ( dict->cid_supplement < 0 )
836         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
837                    dict->cid_supplement ));
838       error = FT_Err_Ok;
839 
840       FT_TRACE4(( " %d %d %d\n",
841                   dict->cid_registry,
842                   dict->cid_ordering,
843                   dict->cid_supplement ));
844     }
845 
846     return error;
847   }
848 
849 
850   static FT_Error
cff_parse_vsindex(CFF_Parser parser)851   cff_parse_vsindex( CFF_Parser  parser )
852   {
853     /* vsindex operator can only be used in a Private DICT */
854     CFF_Private  priv = (CFF_Private)parser->object;
855     FT_Byte**    data = parser->stack;
856     CFF_Blend    blend;
857     FT_Error     error;
858 
859 
860     if ( !priv || !priv->subfont )
861     {
862       error = FT_THROW( Invalid_File_Format );
863       goto Exit;
864     }
865 
866     blend = &priv->subfont->blend;
867 
868     if ( blend->usedBV )
869     {
870       FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
871       error = FT_THROW( Syntax_Error );
872       goto Exit;
873     }
874 
875     priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
876 
877     FT_TRACE4(( " %d\n", priv->vsindex ));
878 
879     error = FT_Err_Ok;
880 
881   Exit:
882     return error;
883   }
884 
885 
886   static FT_Error
cff_parse_blend(CFF_Parser parser)887   cff_parse_blend( CFF_Parser  parser )
888   {
889     /* blend operator can only be used in a Private DICT */
890     CFF_Private  priv = (CFF_Private)parser->object;
891     CFF_SubFont  subFont;
892     CFF_Blend    blend;
893     FT_UInt      numBlends;
894     FT_Error     error;
895 
896 
897     error = FT_ERR( Stack_Underflow );
898 
899     if ( !priv || !priv->subfont )
900     {
901       error = FT_THROW( Invalid_File_Format );
902       goto Exit;
903     }
904 
905     subFont = priv->subfont;
906     blend   = &subFont->blend;
907 
908     if ( cff_blend_check_vector( blend,
909                                  priv->vsindex,
910                                  subFont->lenNDV,
911                                  subFont->NDV ) )
912     {
913       error = cff_blend_build_vector( blend,
914                                       priv->vsindex,
915                                       subFont->lenNDV,
916                                       subFont->NDV );
917       if ( error )
918         goto Exit;
919     }
920 
921     numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
922     if ( numBlends > parser->stackSize )
923     {
924       FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
925       error = FT_THROW( Invalid_File_Format );
926       goto Exit;
927     }
928 
929     FT_TRACE4(( "   %d values blended\n", numBlends ));
930 
931     error = cff_blend_doBlend( subFont, parser, numBlends );
932 
933     blend->usedBV = TRUE;
934 
935   Exit:
936     return error;
937   }
938 
939 
940   /* maxstack operator increases parser and operand stacks for CFF2 */
941   static FT_Error
cff_parse_maxstack(CFF_Parser parser)942   cff_parse_maxstack( CFF_Parser  parser )
943   {
944     /* maxstack operator can only be used in a Top DICT */
945     CFF_FontRecDict  dict  = (CFF_FontRecDict)parser->object;
946     FT_Byte**        data  = parser->stack;
947     FT_Error         error = FT_Err_Ok;
948 
949 
950     if ( !dict )
951     {
952       error = FT_THROW( Invalid_File_Format );
953       goto Exit;
954     }
955 
956     dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
957     if ( dict->maxstack > CFF2_MAX_STACK )
958       dict->maxstack = CFF2_MAX_STACK;
959     if ( dict->maxstack < CFF2_DEFAULT_STACK )
960       dict->maxstack = CFF2_DEFAULT_STACK;
961 
962     FT_TRACE4(( " %d\n", dict->maxstack ));
963 
964   Exit:
965     return error;
966   }
967 
968 
969 #define CFF_FIELD_NUM( code, name, id )             \
970           CFF_FIELD( code, name, id, cff_kind_num )
971 #define CFF_FIELD_FIXED( code, name, id )             \
972           CFF_FIELD( code, name, id, cff_kind_fixed )
973 #define CFF_FIELD_FIXED_1000( code, name, id )                 \
974           CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
975 #define CFF_FIELD_STRING( code, name, id )             \
976           CFF_FIELD( code, name, id, cff_kind_string )
977 #define CFF_FIELD_BOOL( code, name, id )             \
978           CFF_FIELD( code, name, id, cff_kind_bool )
979 
980 
981 #ifndef FT_CONFIG_OPTION_PIC
982 
983 
984 #undef  CFF_FIELD
985 #undef  CFF_FIELD_DELTA
986 
987 
988 #ifndef FT_DEBUG_LEVEL_TRACE
989 
990 
991 #define CFF_FIELD_CALLBACK( code, name, id ) \
992           {                                  \
993             cff_kind_callback,               \
994             code | CFFCODE,                  \
995             0, 0,                            \
996             cff_parse_ ## name,              \
997             0, 0                             \
998           },
999 
1000 #define CFF_FIELD_BLEND( code, id ) \
1001           {                         \
1002             cff_kind_blend,         \
1003             code | CFFCODE,         \
1004             0, 0,                   \
1005             cff_parse_blend,        \
1006             0, 0                    \
1007           },
1008 
1009 #define CFF_FIELD( code, name, id, kind ) \
1010           {                               \
1011             kind,                         \
1012             code | CFFCODE,               \
1013             FT_FIELD_OFFSET( name ),      \
1014             FT_FIELD_SIZE( name ),        \
1015             0, 0, 0                       \
1016           },
1017 
1018 #define CFF_FIELD_DELTA( code, name, max, id ) \
1019           {                                    \
1020             cff_kind_delta,                    \
1021             code | CFFCODE,                    \
1022             FT_FIELD_OFFSET( name ),           \
1023             FT_FIELD_SIZE_DELTA( name ),       \
1024             0,                                 \
1025             max,                               \
1026             FT_FIELD_OFFSET( num_ ## name )    \
1027           },
1028 
1029   static const CFF_Field_Handler  cff_field_handlers[] =
1030   {
1031 
1032 #include "cfftoken.h"
1033 
1034     { 0, 0, 0, 0, 0, 0, 0 }
1035   };
1036 
1037 
1038 #else /* FT_DEBUG_LEVEL_TRACE */
1039 
1040 
1041 
1042 #define CFF_FIELD_CALLBACK( code, name, id ) \
1043           {                                  \
1044             cff_kind_callback,               \
1045             code | CFFCODE,                  \
1046             0, 0,                            \
1047             cff_parse_ ## name,              \
1048             0, 0,                            \
1049             id                               \
1050           },
1051 
1052 #define CFF_FIELD_BLEND( code, id ) \
1053           {                         \
1054             cff_kind_blend,         \
1055             code | CFFCODE,         \
1056             0, 0,                   \
1057             cff_parse_blend,        \
1058             0, 0,                   \
1059             id                      \
1060           },
1061 
1062 #define CFF_FIELD( code, name, id, kind ) \
1063           {                               \
1064             kind,                         \
1065             code | CFFCODE,               \
1066             FT_FIELD_OFFSET( name ),      \
1067             FT_FIELD_SIZE( name ),        \
1068             0, 0, 0,                      \
1069             id                            \
1070           },
1071 
1072 #define CFF_FIELD_DELTA( code, name, max, id ) \
1073           {                                    \
1074             cff_kind_delta,                    \
1075             code | CFFCODE,                    \
1076             FT_FIELD_OFFSET( name ),           \
1077             FT_FIELD_SIZE_DELTA( name ),       \
1078             0,                                 \
1079             max,                               \
1080             FT_FIELD_OFFSET( num_ ## name ),   \
1081             id                                 \
1082           },
1083 
1084   static const CFF_Field_Handler  cff_field_handlers[] =
1085   {
1086 
1087 #include "cfftoken.h"
1088 
1089     { 0, 0, 0, 0, 0, 0, 0, 0 }
1090   };
1091 
1092 
1093 #endif /* FT_DEBUG_LEVEL_TRACE */
1094 
1095 
1096 #else /* FT_CONFIG_OPTION_PIC */
1097 
1098 
1099   void
FT_Destroy_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler * clazz)1100   FT_Destroy_Class_cff_field_handlers( FT_Library          library,
1101                                        CFF_Field_Handler*  clazz )
1102   {
1103     FT_Memory  memory = library->memory;
1104 
1105 
1106     if ( clazz )
1107       FT_FREE( clazz );
1108   }
1109 
1110 
1111   FT_Error
FT_Create_Class_cff_field_handlers(FT_Library library,CFF_Field_Handler ** output_class)1112   FT_Create_Class_cff_field_handlers( FT_Library           library,
1113                                       CFF_Field_Handler**  output_class )
1114   {
1115     CFF_Field_Handler*  clazz  = NULL;
1116     FT_Error            error;
1117     FT_Memory           memory = library->memory;
1118 
1119     int  i = 0;
1120 
1121 
1122 #undef CFF_FIELD
1123 #define CFF_FIELD( code, name, id, kind ) i++;
1124 #undef CFF_FIELD_DELTA
1125 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
1126 #undef CFF_FIELD_CALLBACK
1127 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
1128 #undef CFF_FIELD_BLEND
1129 #define CFF_FIELD_BLEND( code, id ) i++;
1130 
1131 #include "cfftoken.h"
1132 
1133     i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
1134 
1135     if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
1136       return error;
1137 
1138     i = 0;
1139 
1140 
1141 #ifndef FT_DEBUG_LEVEL_TRACE
1142 
1143 
1144 #undef CFF_FIELD_CALLBACK
1145 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
1146           clazz[i].kind         = cff_kind_callback;   \
1147           clazz[i].code         = code_ | CFFCODE;     \
1148           clazz[i].offset       = 0;                   \
1149           clazz[i].size         = 0;                   \
1150           clazz[i].reader       = cff_parse_ ## name_; \
1151           clazz[i].array_max    = 0;                   \
1152           clazz[i].count_offset = 0;                   \
1153           i++;
1154 
1155 #undef  CFF_FIELD
1156 #define CFF_FIELD( code_, name_, id_, kind_ )               \
1157           clazz[i].kind         = kind_;                    \
1158           clazz[i].code         = code_ | CFFCODE;          \
1159           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
1160           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
1161           clazz[i].reader       = 0;                        \
1162           clazz[i].array_max    = 0;                        \
1163           clazz[i].count_offset = 0;                        \
1164           i++;                                              \
1165 
1166 #undef  CFF_FIELD_DELTA
1167 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
1168           clazz[i].kind         = cff_kind_delta;                   \
1169           clazz[i].code         = code_ | CFFCODE;                  \
1170           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
1171           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
1172           clazz[i].reader       = 0;                                \
1173           clazz[i].array_max    = max_;                             \
1174           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
1175           i++;
1176 
1177 #undef  CFF_FIELD_BLEND
1178 #define CFF_FIELD_BLEND( code_, id_ )              \
1179           clazz[i].kind         = cff_kind_blend;  \
1180           clazz[i].code         = code_ | CFFCODE; \
1181           clazz[i].offset       = 0;               \
1182           clazz[i].size         = 0;               \
1183           clazz[i].reader       = cff_parse_blend; \
1184           clazz[i].array_max    = 0;               \
1185           clazz[i].count_offset = 0;               \
1186           i++;
1187 
1188 #include "cfftoken.h"
1189 
1190     clazz[i].kind         = 0;
1191     clazz[i].code         = 0;
1192     clazz[i].offset       = 0;
1193     clazz[i].size         = 0;
1194     clazz[i].reader       = 0;
1195     clazz[i].array_max    = 0;
1196     clazz[i].count_offset = 0;
1197 
1198 
1199 #else /* FT_DEBUG_LEVEL_TRACE */
1200 
1201 
1202 #undef CFF_FIELD_CALLBACK
1203 #define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
1204           clazz[i].kind         = cff_kind_callback;   \
1205           clazz[i].code         = code_ | CFFCODE;     \
1206           clazz[i].offset       = 0;                   \
1207           clazz[i].size         = 0;                   \
1208           clazz[i].reader       = cff_parse_ ## name_; \
1209           clazz[i].array_max    = 0;                   \
1210           clazz[i].count_offset = 0;                   \
1211           clazz[i].id           = id_;                 \
1212           i++;
1213 
1214 #undef  CFF_FIELD
1215 #define CFF_FIELD( code_, name_, id_, kind_ )               \
1216           clazz[i].kind         = kind_;                    \
1217           clazz[i].code         = code_ | CFFCODE;          \
1218           clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
1219           clazz[i].size         = FT_FIELD_SIZE( name_ );   \
1220           clazz[i].reader       = 0;                        \
1221           clazz[i].array_max    = 0;                        \
1222           clazz[i].count_offset = 0;                        \
1223           clazz[i].id           = id_;                      \
1224           i++;                                              \
1225 
1226 #undef  CFF_FIELD_DELTA
1227 #define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
1228           clazz[i].kind         = cff_kind_delta;                   \
1229           clazz[i].code         = code_ | CFFCODE;                  \
1230           clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
1231           clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
1232           clazz[i].reader       = 0;                                \
1233           clazz[i].array_max    = max_;                             \
1234           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
1235           clazz[i].id           = id_;                              \
1236           i++;
1237 
1238 #undef  CFF_FIELD_BLEND
1239 #define CFF_FIELD_BLEND( code_, id_ )              \
1240           clazz[i].kind         = cff_kind_blend;  \
1241           clazz[i].code         = code_ | CFFCODE; \
1242           clazz[i].offset       = 0;               \
1243           clazz[i].size         = 0;               \
1244           clazz[i].reader       = cff_parse_blend; \
1245           clazz[i].array_max    = 0;               \
1246           clazz[i].count_offset = 0;               \
1247           clazz[i].id           = id_;             \
1248           i++;
1249 
1250 #include "cfftoken.h"
1251 
1252     clazz[i].kind         = 0;
1253     clazz[i].code         = 0;
1254     clazz[i].offset       = 0;
1255     clazz[i].size         = 0;
1256     clazz[i].reader       = 0;
1257     clazz[i].array_max    = 0;
1258     clazz[i].count_offset = 0;
1259     clazz[i].id           = 0;
1260 
1261 
1262 #endif /* FT_DEBUG_LEVEL_TRACE */
1263 
1264 
1265     *output_class = clazz;
1266 
1267     return FT_Err_Ok;
1268   }
1269 
1270 
1271 #endif /* FT_CONFIG_OPTION_PIC */
1272 
1273 
1274   FT_LOCAL_DEF( FT_Error )
cff_parser_run(CFF_Parser parser,FT_Byte * start,FT_Byte * limit)1275   cff_parser_run( CFF_Parser  parser,
1276                   FT_Byte*    start,
1277                   FT_Byte*    limit )
1278   {
1279     FT_Byte*    p       = start;
1280     FT_Error    error   = FT_Err_Ok;
1281     FT_Library  library = parser->library;
1282     FT_UNUSED( library );
1283 
1284 
1285     parser->top    = parser->stack;
1286     parser->start  = start;
1287     parser->limit  = limit;
1288     parser->cursor = start;
1289 
1290     while ( p < limit )
1291     {
1292       FT_UInt  v = *p;
1293 
1294       /* Opcode 31 is legacy MM T2 operator, not a number.      */
1295       /* Opcode 255 is reserved and should not appear in fonts; */
1296       /* it is used internally for CFF2 blends.                 */
1297       if ( v >= 27 && v != 31 && v != 255 )
1298       {
1299         /* it's a number; we will push its position on the stack */
1300         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1301           goto Stack_Overflow;
1302 
1303         *parser->top++ = p;
1304 
1305         /* now, skip it */
1306         if ( v == 30 )
1307         {
1308           /* skip real number */
1309           p++;
1310           for (;;)
1311           {
1312             /* An unterminated floating point number at the */
1313             /* end of a dictionary is invalid but harmless. */
1314             if ( p >= limit )
1315               goto Exit;
1316             v = p[0] >> 4;
1317             if ( v == 15 )
1318               break;
1319             v = p[0] & 0xF;
1320             if ( v == 15 )
1321               break;
1322             p++;
1323           }
1324         }
1325         else if ( v == 28 )
1326           p += 2;
1327         else if ( v == 29 )
1328           p += 4;
1329         else if ( v > 246 )
1330           p += 1;
1331       }
1332 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1333       else if ( v == 31 )
1334       {
1335         /* a Type 2 charstring */
1336 
1337         CFF_Decoder  decoder;
1338         CFF_FontRec  cff_rec;
1339         FT_Byte*     charstring_base;
1340         FT_ULong     charstring_len;
1341 
1342         FT_Fixed*  stack;
1343         FT_Byte*   q;
1344 
1345 
1346         charstring_base = ++p;
1347 
1348         /* search `endchar' operator */
1349         for (;;)
1350         {
1351           if ( p >= limit )
1352             goto Exit;
1353           if ( *p == 14 )
1354             break;
1355           p++;
1356         }
1357 
1358         charstring_len = (FT_ULong)( p - charstring_base ) + 1;
1359 
1360         /* construct CFF_Decoder object */
1361         FT_ZERO( &decoder );
1362         FT_ZERO( &cff_rec );
1363 
1364         cff_rec.top_font.font_dict.num_designs = parser->num_designs;
1365         cff_rec.top_font.font_dict.num_axes    = parser->num_axes;
1366         decoder.cff                            = &cff_rec;
1367 
1368         error = cff_decoder_parse_charstrings( &decoder,
1369                                                charstring_base,
1370                                                charstring_len,
1371                                                1 );
1372 
1373         /* Now copy the stack data in the temporary decoder object,    */
1374         /* converting it back to charstring number representations     */
1375         /* (this is ugly, I know).                                     */
1376         /*                                                             */
1377         /* We overwrite the original top DICT charstring under the     */
1378         /* assumption that the charstring representation of the result */
1379         /* of `cff_decoder_parse_charstrings' is shorter, which should */
1380         /* be always true.                                             */
1381 
1382         q     = charstring_base - 1;
1383         stack = decoder.stack;
1384 
1385         while ( stack < decoder.top )
1386         {
1387           FT_ULong  num;
1388           FT_Bool   neg;
1389 
1390 
1391           if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1392             goto Stack_Overflow;
1393 
1394           *parser->top++ = q;
1395 
1396           if ( *stack < 0 )
1397           {
1398             num = (FT_ULong)-*stack;
1399             neg = 1;
1400           }
1401           else
1402           {
1403             num = (FT_ULong)*stack;
1404             neg = 0;
1405           }
1406 
1407           if ( num & 0xFFFFU )
1408           {
1409             if ( neg )
1410               num = (FT_ULong)-num;
1411 
1412             *q++ = 255;
1413             *q++ = ( num & 0xFF000000U ) >> 24;
1414             *q++ = ( num & 0x00FF0000U ) >> 16;
1415             *q++ = ( num & 0x0000FF00U ) >>  8;
1416             *q++ =   num & 0x000000FFU;
1417           }
1418           else
1419           {
1420             num >>= 16;
1421 
1422             if ( neg )
1423             {
1424               if ( num <= 107 )
1425                 *q++ = (FT_Byte)( 139 - num );
1426               else if ( num <= 1131 )
1427               {
1428                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
1429                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1430               }
1431               else
1432               {
1433                 num = (FT_ULong)-num;
1434 
1435                 *q++ = 28;
1436                 *q++ = (FT_Byte)( num >> 8 );
1437                 *q++ = (FT_Byte)( num & 0xFF );
1438               }
1439             }
1440             else
1441             {
1442               if ( num <= 107 )
1443                 *q++ = (FT_Byte)( num + 139 );
1444               else if ( num <= 1131 )
1445               {
1446                 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
1447                 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1448               }
1449               else
1450               {
1451                 *q++ = 28;
1452                 *q++ = (FT_Byte)( num >> 8 );
1453                 *q++ = (FT_Byte)( num & 0xFF );
1454               }
1455             }
1456           }
1457 
1458           stack++;
1459         }
1460       }
1461 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
1462       else
1463       {
1464         /* This is not a number, hence it's an operator.  Compute its code */
1465         /* and look for it in our current list.                            */
1466 
1467         FT_UInt                   code;
1468         FT_UInt                   num_args;
1469         const CFF_Field_Handler*  field;
1470 
1471 
1472         if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1473           goto Stack_Overflow;
1474 
1475         num_args     = (FT_UInt)( parser->top - parser->stack );
1476         *parser->top = p;
1477         code         = v;
1478 
1479         if ( v == 12 )
1480         {
1481           /* two byte operator */
1482           p++;
1483           if ( p >= limit )
1484             goto Syntax_Error;
1485 
1486           code = 0x100 | p[0];
1487         }
1488         code = code | parser->object_code;
1489 
1490         for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
1491         {
1492           if ( field->code == (FT_Int)code )
1493           {
1494             /* we found our field's handler; read it */
1495             FT_Long   val;
1496             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
1497 
1498 
1499 #ifdef FT_DEBUG_LEVEL_TRACE
1500             FT_TRACE4(( "  %s", field->id ));
1501 #endif
1502 
1503             /* check that we have enough arguments -- except for */
1504             /* delta encoded arrays, which can be empty          */
1505             if ( field->kind != cff_kind_delta && num_args < 1 )
1506               goto Stack_Underflow;
1507 
1508             switch ( field->kind )
1509             {
1510             case cff_kind_bool:
1511             case cff_kind_string:
1512             case cff_kind_num:
1513               val = cff_parse_num( parser, parser->stack );
1514               goto Store_Number;
1515 
1516             case cff_kind_fixed:
1517               val = cff_parse_fixed( parser, parser->stack );
1518               goto Store_Number;
1519 
1520             case cff_kind_fixed_thousand:
1521               val = cff_parse_fixed_scaled( parser, parser->stack, 3 );
1522 
1523             Store_Number:
1524               switch ( field->size )
1525               {
1526               case (8 / FT_CHAR_BIT):
1527                 *(FT_Byte*)q = (FT_Byte)val;
1528                 break;
1529 
1530               case (16 / FT_CHAR_BIT):
1531                 *(FT_Short*)q = (FT_Short)val;
1532                 break;
1533 
1534               case (32 / FT_CHAR_BIT):
1535                 *(FT_Int32*)q = (FT_Int)val;
1536                 break;
1537 
1538               default:  /* for 64-bit systems */
1539                 *(FT_Long*)q = val;
1540               }
1541 
1542 #ifdef FT_DEBUG_LEVEL_TRACE
1543               switch ( field->kind )
1544               {
1545               case cff_kind_bool:
1546                 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1547                 break;
1548 
1549               case cff_kind_string:
1550                 FT_TRACE4(( " %ld (SID)\n", val ));
1551                 break;
1552 
1553               case cff_kind_num:
1554                 FT_TRACE4(( " %ld\n", val ));
1555                 break;
1556 
1557               case cff_kind_fixed:
1558                 FT_TRACE4(( " %f\n", (double)val / 65536 ));
1559                 break;
1560 
1561               case cff_kind_fixed_thousand:
1562                 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1563 
1564               default:
1565                 ; /* never reached */
1566               }
1567 #endif
1568 
1569               break;
1570 
1571             case cff_kind_delta:
1572               {
1573                 FT_Byte*   qcount = (FT_Byte*)parser->object +
1574                                       field->count_offset;
1575 
1576                 FT_Byte**  data = parser->stack;
1577 
1578 
1579                 if ( num_args > field->array_max )
1580                   num_args = field->array_max;
1581 
1582                 FT_TRACE4(( " [" ));
1583 
1584                 /* store count */
1585                 *qcount = (FT_Byte)num_args;
1586 
1587                 val = 0;
1588                 while ( num_args > 0 )
1589                 {
1590                   val += cff_parse_num( parser, data++ );
1591                   switch ( field->size )
1592                   {
1593                   case (8 / FT_CHAR_BIT):
1594                     *(FT_Byte*)q = (FT_Byte)val;
1595                     break;
1596 
1597                   case (16 / FT_CHAR_BIT):
1598                     *(FT_Short*)q = (FT_Short)val;
1599                     break;
1600 
1601                   case (32 / FT_CHAR_BIT):
1602                     *(FT_Int32*)q = (FT_Int)val;
1603                     break;
1604 
1605                   default:  /* for 64-bit systems */
1606                     *(FT_Long*)q = val;
1607                   }
1608 
1609                   FT_TRACE4(( " %ld", val ));
1610 
1611                   q += field->size;
1612                   num_args--;
1613                 }
1614 
1615                 FT_TRACE4(( "]\n" ));
1616               }
1617               break;
1618 
1619             default:  /* callback or blend */
1620               error = field->reader( parser );
1621               if ( error )
1622                 goto Exit;
1623             }
1624             goto Found;
1625           }
1626         }
1627 
1628         /* this is an unknown operator, or it is unsupported; */
1629         /* we will ignore it for now.                         */
1630 
1631       Found:
1632         /* clear stack */
1633         /* TODO: could clear blend stack here,       */
1634         /*       but we don't have access to subFont */
1635         if ( field->kind != cff_kind_blend )
1636           parser->top = parser->stack;
1637       }
1638       p++;
1639     }
1640 
1641   Exit:
1642     return error;
1643 
1644   Stack_Overflow:
1645     error = FT_THROW( Invalid_Argument );
1646     goto Exit;
1647 
1648   Stack_Underflow:
1649     error = FT_THROW( Invalid_Argument );
1650     goto Exit;
1651 
1652   Syntax_Error:
1653     error = FT_THROW( Invalid_Argument );
1654     goto Exit;
1655   }
1656 
1657 
1658 /* END */
1659