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