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