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