• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * cffdecode.c
4  *
5  *   PostScript CFF (Type 2) decoding routines (body).
6  *
7  * Copyright 2017-2018 by
8  * David Turner, Robert Wilhelm, and Werner Lemberg.
9  *
10  * This file is part of the FreeType project, and may only be used,
11  * modified, and distributed under the terms of the FreeType project
12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
13  * this file you indicate that you have read the license and
14  * understand and accept it fully.
15  *
16  */
17 
18 
19 #include <ft2build.h>
20 #include FT_FREETYPE_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_SERVICE_H
23 #include FT_SERVICE_CFF_TABLE_LOAD_H
24 
25 #include "cffdecode.h"
26 #include "psobjs.h"
27 
28 #include "psauxerr.h"
29 
30 
31   /**************************************************************************
32    *
33    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
34    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35    * messages during execution.
36    */
37 #undef  FT_COMPONENT
38 #define FT_COMPONENT  trace_cffdecode
39 
40 
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
42 
43   typedef enum  CFF_Operator_
44   {
45     cff_op_unknown = 0,
46 
47     cff_op_rmoveto,
48     cff_op_hmoveto,
49     cff_op_vmoveto,
50 
51     cff_op_rlineto,
52     cff_op_hlineto,
53     cff_op_vlineto,
54 
55     cff_op_rrcurveto,
56     cff_op_hhcurveto,
57     cff_op_hvcurveto,
58     cff_op_rcurveline,
59     cff_op_rlinecurve,
60     cff_op_vhcurveto,
61     cff_op_vvcurveto,
62 
63     cff_op_flex,
64     cff_op_hflex,
65     cff_op_hflex1,
66     cff_op_flex1,
67 
68     cff_op_endchar,
69 
70     cff_op_hstem,
71     cff_op_vstem,
72     cff_op_hstemhm,
73     cff_op_vstemhm,
74 
75     cff_op_hintmask,
76     cff_op_cntrmask,
77     cff_op_dotsection,  /* deprecated, acts as no-op */
78 
79     cff_op_abs,
80     cff_op_add,
81     cff_op_sub,
82     cff_op_div,
83     cff_op_neg,
84     cff_op_random,
85     cff_op_mul,
86     cff_op_sqrt,
87 
88     cff_op_blend,
89 
90     cff_op_drop,
91     cff_op_exch,
92     cff_op_index,
93     cff_op_roll,
94     cff_op_dup,
95 
96     cff_op_put,
97     cff_op_get,
98     cff_op_store,
99     cff_op_load,
100 
101     cff_op_and,
102     cff_op_or,
103     cff_op_not,
104     cff_op_eq,
105     cff_op_ifelse,
106 
107     cff_op_callsubr,
108     cff_op_callgsubr,
109     cff_op_return,
110 
111     /* Type 1 opcodes: invalid but seen in real life */
112     cff_op_hsbw,
113     cff_op_closepath,
114     cff_op_callothersubr,
115     cff_op_pop,
116     cff_op_seac,
117     cff_op_sbw,
118     cff_op_setcurrentpoint,
119 
120     /* do not remove */
121     cff_op_max
122 
123   } CFF_Operator;
124 
125 
126 #define CFF_COUNT_CHECK_WIDTH  0x80
127 #define CFF_COUNT_EXACT        0x40
128 #define CFF_COUNT_CLEAR_STACK  0x20
129 
130   /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are  */
131   /* used for checking the width and requested numbers of arguments    */
132   /* only; they are set to zero afterwards                             */
133 
134   /* the other two flags are informative only and unused currently     */
135 
136   static const FT_Byte  cff_argument_counts[] =
137   {
138     0,  /* unknown */
139 
140     2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
141     1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
142     1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
143 
144     0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
145     0 | CFF_COUNT_CLEAR_STACK,
146     0 | CFF_COUNT_CLEAR_STACK,
147 
148     0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
149     0 | CFF_COUNT_CLEAR_STACK,
150     0 | CFF_COUNT_CLEAR_STACK,
151     0 | CFF_COUNT_CLEAR_STACK,
152     0 | CFF_COUNT_CLEAR_STACK,
153     0 | CFF_COUNT_CLEAR_STACK,
154     0 | CFF_COUNT_CLEAR_STACK,
155 
156     13, /* flex */
157     7,
158     9,
159     11,
160 
161     0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
162 
163     2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
164     2 | CFF_COUNT_CHECK_WIDTH,
165     2 | CFF_COUNT_CHECK_WIDTH,
166     2 | CFF_COUNT_CHECK_WIDTH,
167 
168     0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
169     0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
170     0, /* dotsection */
171 
172     1, /* abs */
173     2,
174     2,
175     2,
176     1,
177     0,
178     2,
179     1,
180 
181     1, /* blend */
182 
183     1, /* drop */
184     2,
185     1,
186     2,
187     1,
188 
189     2, /* put */
190     1,
191     4,
192     3,
193 
194     2, /* and */
195     2,
196     1,
197     2,
198     4,
199 
200     1, /* callsubr */
201     1,
202     0,
203 
204     2, /* hsbw */
205     0,
206     0,
207     0,
208     5, /* seac */
209     4, /* sbw */
210     2  /* setcurrentpoint */
211   };
212 
213 
214   static FT_Error
cff_operator_seac(CFF_Decoder * decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)215   cff_operator_seac( CFF_Decoder*  decoder,
216                      FT_Pos        asb,
217                      FT_Pos        adx,
218                      FT_Pos        ady,
219                      FT_Int        bchar,
220                      FT_Int        achar )
221   {
222     FT_Error      error;
223     CFF_Builder*  builder = &decoder->builder;
224     FT_Int        bchar_index, achar_index;
225     TT_Face       face    = decoder->builder.face;
226     FT_Vector     left_bearing, advance;
227     FT_Byte*      charstring;
228     FT_ULong      charstring_len;
229     FT_Pos        glyph_width;
230 
231 
232     if ( decoder->seac )
233     {
234       FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
235       return FT_THROW( Syntax_Error );
236     }
237 
238     adx += decoder->builder.left_bearing.x;
239     ady += decoder->builder.left_bearing.y;
240 
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
242     /* Incremental fonts don't necessarily have valid charsets.        */
243     /* They use the character code, not the glyph index, in this case. */
244     if ( face->root.internal->incremental_interface )
245     {
246       bchar_index = bchar;
247       achar_index = achar;
248     }
249     else
250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
251     {
252       CFF_Font cff = (CFF_Font)(face->extra.data);
253 
254 
255       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
256       achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
257     }
258 
259     if ( bchar_index < 0 || achar_index < 0 )
260     {
261       FT_ERROR(( "cff_operator_seac:"
262                  " invalid seac character code arguments\n" ));
263       return FT_THROW( Syntax_Error );
264     }
265 
266     /* If we are trying to load a composite glyph, do not load the */
267     /* accent character and return the array of subglyphs.         */
268     if ( builder->no_recurse )
269     {
270       FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;
271       FT_GlyphLoader  loader = glyph->internal->loader;
272       FT_SubGlyph     subg;
273 
274 
275       /* reallocate subglyph array if necessary */
276       error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
277       if ( error )
278         goto Exit;
279 
280       subg = loader->current.subglyphs;
281 
282       /* subglyph 0 = base character */
283       subg->index = bchar_index;
284       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
285                     FT_SUBGLYPH_FLAG_USE_MY_METRICS;
286       subg->arg1  = 0;
287       subg->arg2  = 0;
288       subg++;
289 
290       /* subglyph 1 = accent character */
291       subg->index = achar_index;
292       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
293       subg->arg1  = (FT_Int)( adx >> 16 );
294       subg->arg2  = (FT_Int)( ady >> 16 );
295 
296       /* set up remaining glyph fields */
297       glyph->num_subglyphs = 2;
298       glyph->subglyphs     = loader->base.subglyphs;
299       glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
300 
301       loader->current.num_subglyphs = 2;
302     }
303 
304     FT_GlyphLoader_Prepare( builder->loader );
305 
306     /* First load `bchar' in builder */
307     error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
308                                          &charstring, &charstring_len );
309     if ( !error )
310     {
311       /* the seac operator must not be nested */
312       decoder->seac = TRUE;
313       error = cff_decoder_parse_charstrings( decoder, charstring,
314                                              charstring_len, 0 );
315       decoder->seac = FALSE;
316 
317       decoder->free_glyph_callback( face, &charstring, charstring_len );
318 
319       if ( error )
320         goto Exit;
321     }
322 
323     /* Save the left bearing, advance and glyph width of the base */
324     /* character as they will be erased by the next load.         */
325 
326     left_bearing = builder->left_bearing;
327     advance      = builder->advance;
328     glyph_width  = decoder->glyph_width;
329 
330     builder->left_bearing.x = 0;
331     builder->left_bearing.y = 0;
332 
333     builder->pos_x = adx - asb;
334     builder->pos_y = ady;
335 
336     /* Now load `achar' on top of the base outline. */
337     error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
338                                          &charstring, &charstring_len );
339     if ( !error )
340     {
341       /* the seac operator must not be nested */
342       decoder->seac = TRUE;
343       error = cff_decoder_parse_charstrings( decoder, charstring,
344                                              charstring_len, 0 );
345       decoder->seac = FALSE;
346 
347       decoder->free_glyph_callback( face, &charstring, charstring_len );
348 
349       if ( error )
350         goto Exit;
351     }
352 
353     /* Restore the left side bearing, advance and glyph width */
354     /* of the base character.                                 */
355     builder->left_bearing = left_bearing;
356     builder->advance      = advance;
357     decoder->glyph_width  = glyph_width;
358 
359     builder->pos_x = 0;
360     builder->pos_y = 0;
361 
362   Exit:
363     return error;
364   }
365 
366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
367 
368 
369   /*************************************************************************/
370   /*************************************************************************/
371   /*************************************************************************/
372   /**********                                                      *********/
373   /**********                                                      *********/
374   /**********             GENERIC CHARSTRING PARSING               *********/
375   /**********                                                      *********/
376   /**********                                                      *********/
377   /*************************************************************************/
378   /*************************************************************************/
379   /*************************************************************************/
380 
381   /**************************************************************************
382    *
383    * @Function:
384    *   cff_compute_bias
385    *
386    * @Description:
387    *   Computes the bias value in dependence of the number of glyph
388    *   subroutines.
389    *
390    * @Input:
391    *   in_charstring_type ::
392    *     The `CharstringType' value of the top DICT
393    *     dictionary.
394    *
395    *   num_subrs ::
396    *     The number of glyph subroutines.
397    *
398    * @Return:
399    *   The bias value.
400    */
401   static FT_Int
cff_compute_bias(FT_Int in_charstring_type,FT_UInt num_subrs)402   cff_compute_bias( FT_Int   in_charstring_type,
403                     FT_UInt  num_subrs )
404   {
405     FT_Int  result;
406 
407 
408     if ( in_charstring_type == 1 )
409       result = 0;
410     else if ( num_subrs < 1240 )
411       result = 107;
412     else if ( num_subrs < 33900U )
413       result = 1131;
414     else
415       result = 32768U;
416 
417     return result;
418   }
419 
420 
421   FT_LOCAL_DEF( FT_Int )
cff_lookup_glyph_by_stdcharcode(CFF_Font cff,FT_Int charcode)422   cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,
423                                    FT_Int    charcode )
424   {
425     FT_UInt    n;
426     FT_UShort  glyph_sid;
427 
428     FT_Service_CFFLoad  cffload;
429 
430 
431     /* CID-keyed fonts don't have glyph names */
432     if ( !cff->charset.sids )
433       return -1;
434 
435     /* check range of standard char code */
436     if ( charcode < 0 || charcode > 255 )
437       return -1;
438 
439 #if 0
440     /* retrieve cffload from list of current modules */
441     FT_Service_CFFLoad  cffload;
442 
443 
444     FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
445     if ( !cffload )
446     {
447       FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
448                  " the `cffload' module is not available\n" ));
449       return FT_THROW( Unimplemented_Feature );
450     }
451 #endif
452 
453     cffload = (FT_Service_CFFLoad)cff->cffload;
454 
455     /* Get code to SID mapping from `cff_standard_encoding'. */
456     glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
457 
458     for ( n = 0; n < cff->num_glyphs; n++ )
459     {
460       if ( cff->charset.sids[n] == glyph_sid )
461         return (FT_Int)n;
462     }
463 
464     return -1;
465   }
466 
467 
468 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
469 
470   /**************************************************************************
471    *
472    * @Function:
473    *   cff_decoder_parse_charstrings
474    *
475    * @Description:
476    *   Parses a given Type 2 charstrings program.
477    *
478    * @InOut:
479    *   decoder ::
480    *     The current Type 1 decoder.
481    *
482    * @Input:
483    *   charstring_base ::
484    *     The base of the charstring stream.
485    *
486    *   charstring_len ::
487    *     The length in bytes of the charstring stream.
488    *
489    *   in_dict ::
490    *     Set to 1 if function is called from top or
491    *     private DICT (needed for Multiple Master CFFs).
492    *
493    * @Return:
494    *   FreeType error code.  0 means success.
495    */
496   FT_LOCAL_DEF( FT_Error )
cff_decoder_parse_charstrings(CFF_Decoder * decoder,FT_Byte * charstring_base,FT_ULong charstring_len,FT_Bool in_dict)497   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
498                                  FT_Byte*      charstring_base,
499                                  FT_ULong      charstring_len,
500                                  FT_Bool       in_dict )
501   {
502     FT_Error           error;
503     CFF_Decoder_Zone*  zone;
504     FT_Byte*           ip;
505     FT_Byte*           limit;
506     CFF_Builder*       builder = &decoder->builder;
507     FT_Pos             x, y;
508     FT_Fixed*          stack;
509     FT_Int             charstring_type =
510                          decoder->cff->top_font.font_dict.charstring_type;
511     FT_UShort          num_designs =
512                          decoder->cff->top_font.font_dict.num_designs;
513     FT_UShort          num_axes =
514                          decoder->cff->top_font.font_dict.num_axes;
515 
516     T2_Hints_Funcs  hinter;
517 
518 
519     /* set default width */
520     decoder->num_hints  = 0;
521     decoder->read_width = 1;
522 
523     /* initialize the decoder */
524     decoder->top  = decoder->stack;
525     decoder->zone = decoder->zones;
526     zone          = decoder->zones;
527     stack         = decoder->top;
528 
529     hinter = (T2_Hints_Funcs)builder->hints_funcs;
530 
531     builder->path_begun = 0;
532 
533     zone->base           = charstring_base;
534     limit = zone->limit  = charstring_base + charstring_len;
535     ip    = zone->cursor = zone->base;
536 
537     error = FT_Err_Ok;
538 
539     x = builder->pos_x;
540     y = builder->pos_y;
541 
542     /* begin hints recording session, if any */
543     if ( hinter )
544       hinter->open( hinter->hints );
545 
546     /* now execute loop */
547     while ( ip < limit )
548     {
549       CFF_Operator  op;
550       FT_Byte       v;
551 
552 
553       /*********************************************************************
554        *
555        * Decode operator or operand
556        */
557       v = *ip++;
558       if ( v >= 32 || v == 28 )
559       {
560         FT_Int    shift = 16;
561         FT_Int32  val;
562 
563 
564         /* this is an operand, push it on the stack */
565 
566         /* if we use shifts, all computations are done with unsigned */
567         /* values; the conversion to a signed value is the last step */
568         if ( v == 28 )
569         {
570           if ( ip + 1 >= limit )
571             goto Syntax_Error;
572           val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
573           ip += 2;
574         }
575         else if ( v < 247 )
576           val = (FT_Int32)v - 139;
577         else if ( v < 251 )
578         {
579           if ( ip >= limit )
580             goto Syntax_Error;
581           val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
582         }
583         else if ( v < 255 )
584         {
585           if ( ip >= limit )
586             goto Syntax_Error;
587           val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
588         }
589         else
590         {
591           if ( ip + 3 >= limit )
592             goto Syntax_Error;
593           val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
594                             ( (FT_UInt32)ip[1] << 16 ) |
595                             ( (FT_UInt32)ip[2] <<  8 ) |
596                               (FT_UInt32)ip[3]         );
597           ip += 4;
598           if ( charstring_type == 2 )
599             shift = 0;
600         }
601         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
602           goto Stack_Overflow;
603 
604         val             = (FT_Int32)( (FT_UInt32)val << shift );
605         *decoder->top++ = val;
606 
607 #ifdef FT_DEBUG_LEVEL_TRACE
608         if ( !( val & 0xFFFFL ) )
609           FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
610         else
611           FT_TRACE4(( " %.5f", val / 65536.0 ));
612 #endif
613 
614       }
615       else
616       {
617         /* The specification says that normally arguments are to be taken */
618         /* from the bottom of the stack.  However, this seems not to be   */
619         /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
620         /* arguments similar to a PS interpreter.                         */
621 
622         FT_Fixed*  args     = decoder->top;
623         FT_Int     num_args = (FT_Int)( args - decoder->stack );
624         FT_Int     req_args;
625 
626 
627         /* find operator */
628         op = cff_op_unknown;
629 
630         switch ( v )
631         {
632         case 1:
633           op = cff_op_hstem;
634           break;
635         case 3:
636           op = cff_op_vstem;
637           break;
638         case 4:
639           op = cff_op_vmoveto;
640           break;
641         case 5:
642           op = cff_op_rlineto;
643           break;
644         case 6:
645           op = cff_op_hlineto;
646           break;
647         case 7:
648           op = cff_op_vlineto;
649           break;
650         case 8:
651           op = cff_op_rrcurveto;
652           break;
653         case 9:
654           op = cff_op_closepath;
655           break;
656         case 10:
657           op = cff_op_callsubr;
658           break;
659         case 11:
660           op = cff_op_return;
661           break;
662         case 12:
663           if ( ip >= limit )
664             goto Syntax_Error;
665           v = *ip++;
666 
667           switch ( v )
668           {
669           case 0:
670             op = cff_op_dotsection;
671             break;
672           case 1: /* this is actually the Type1 vstem3 operator */
673             op = cff_op_vstem;
674             break;
675           case 2: /* this is actually the Type1 hstem3 operator */
676             op = cff_op_hstem;
677             break;
678           case 3:
679             op = cff_op_and;
680             break;
681           case 4:
682             op = cff_op_or;
683             break;
684           case 5:
685             op = cff_op_not;
686             break;
687           case 6:
688             op = cff_op_seac;
689             break;
690           case 7:
691             op = cff_op_sbw;
692             break;
693           case 8:
694             op = cff_op_store;
695             break;
696           case 9:
697             op = cff_op_abs;
698             break;
699           case 10:
700             op = cff_op_add;
701             break;
702           case 11:
703             op = cff_op_sub;
704             break;
705           case 12:
706             op = cff_op_div;
707             break;
708           case 13:
709             op = cff_op_load;
710             break;
711           case 14:
712             op = cff_op_neg;
713             break;
714           case 15:
715             op = cff_op_eq;
716             break;
717           case 16:
718             op = cff_op_callothersubr;
719             break;
720           case 17:
721             op = cff_op_pop;
722             break;
723           case 18:
724             op = cff_op_drop;
725             break;
726           case 20:
727             op = cff_op_put;
728             break;
729           case 21:
730             op = cff_op_get;
731             break;
732           case 22:
733             op = cff_op_ifelse;
734             break;
735           case 23:
736             op = cff_op_random;
737             break;
738           case 24:
739             op = cff_op_mul;
740             break;
741           case 26:
742             op = cff_op_sqrt;
743             break;
744           case 27:
745             op = cff_op_dup;
746             break;
747           case 28:
748             op = cff_op_exch;
749             break;
750           case 29:
751             op = cff_op_index;
752             break;
753           case 30:
754             op = cff_op_roll;
755             break;
756           case 33:
757             op = cff_op_setcurrentpoint;
758             break;
759           case 34:
760             op = cff_op_hflex;
761             break;
762           case 35:
763             op = cff_op_flex;
764             break;
765           case 36:
766             op = cff_op_hflex1;
767             break;
768           case 37:
769             op = cff_op_flex1;
770             break;
771           default:
772             FT_TRACE4(( " unknown op (12, %d)\n", v ));
773             break;
774           }
775           break;
776         case 13:
777           op = cff_op_hsbw;
778           break;
779         case 14:
780           op = cff_op_endchar;
781           break;
782         case 16:
783           op = cff_op_blend;
784           break;
785         case 18:
786           op = cff_op_hstemhm;
787           break;
788         case 19:
789           op = cff_op_hintmask;
790           break;
791         case 20:
792           op = cff_op_cntrmask;
793           break;
794         case 21:
795           op = cff_op_rmoveto;
796           break;
797         case 22:
798           op = cff_op_hmoveto;
799           break;
800         case 23:
801           op = cff_op_vstemhm;
802           break;
803         case 24:
804           op = cff_op_rcurveline;
805           break;
806         case 25:
807           op = cff_op_rlinecurve;
808           break;
809         case 26:
810           op = cff_op_vvcurveto;
811           break;
812         case 27:
813           op = cff_op_hhcurveto;
814           break;
815         case 29:
816           op = cff_op_callgsubr;
817           break;
818         case 30:
819           op = cff_op_vhcurveto;
820           break;
821         case 31:
822           op = cff_op_hvcurveto;
823           break;
824         default:
825           FT_TRACE4(( " unknown op (%d)\n", v ));
826           break;
827         }
828 
829         if ( op == cff_op_unknown )
830           continue;
831 
832         /* in Multiple Master CFFs, T2 charstrings can appear in */
833         /* dictionaries, but some operators are prohibited       */
834         if ( in_dict )
835         {
836           switch ( op )
837           {
838           case cff_op_hstem:
839           case cff_op_vstem:
840           case cff_op_vmoveto:
841           case cff_op_rlineto:
842           case cff_op_hlineto:
843           case cff_op_vlineto:
844           case cff_op_rrcurveto:
845           case cff_op_hstemhm:
846           case cff_op_hintmask:
847           case cff_op_cntrmask:
848           case cff_op_rmoveto:
849           case cff_op_hmoveto:
850           case cff_op_vstemhm:
851           case cff_op_rcurveline:
852           case cff_op_rlinecurve:
853           case cff_op_vvcurveto:
854           case cff_op_hhcurveto:
855           case cff_op_vhcurveto:
856           case cff_op_hvcurveto:
857           case cff_op_hflex:
858           case cff_op_flex:
859           case cff_op_hflex1:
860           case cff_op_flex1:
861           case cff_op_callsubr:
862           case cff_op_callgsubr:
863             goto MM_Error;
864 
865           default:
866             break;
867           }
868         }
869 
870         /* check arguments */
871         req_args = cff_argument_counts[op];
872         if ( req_args & CFF_COUNT_CHECK_WIDTH )
873         {
874           if ( num_args > 0 && decoder->read_width )
875           {
876             /* If `nominal_width' is non-zero, the number is really a      */
877             /* difference against `nominal_width'.  Else, the number here  */
878             /* is truly a width, not a difference against `nominal_width'. */
879             /* If the font does not set `nominal_width', then              */
880             /* `nominal_width' defaults to zero, and so we can set         */
881             /* `glyph_width' to `nominal_width' plus number on the stack   */
882             /* -- for either case.                                         */
883 
884             FT_Int  set_width_ok;
885 
886 
887             switch ( op )
888             {
889             case cff_op_hmoveto:
890             case cff_op_vmoveto:
891               set_width_ok = num_args & 2;
892               break;
893 
894             case cff_op_hstem:
895             case cff_op_vstem:
896             case cff_op_hstemhm:
897             case cff_op_vstemhm:
898             case cff_op_rmoveto:
899             case cff_op_hintmask:
900             case cff_op_cntrmask:
901               set_width_ok = num_args & 1;
902               break;
903 
904             case cff_op_endchar:
905               /* If there is a width specified for endchar, we either have */
906               /* 1 argument or 5 arguments.  We like to argue.             */
907               set_width_ok = in_dict
908                                ? 0
909                                : ( ( num_args == 5 ) || ( num_args == 1 ) );
910               break;
911 
912             default:
913               set_width_ok = 0;
914               break;
915             }
916 
917             if ( set_width_ok )
918             {
919               decoder->glyph_width = decoder->nominal_width +
920                                        ( stack[0] >> 16 );
921 
922               if ( decoder->width_only )
923               {
924                 /* we only want the advance width; stop here */
925                 break;
926               }
927 
928               /* Consumed an argument. */
929               num_args--;
930             }
931           }
932 
933           decoder->read_width = 0;
934           req_args            = 0;
935         }
936 
937         req_args &= 0x000F;
938         if ( num_args < req_args )
939           goto Stack_Underflow;
940         args     -= req_args;
941         num_args -= req_args;
942 
943         /* At this point, `args' points to the first argument of the  */
944         /* operand in case `req_args' isn't zero.  Otherwise, we have */
945         /* to adjust `args' manually.                                 */
946 
947         /* Note that we only pop arguments from the stack which we    */
948         /* really need and can digest so that we can continue in case */
949         /* of superfluous stack elements.                             */
950 
951         switch ( op )
952         {
953         case cff_op_hstem:
954         case cff_op_vstem:
955         case cff_op_hstemhm:
956         case cff_op_vstemhm:
957           /* the number of arguments is always even here */
958           FT_TRACE4((
959               op == cff_op_hstem   ? " hstem\n"   :
960             ( op == cff_op_vstem   ? " vstem\n"   :
961             ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
962 
963           if ( hinter )
964             hinter->stems( hinter->hints,
965                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
966                            num_args / 2,
967                            args - ( num_args & ~1 ) );
968 
969           decoder->num_hints += num_args / 2;
970           args = stack;
971           break;
972 
973         case cff_op_hintmask:
974         case cff_op_cntrmask:
975           FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
976 
977           /* implement vstem when needed --                        */
978           /* the specification doesn't say it, but this also works */
979           /* with the 'cntrmask' operator                          */
980           /*                                                       */
981           if ( num_args > 0 )
982           {
983             if ( hinter )
984               hinter->stems( hinter->hints,
985                              0,
986                              num_args / 2,
987                              args - ( num_args & ~1 ) );
988 
989             decoder->num_hints += num_args / 2;
990           }
991 
992           /* In a valid charstring there must be at least one byte */
993           /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
994           /* instruction).  Additionally, there must be space for  */
995           /* `num_hints' bits.                                     */
996 
997           if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
998             goto Syntax_Error;
999 
1000           if ( hinter )
1001           {
1002             if ( op == cff_op_hintmask )
1003               hinter->hintmask( hinter->hints,
1004                                 (FT_UInt)builder->current->n_points,
1005                                 (FT_UInt)decoder->num_hints,
1006                                 ip );
1007             else
1008               hinter->counter( hinter->hints,
1009                                (FT_UInt)decoder->num_hints,
1010                                ip );
1011           }
1012 
1013 #ifdef FT_DEBUG_LEVEL_TRACE
1014           {
1015             FT_UInt  maskbyte;
1016 
1017 
1018             FT_TRACE4(( " (maskbytes:" ));
1019 
1020             for ( maskbyte = 0;
1021                   maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1022                   maskbyte++, ip++ )
1023               FT_TRACE4(( " 0x%02X", *ip ));
1024 
1025             FT_TRACE4(( ")\n" ));
1026           }
1027 #else
1028           ip += ( decoder->num_hints + 7 ) >> 3;
1029 #endif
1030           args = stack;
1031           break;
1032 
1033         case cff_op_rmoveto:
1034           FT_TRACE4(( " rmoveto\n" ));
1035 
1036           cff_builder_close_contour( builder );
1037           builder->path_begun = 0;
1038           x    = ADD_LONG( x, args[-2] );
1039           y    = ADD_LONG( y, args[-1] );
1040           args = stack;
1041           break;
1042 
1043         case cff_op_vmoveto:
1044           FT_TRACE4(( " vmoveto\n" ));
1045 
1046           cff_builder_close_contour( builder );
1047           builder->path_begun = 0;
1048           y    = ADD_LONG( y, args[-1] );
1049           args = stack;
1050           break;
1051 
1052         case cff_op_hmoveto:
1053           FT_TRACE4(( " hmoveto\n" ));
1054 
1055           cff_builder_close_contour( builder );
1056           builder->path_begun = 0;
1057           x    = ADD_LONG( x, args[-1] );
1058           args = stack;
1059           break;
1060 
1061         case cff_op_rlineto:
1062           FT_TRACE4(( " rlineto\n" ));
1063 
1064           if ( cff_builder_start_point( builder, x, y )  ||
1065                cff_check_points( builder, num_args / 2 ) )
1066             goto Fail;
1067 
1068           if ( num_args < 2 )
1069             goto Stack_Underflow;
1070 
1071           args -= num_args & ~1;
1072           while ( args < decoder->top )
1073           {
1074             x = ADD_LONG( x, args[0] );
1075             y = ADD_LONG( y, args[1] );
1076             cff_builder_add_point( builder, x, y, 1 );
1077             args += 2;
1078           }
1079           args = stack;
1080           break;
1081 
1082         case cff_op_hlineto:
1083         case cff_op_vlineto:
1084           {
1085             FT_Int  phase = ( op == cff_op_hlineto );
1086 
1087 
1088             FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1089                                              : " vlineto\n" ));
1090 
1091             if ( num_args < 0 )
1092               goto Stack_Underflow;
1093 
1094             /* there exist subsetted fonts (found in PDFs) */
1095             /* which call `hlineto' without arguments      */
1096             if ( num_args == 0 )
1097               break;
1098 
1099             if ( cff_builder_start_point( builder, x, y ) ||
1100                  cff_check_points( builder, num_args )    )
1101               goto Fail;
1102 
1103             args = stack;
1104             while ( args < decoder->top )
1105             {
1106               if ( phase )
1107                 x = ADD_LONG( x, args[0] );
1108               else
1109                 y = ADD_LONG( y, args[0] );
1110 
1111               if ( cff_builder_add_point1( builder, x, y ) )
1112                 goto Fail;
1113 
1114               args++;
1115               phase ^= 1;
1116             }
1117             args = stack;
1118           }
1119           break;
1120 
1121         case cff_op_rrcurveto:
1122           {
1123             FT_Int  nargs;
1124 
1125 
1126             FT_TRACE4(( " rrcurveto\n" ));
1127 
1128             if ( num_args < 6 )
1129               goto Stack_Underflow;
1130 
1131             nargs = num_args - num_args % 6;
1132 
1133             if ( cff_builder_start_point( builder, x, y ) ||
1134                  cff_check_points( builder, nargs / 2 )   )
1135               goto Fail;
1136 
1137             args -= nargs;
1138             while ( args < decoder->top )
1139             {
1140               x = ADD_LONG( x, args[0] );
1141               y = ADD_LONG( y, args[1] );
1142               cff_builder_add_point( builder, x, y, 0 );
1143 
1144               x = ADD_LONG( x, args[2] );
1145               y = ADD_LONG( y, args[3] );
1146               cff_builder_add_point( builder, x, y, 0 );
1147 
1148               x = ADD_LONG( x, args[4] );
1149               y = ADD_LONG( y, args[5] );
1150               cff_builder_add_point( builder, x, y, 1 );
1151 
1152               args += 6;
1153             }
1154             args = stack;
1155           }
1156           break;
1157 
1158         case cff_op_vvcurveto:
1159           {
1160             FT_Int  nargs;
1161 
1162 
1163             FT_TRACE4(( " vvcurveto\n" ));
1164 
1165             if ( num_args < 4 )
1166               goto Stack_Underflow;
1167 
1168             /* if num_args isn't of the form 4n or 4n+1, */
1169             /* we enforce it by clearing the second bit  */
1170 
1171             nargs = num_args & ~2;
1172 
1173             if ( cff_builder_start_point( builder, x, y ) )
1174               goto Fail;
1175 
1176             args -= nargs;
1177 
1178             if ( nargs & 1 )
1179             {
1180               x = ADD_LONG( x, args[0] );
1181               args++;
1182               nargs--;
1183             }
1184 
1185             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1186               goto Fail;
1187 
1188             while ( args < decoder->top )
1189             {
1190               y = ADD_LONG( y, args[0] );
1191               cff_builder_add_point( builder, x, y, 0 );
1192 
1193               x = ADD_LONG( x, args[1] );
1194               y = ADD_LONG( y, args[2] );
1195               cff_builder_add_point( builder, x, y, 0 );
1196 
1197               y = ADD_LONG( y, args[3] );
1198               cff_builder_add_point( builder, x, y, 1 );
1199 
1200               args += 4;
1201             }
1202             args = stack;
1203           }
1204           break;
1205 
1206         case cff_op_hhcurveto:
1207           {
1208             FT_Int  nargs;
1209 
1210 
1211             FT_TRACE4(( " hhcurveto\n" ));
1212 
1213             if ( num_args < 4 )
1214               goto Stack_Underflow;
1215 
1216             /* if num_args isn't of the form 4n or 4n+1, */
1217             /* we enforce it by clearing the second bit  */
1218 
1219             nargs = num_args & ~2;
1220 
1221             if ( cff_builder_start_point( builder, x, y ) )
1222               goto Fail;
1223 
1224             args -= nargs;
1225             if ( nargs & 1 )
1226             {
1227               y = ADD_LONG( y, args[0] );
1228               args++;
1229               nargs--;
1230             }
1231 
1232             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1233               goto Fail;
1234 
1235             while ( args < decoder->top )
1236             {
1237               x = ADD_LONG( x, args[0] );
1238               cff_builder_add_point( builder, x, y, 0 );
1239 
1240               x = ADD_LONG( x, args[1] );
1241               y = ADD_LONG( y, args[2] );
1242               cff_builder_add_point( builder, x, y, 0 );
1243 
1244               x = ADD_LONG( x, args[3] );
1245               cff_builder_add_point( builder, x, y, 1 );
1246 
1247               args += 4;
1248             }
1249             args = stack;
1250           }
1251           break;
1252 
1253         case cff_op_vhcurveto:
1254         case cff_op_hvcurveto:
1255           {
1256             FT_Int  phase;
1257             FT_Int  nargs;
1258 
1259 
1260             FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1261                                                : " hvcurveto\n" ));
1262 
1263             if ( cff_builder_start_point( builder, x, y ) )
1264               goto Fail;
1265 
1266             if ( num_args < 4 )
1267               goto Stack_Underflow;
1268 
1269             /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1270             /* we enforce it by clearing the second bit               */
1271 
1272             nargs = num_args & ~2;
1273 
1274             args -= nargs;
1275             if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1276               goto Stack_Underflow;
1277 
1278             phase = ( op == cff_op_hvcurveto );
1279 
1280             while ( nargs >= 4 )
1281             {
1282               nargs -= 4;
1283               if ( phase )
1284               {
1285                 x = ADD_LONG( x, args[0] );
1286                 cff_builder_add_point( builder, x, y, 0 );
1287 
1288                 x = ADD_LONG( x, args[1] );
1289                 y = ADD_LONG( y, args[2] );
1290                 cff_builder_add_point( builder, x, y, 0 );
1291 
1292                 y = ADD_LONG( y, args[3] );
1293                 if ( nargs == 1 )
1294                   x = ADD_LONG( x, args[4] );
1295                 cff_builder_add_point( builder, x, y, 1 );
1296               }
1297               else
1298               {
1299                 y = ADD_LONG( y, args[0] );
1300                 cff_builder_add_point( builder, x, y, 0 );
1301 
1302                 x = ADD_LONG( x, args[1] );
1303                 y = ADD_LONG( y, args[2] );
1304                 cff_builder_add_point( builder, x, y, 0 );
1305 
1306                 x = ADD_LONG( x, args[3] );
1307                 if ( nargs == 1 )
1308                   y = ADD_LONG( y, args[4] );
1309                 cff_builder_add_point( builder, x, y, 1 );
1310               }
1311               args  += 4;
1312               phase ^= 1;
1313             }
1314             args = stack;
1315           }
1316           break;
1317 
1318         case cff_op_rlinecurve:
1319           {
1320             FT_Int  num_lines;
1321             FT_Int  nargs;
1322 
1323 
1324             FT_TRACE4(( " rlinecurve\n" ));
1325 
1326             if ( num_args < 8 )
1327               goto Stack_Underflow;
1328 
1329             nargs     = num_args & ~1;
1330             num_lines = ( nargs - 6 ) / 2;
1331 
1332             if ( cff_builder_start_point( builder, x, y )   ||
1333                  cff_check_points( builder, num_lines + 3 ) )
1334               goto Fail;
1335 
1336             args -= nargs;
1337 
1338             /* first, add the line segments */
1339             while ( num_lines > 0 )
1340             {
1341               x = ADD_LONG( x, args[0] );
1342               y = ADD_LONG( y, args[1] );
1343               cff_builder_add_point( builder, x, y, 1 );
1344 
1345               args += 2;
1346               num_lines--;
1347             }
1348 
1349             /* then the curve */
1350             x = ADD_LONG( x, args[0] );
1351             y = ADD_LONG( y, args[1] );
1352             cff_builder_add_point( builder, x, y, 0 );
1353 
1354             x = ADD_LONG( x, args[2] );
1355             y = ADD_LONG( y, args[3] );
1356             cff_builder_add_point( builder, x, y, 0 );
1357 
1358             x = ADD_LONG( x, args[4] );
1359             y = ADD_LONG( y, args[5] );
1360             cff_builder_add_point( builder, x, y, 1 );
1361 
1362             args = stack;
1363           }
1364           break;
1365 
1366         case cff_op_rcurveline:
1367           {
1368             FT_Int  num_curves;
1369             FT_Int  nargs;
1370 
1371 
1372             FT_TRACE4(( " rcurveline\n" ));
1373 
1374             if ( num_args < 8 )
1375               goto Stack_Underflow;
1376 
1377             nargs      = num_args - 2;
1378             nargs      = nargs - nargs % 6 + 2;
1379             num_curves = ( nargs - 2 ) / 6;
1380 
1381             if ( cff_builder_start_point( builder, x, y )        ||
1382                  cff_check_points( builder, num_curves * 3 + 2 ) )
1383               goto Fail;
1384 
1385             args -= nargs;
1386 
1387             /* first, add the curves */
1388             while ( num_curves > 0 )
1389             {
1390               x = ADD_LONG( x, args[0] );
1391               y = ADD_LONG( y, args[1] );
1392               cff_builder_add_point( builder, x, y, 0 );
1393 
1394               x = ADD_LONG( x, args[2] );
1395               y = ADD_LONG( y, args[3] );
1396               cff_builder_add_point( builder, x, y, 0 );
1397 
1398               x = ADD_LONG( x, args[4] );
1399               y = ADD_LONG( y, args[5] );
1400               cff_builder_add_point( builder, x, y, 1 );
1401 
1402               args += 6;
1403               num_curves--;
1404             }
1405 
1406             /* then the final line */
1407             x = ADD_LONG( x, args[0] );
1408             y = ADD_LONG( y, args[1] );
1409             cff_builder_add_point( builder, x, y, 1 );
1410 
1411             args = stack;
1412           }
1413           break;
1414 
1415         case cff_op_hflex1:
1416           {
1417             FT_Pos  start_y;
1418 
1419 
1420             FT_TRACE4(( " hflex1\n" ));
1421 
1422             /* adding five more points: 4 control points, 1 on-curve point */
1423             /* -- make sure we have enough space for the start point if it */
1424             /* needs to be added                                           */
1425             if ( cff_builder_start_point( builder, x, y ) ||
1426                  cff_check_points( builder, 6 )           )
1427               goto Fail;
1428 
1429             /* record the starting point's y position for later use */
1430             start_y = y;
1431 
1432             /* first control point */
1433             x = ADD_LONG( x, args[0] );
1434             y = ADD_LONG( y, args[1] );
1435             cff_builder_add_point( builder, x, y, 0 );
1436 
1437             /* second control point */
1438             x = ADD_LONG( x, args[2] );
1439             y = ADD_LONG( y, args[3] );
1440             cff_builder_add_point( builder, x, y, 0 );
1441 
1442             /* join point; on curve, with y-value the same as the last */
1443             /* control point's y-value                                 */
1444             x = ADD_LONG( x, args[4] );
1445             cff_builder_add_point( builder, x, y, 1 );
1446 
1447             /* third control point, with y-value the same as the join */
1448             /* point's y-value                                        */
1449             x = ADD_LONG( x, args[5] );
1450             cff_builder_add_point( builder, x, y, 0 );
1451 
1452             /* fourth control point */
1453             x = ADD_LONG( x, args[6] );
1454             y = ADD_LONG( y, args[7] );
1455             cff_builder_add_point( builder, x, y, 0 );
1456 
1457             /* ending point, with y-value the same as the start   */
1458             x = ADD_LONG( x, args[8] );
1459             y = start_y;
1460             cff_builder_add_point( builder, x, y, 1 );
1461 
1462             args = stack;
1463             break;
1464           }
1465 
1466         case cff_op_hflex:
1467           {
1468             FT_Pos  start_y;
1469 
1470 
1471             FT_TRACE4(( " hflex\n" ));
1472 
1473             /* adding six more points; 4 control points, 2 on-curve points */
1474             if ( cff_builder_start_point( builder, x, y ) ||
1475                  cff_check_points( builder, 6 )           )
1476               goto Fail;
1477 
1478             /* record the starting point's y-position for later use */
1479             start_y = y;
1480 
1481             /* first control point */
1482             x = ADD_LONG( x, args[0] );
1483             cff_builder_add_point( builder, x, y, 0 );
1484 
1485             /* second control point */
1486             x = ADD_LONG( x, args[1] );
1487             y = ADD_LONG( y, args[2] );
1488             cff_builder_add_point( builder, x, y, 0 );
1489 
1490             /* join point; on curve, with y-value the same as the last */
1491             /* control point's y-value                                 */
1492             x = ADD_LONG( x, args[3] );
1493             cff_builder_add_point( builder, x, y, 1 );
1494 
1495             /* third control point, with y-value the same as the join */
1496             /* point's y-value                                        */
1497             x = ADD_LONG( x, args[4] );
1498             cff_builder_add_point( builder, x, y, 0 );
1499 
1500             /* fourth control point */
1501             x = ADD_LONG( x, args[5] );
1502             y = start_y;
1503             cff_builder_add_point( builder, x, y, 0 );
1504 
1505             /* ending point, with y-value the same as the start point's */
1506             /* y-value -- we don't add this point, though               */
1507             x = ADD_LONG( x, args[6] );
1508             cff_builder_add_point( builder, x, y, 1 );
1509 
1510             args = stack;
1511             break;
1512           }
1513 
1514         case cff_op_flex1:
1515           {
1516             FT_Pos     start_x, start_y; /* record start x, y values for */
1517                                          /* alter use                    */
1518             FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
1519                                          /* algorithm below              */
1520             FT_Int     horizontal, count;
1521             FT_Fixed*  temp;
1522 
1523 
1524             FT_TRACE4(( " flex1\n" ));
1525 
1526             /* adding six more points; 4 control points, 2 on-curve points */
1527             if ( cff_builder_start_point( builder, x, y ) ||
1528                  cff_check_points( builder, 6 )           )
1529               goto Fail;
1530 
1531             /* record the starting point's x, y position for later use */
1532             start_x = x;
1533             start_y = y;
1534 
1535             /* XXX: figure out whether this is supposed to be a horizontal */
1536             /*      or vertical flex; the Type 2 specification is vague... */
1537 
1538             temp = args;
1539 
1540             /* grab up to the last argument */
1541             for ( count = 5; count > 0; count-- )
1542             {
1543               dx    = ADD_LONG( dx, temp[0] );
1544               dy    = ADD_LONG( dy, temp[1] );
1545               temp += 2;
1546             }
1547 
1548             if ( dx < 0 )
1549               dx = -dx;
1550             if ( dy < 0 )
1551               dy = -dy;
1552 
1553             /* strange test, but here it is... */
1554             horizontal = ( dx > dy );
1555 
1556             for ( count = 5; count > 0; count-- )
1557             {
1558               x = ADD_LONG( x, args[0] );
1559               y = ADD_LONG( y, args[1] );
1560               cff_builder_add_point( builder, x, y,
1561                                      (FT_Bool)( count == 3 ) );
1562               args += 2;
1563             }
1564 
1565             /* is last operand an x- or y-delta? */
1566             if ( horizontal )
1567             {
1568               x = ADD_LONG( x, args[0] );
1569               y = start_y;
1570             }
1571             else
1572             {
1573               x = start_x;
1574               y = ADD_LONG( y, args[0] );
1575             }
1576 
1577             cff_builder_add_point( builder, x, y, 1 );
1578 
1579             args = stack;
1580             break;
1581            }
1582 
1583         case cff_op_flex:
1584           {
1585             FT_UInt  count;
1586 
1587 
1588             FT_TRACE4(( " flex\n" ));
1589 
1590             if ( cff_builder_start_point( builder, x, y ) ||
1591                  cff_check_points( builder, 6 )           )
1592               goto Fail;
1593 
1594             for ( count = 6; count > 0; count-- )
1595             {
1596               x = ADD_LONG( x, args[0] );
1597               y = ADD_LONG( y, args[1] );
1598               cff_builder_add_point( builder, x, y,
1599                                      (FT_Bool)( count == 4 || count == 1 ) );
1600               args += 2;
1601             }
1602 
1603             args = stack;
1604           }
1605           break;
1606 
1607         case cff_op_seac:
1608           FT_TRACE4(( " seac\n" ));
1609 
1610           error = cff_operator_seac( decoder,
1611                                      args[0], args[1], args[2],
1612                                      (FT_Int)( args[3] >> 16 ),
1613                                      (FT_Int)( args[4] >> 16 ) );
1614 
1615           /* add current outline to the glyph slot */
1616           FT_GlyphLoader_Add( builder->loader );
1617 
1618           /* return now! */
1619           FT_TRACE4(( "\n" ));
1620           return error;
1621 
1622         case cff_op_endchar:
1623           /* in dictionaries, `endchar' simply indicates end of data */
1624           if ( in_dict )
1625             return error;
1626 
1627           FT_TRACE4(( " endchar\n" ));
1628 
1629           /* We are going to emulate the seac operator. */
1630           if ( num_args >= 4 )
1631           {
1632             /* Save glyph width so that the subglyphs don't overwrite it. */
1633             FT_Pos  glyph_width = decoder->glyph_width;
1634 
1635 
1636             error = cff_operator_seac( decoder,
1637                                        0L, args[-4], args[-3],
1638                                        (FT_Int)( args[-2] >> 16 ),
1639                                        (FT_Int)( args[-1] >> 16 ) );
1640 
1641             decoder->glyph_width = glyph_width;
1642           }
1643           else
1644           {
1645             cff_builder_close_contour( builder );
1646 
1647             /* close hints recording session */
1648             if ( hinter )
1649             {
1650               if ( hinter->close( hinter->hints,
1651                                   (FT_UInt)builder->current->n_points ) )
1652                 goto Syntax_Error;
1653 
1654               /* apply hints to the loaded glyph outline now */
1655               error = hinter->apply( hinter->hints,
1656                                      builder->current,
1657                                      (PSH_Globals)builder->hints_globals,
1658                                      decoder->hint_mode );
1659               if ( error )
1660                 goto Fail;
1661             }
1662 
1663             /* add current outline to the glyph slot */
1664             FT_GlyphLoader_Add( builder->loader );
1665           }
1666 
1667           /* return now! */
1668           FT_TRACE4(( "\n" ));
1669           return error;
1670 
1671         case cff_op_abs:
1672           FT_TRACE4(( " abs\n" ));
1673 
1674           if ( args[0] < 0 )
1675           {
1676             if ( args[0] == FT_LONG_MIN )
1677               args[0] = FT_LONG_MAX;
1678             else
1679               args[0] = -args[0];
1680           }
1681           args++;
1682           break;
1683 
1684         case cff_op_add:
1685           FT_TRACE4(( " add\n" ));
1686 
1687           args[0] = ADD_LONG( args[0], args[1] );
1688           args++;
1689           break;
1690 
1691         case cff_op_sub:
1692           FT_TRACE4(( " sub\n" ));
1693 
1694           args[0] = SUB_LONG( args[0], args[1] );
1695           args++;
1696           break;
1697 
1698         case cff_op_div:
1699           FT_TRACE4(( " div\n" ));
1700 
1701           args[0] = FT_DivFix( args[0], args[1] );
1702           args++;
1703           break;
1704 
1705         case cff_op_neg:
1706           FT_TRACE4(( " neg\n" ));
1707 
1708           if ( args[0] == FT_LONG_MIN )
1709             args[0] = FT_LONG_MAX;
1710           args[0] = -args[0];
1711           args++;
1712           break;
1713 
1714         case cff_op_random:
1715           FT_TRACE4(( " random\n" ));
1716 
1717           /* only use the lower 16 bits of `random'  */
1718           /* to generate a number in the range (0;1] */
1719           args[0] = (FT_Fixed)
1720                       ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
1721           args++;
1722 
1723           decoder->current_subfont->random =
1724             cff_random( decoder->current_subfont->random );
1725           break;
1726 
1727         case cff_op_mul:
1728           FT_TRACE4(( " mul\n" ));
1729 
1730           args[0] = FT_MulFix( args[0], args[1] );
1731           args++;
1732           break;
1733 
1734         case cff_op_sqrt:
1735           FT_TRACE4(( " sqrt\n" ));
1736 
1737           if ( args[0] > 0 )
1738           {
1739             FT_Fixed  root = args[0];
1740             FT_Fixed  new_root;
1741 
1742 
1743             for (;;)
1744             {
1745               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1746               if ( new_root == root )
1747                 break;
1748               root = new_root;
1749             }
1750             args[0] = new_root;
1751           }
1752           else
1753             args[0] = 0;
1754           args++;
1755           break;
1756 
1757         case cff_op_drop:
1758           /* nothing */
1759           FT_TRACE4(( " drop\n" ));
1760 
1761           break;
1762 
1763         case cff_op_exch:
1764           {
1765             FT_Fixed  tmp;
1766 
1767 
1768             FT_TRACE4(( " exch\n" ));
1769 
1770             tmp     = args[0];
1771             args[0] = args[1];
1772             args[1] = tmp;
1773             args   += 2;
1774           }
1775           break;
1776 
1777         case cff_op_index:
1778           {
1779             FT_Int  idx = (FT_Int)( args[0] >> 16 );
1780 
1781 
1782             FT_TRACE4(( " index\n" ));
1783 
1784             if ( idx < 0 )
1785               idx = 0;
1786             else if ( idx > num_args - 2 )
1787               idx = num_args - 2;
1788             args[0] = args[-( idx + 1 )];
1789             args++;
1790           }
1791           break;
1792 
1793         case cff_op_roll:
1794           {
1795             FT_Int  count = (FT_Int)( args[0] >> 16 );
1796             FT_Int  idx   = (FT_Int)( args[1] >> 16 );
1797 
1798 
1799             FT_TRACE4(( " roll\n" ));
1800 
1801             if ( count <= 0 )
1802               count = 1;
1803 
1804             args -= count;
1805             if ( args < stack )
1806               goto Stack_Underflow;
1807 
1808             if ( idx >= 0 )
1809             {
1810               while ( idx > 0 )
1811               {
1812                 FT_Fixed  tmp = args[count - 1];
1813                 FT_Int    i;
1814 
1815 
1816                 for ( i = count - 2; i >= 0; i-- )
1817                   args[i + 1] = args[i];
1818                 args[0] = tmp;
1819                 idx--;
1820               }
1821             }
1822             else
1823             {
1824               while ( idx < 0 )
1825               {
1826                 FT_Fixed  tmp = args[0];
1827                 FT_Int    i;
1828 
1829 
1830                 for ( i = 0; i < count - 1; i++ )
1831                   args[i] = args[i + 1];
1832                 args[count - 1] = tmp;
1833                 idx++;
1834               }
1835             }
1836             args += count;
1837           }
1838           break;
1839 
1840         case cff_op_dup:
1841           FT_TRACE4(( " dup\n" ));
1842 
1843           args[1] = args[0];
1844           args   += 2;
1845           break;
1846 
1847         case cff_op_put:
1848           {
1849             FT_Fixed  val = args[0];
1850             FT_Int    idx = (FT_Int)( args[1] >> 16 );
1851 
1852 
1853             FT_TRACE4(( " put\n" ));
1854 
1855             /* the Type2 specification before version 16-March-2000 */
1856             /* didn't give a hard-coded size limit of the temporary */
1857             /* storage array; instead, an argument of the           */
1858             /* `MultipleMaster' operator set the size               */
1859             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1860               decoder->buildchar[idx] = val;
1861           }
1862           break;
1863 
1864         case cff_op_get:
1865           {
1866             FT_Int    idx = (FT_Int)( args[0] >> 16 );
1867             FT_Fixed  val = 0;
1868 
1869 
1870             FT_TRACE4(( " get\n" ));
1871 
1872             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1873               val = decoder->buildchar[idx];
1874 
1875             args[0] = val;
1876             args++;
1877           }
1878           break;
1879 
1880         case cff_op_store:
1881           /* this operator was removed from the Type2 specification */
1882           /* in version 16-March-2000                               */
1883 
1884           /* since we currently don't handle interpolation of multiple */
1885           /* master fonts, this is a no-op                             */
1886           FT_TRACE4(( " store\n" ));
1887           break;
1888 
1889         case cff_op_load:
1890           /* this operator was removed from the Type2 specification */
1891           /* in version 16-March-2000                               */
1892           {
1893             FT_Int  reg_idx = (FT_Int)args[0];
1894             FT_Int  idx     = (FT_Int)args[1];
1895             FT_Int  count   = (FT_Int)args[2];
1896 
1897 
1898             FT_TRACE4(( " load\n" ));
1899 
1900             /* since we currently don't handle interpolation of multiple */
1901             /* master fonts, we store a vector [1 0 0 ...] in the        */
1902             /* temporary storage array regardless of the Registry index  */
1903             if ( reg_idx >= 0 && reg_idx <= 2             &&
1904                  idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1905                  count >= 0 && count <= num_axes          )
1906             {
1907               FT_Int  end, i;
1908 
1909 
1910               end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
1911 
1912               if ( idx < end )
1913                 decoder->buildchar[idx] = 1 << 16;
1914 
1915               for ( i = idx + 1; i < end; i++ )
1916                 decoder->buildchar[i] = 0;
1917             }
1918           }
1919           break;
1920 
1921         case cff_op_blend:
1922           /* this operator was removed from the Type2 specification */
1923           /* in version 16-March-2000                               */
1924           {
1925             FT_Int  num_results = (FT_Int)( args[0] >> 16 );
1926 
1927 
1928             FT_TRACE4(( " blend\n" ));
1929 
1930             if ( num_results < 0 )
1931               goto Syntax_Error;
1932 
1933             if ( num_results * (FT_Int)num_designs > num_args )
1934               goto Stack_Underflow;
1935 
1936             /* since we currently don't handle interpolation of multiple */
1937             /* master fonts, return the `num_results' values of the      */
1938             /* first master                                              */
1939             args     -= num_results * ( num_designs - 1 );
1940             num_args -= num_results * ( num_designs - 1 );
1941           }
1942           break;
1943 
1944         case cff_op_dotsection:
1945           /* this operator is deprecated and ignored by the parser */
1946           FT_TRACE4(( " dotsection\n" ));
1947           break;
1948 
1949         case cff_op_closepath:
1950           /* this is an invalid Type 2 operator; however, there        */
1951           /* exist fonts which are incorrectly converted from probably */
1952           /* Type 1 to CFF, and some parsers seem to accept it         */
1953 
1954           FT_TRACE4(( " closepath (invalid op)\n" ));
1955 
1956           args = stack;
1957           break;
1958 
1959         case cff_op_hsbw:
1960           /* this is an invalid Type 2 operator; however, there        */
1961           /* exist fonts which are incorrectly converted from probably */
1962           /* Type 1 to CFF, and some parsers seem to accept it         */
1963 
1964           FT_TRACE4(( " hsbw (invalid op)\n" ));
1965 
1966           decoder->glyph_width =
1967             ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
1968 
1969           decoder->builder.left_bearing.x = args[0];
1970           decoder->builder.left_bearing.y = 0;
1971 
1972           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
1973           y    = decoder->builder.pos_y;
1974           args = stack;
1975           break;
1976 
1977         case cff_op_sbw:
1978           /* this is an invalid Type 2 operator; however, there        */
1979           /* exist fonts which are incorrectly converted from probably */
1980           /* Type 1 to CFF, and some parsers seem to accept it         */
1981 
1982           FT_TRACE4(( " sbw (invalid op)\n" ));
1983 
1984           decoder->glyph_width =
1985             ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
1986 
1987           decoder->builder.left_bearing.x = args[0];
1988           decoder->builder.left_bearing.y = args[1];
1989 
1990           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
1991           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
1992           args = stack;
1993           break;
1994 
1995         case cff_op_setcurrentpoint:
1996           /* this is an invalid Type 2 operator; however, there        */
1997           /* exist fonts which are incorrectly converted from probably */
1998           /* Type 1 to CFF, and some parsers seem to accept it         */
1999 
2000           FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2001 
2002           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
2003           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
2004           args = stack;
2005           break;
2006 
2007         case cff_op_callothersubr:
2008           /* this is an invalid Type 2 operator; however, there        */
2009           /* exist fonts which are incorrectly converted from probably */
2010           /* Type 1 to CFF, and some parsers seem to accept it         */
2011 
2012           FT_TRACE4(( " callothersubr (invalid op)\n" ));
2013 
2014           /* subsequent `pop' operands should add the arguments,       */
2015           /* this is the implementation described for `unknown' other  */
2016           /* subroutines in the Type1 spec.                            */
2017           /*                                                           */
2018           /* XXX Fix return arguments (see discussion below).          */
2019           args -= 2 + ( args[-2] >> 16 );
2020           if ( args < stack )
2021             goto Stack_Underflow;
2022           break;
2023 
2024         case cff_op_pop:
2025           /* this is an invalid Type 2 operator; however, there        */
2026           /* exist fonts which are incorrectly converted from probably */
2027           /* Type 1 to CFF, and some parsers seem to accept it         */
2028 
2029           FT_TRACE4(( " pop (invalid op)\n" ));
2030 
2031           /* XXX Increasing `args' is wrong: After a certain number of */
2032           /* `pop's we get a stack overflow.  Reason for doing it is   */
2033           /* code like this (actually found in a CFF font):            */
2034           /*                                                           */
2035           /*   17 1 3 callothersubr                                    */
2036           /*   pop                                                     */
2037           /*   callsubr                                                */
2038           /*                                                           */
2039           /* Since we handle `callothersubr' as a no-op, and           */
2040           /* `callsubr' needs at least one argument, `pop' can't be a  */
2041           /* no-op too as it basically should be.                      */
2042           /*                                                           */
2043           /* The right solution would be to provide real support for   */
2044           /* `callothersubr' as done in `t1decode.c', however, given   */
2045           /* the fact that CFF fonts with `pop' are invalid, it is     */
2046           /* questionable whether it is worth the time.                */
2047           args++;
2048           break;
2049 
2050         case cff_op_and:
2051           {
2052             FT_Fixed  cond = ( args[0] && args[1] );
2053 
2054 
2055             FT_TRACE4(( " and\n" ));
2056 
2057             args[0] = cond ? 0x10000L : 0;
2058             args++;
2059           }
2060           break;
2061 
2062         case cff_op_or:
2063           {
2064             FT_Fixed  cond = ( args[0] || args[1] );
2065 
2066 
2067             FT_TRACE4(( " or\n" ));
2068 
2069             args[0] = cond ? 0x10000L : 0;
2070             args++;
2071           }
2072           break;
2073 
2074         case cff_op_not:
2075           {
2076             FT_Fixed  cond = !args[0];
2077 
2078 
2079             FT_TRACE4(( " not\n" ));
2080 
2081             args[0] = cond ? 0x10000L : 0;
2082             args++;
2083           }
2084           break;
2085 
2086         case cff_op_eq:
2087           {
2088             FT_Fixed  cond = ( args[0] == args[1] );
2089 
2090 
2091             FT_TRACE4(( " eq\n" ));
2092 
2093             args[0] = cond ? 0x10000L : 0;
2094             args++;
2095           }
2096           break;
2097 
2098         case cff_op_ifelse:
2099           {
2100             FT_Fixed  cond = ( args[2] <= args[3] );
2101 
2102 
2103             FT_TRACE4(( " ifelse\n" ));
2104 
2105             if ( !cond )
2106               args[0] = args[1];
2107             args++;
2108           }
2109           break;
2110 
2111         case cff_op_callsubr:
2112           {
2113             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2114                                       decoder->locals_bias );
2115 
2116 
2117             FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
2118                         idx,
2119                         zone - decoder->zones + 1 ));
2120 
2121             if ( idx >= decoder->num_locals )
2122             {
2123               FT_ERROR(( "cff_decoder_parse_charstrings:"
2124                          " invalid local subr index\n" ));
2125               goto Syntax_Error;
2126             }
2127 
2128             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2129             {
2130               FT_ERROR(( "cff_decoder_parse_charstrings:"
2131                          " too many nested subrs\n" ));
2132               goto Syntax_Error;
2133             }
2134 
2135             zone->cursor = ip;  /* save current instruction pointer */
2136 
2137             zone++;
2138             zone->base   = decoder->locals[idx];
2139             zone->limit  = decoder->locals[idx + 1];
2140             zone->cursor = zone->base;
2141 
2142             if ( !zone->base || zone->limit == zone->base )
2143             {
2144               FT_ERROR(( "cff_decoder_parse_charstrings:"
2145                          " invoking empty subrs\n" ));
2146               goto Syntax_Error;
2147             }
2148 
2149             decoder->zone = zone;
2150             ip            = zone->base;
2151             limit         = zone->limit;
2152           }
2153           break;
2154 
2155         case cff_op_callgsubr:
2156           {
2157             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2158                                       decoder->globals_bias );
2159 
2160 
2161             FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
2162                         idx,
2163                         zone - decoder->zones + 1 ));
2164 
2165             if ( idx >= decoder->num_globals )
2166             {
2167               FT_ERROR(( "cff_decoder_parse_charstrings:"
2168                          " invalid global subr index\n" ));
2169               goto Syntax_Error;
2170             }
2171 
2172             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2173             {
2174               FT_ERROR(( "cff_decoder_parse_charstrings:"
2175                          " too many nested subrs\n" ));
2176               goto Syntax_Error;
2177             }
2178 
2179             zone->cursor = ip;  /* save current instruction pointer */
2180 
2181             zone++;
2182             zone->base   = decoder->globals[idx];
2183             zone->limit  = decoder->globals[idx + 1];
2184             zone->cursor = zone->base;
2185 
2186             if ( !zone->base || zone->limit == zone->base )
2187             {
2188               FT_ERROR(( "cff_decoder_parse_charstrings:"
2189                          " invoking empty subrs\n" ));
2190               goto Syntax_Error;
2191             }
2192 
2193             decoder->zone = zone;
2194             ip            = zone->base;
2195             limit         = zone->limit;
2196           }
2197           break;
2198 
2199         case cff_op_return:
2200           FT_TRACE4(( " return (leaving level %d)\n",
2201                       decoder->zone - decoder->zones ));
2202 
2203           if ( decoder->zone <= decoder->zones )
2204           {
2205             FT_ERROR(( "cff_decoder_parse_charstrings:"
2206                        " unexpected return\n" ));
2207             goto Syntax_Error;
2208           }
2209 
2210           decoder->zone--;
2211           zone  = decoder->zone;
2212           ip    = zone->cursor;
2213           limit = zone->limit;
2214           break;
2215 
2216         default:
2217           FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2218 
2219           if ( ip[-1] == 12 )
2220             FT_ERROR(( " %d", ip[0] ));
2221           FT_ERROR(( "\n" ));
2222 
2223           return FT_THROW( Unimplemented_Feature );
2224         }
2225 
2226         decoder->top = args;
2227 
2228         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2229           goto Stack_Overflow;
2230 
2231       } /* general operator processing */
2232 
2233     } /* while ip < limit */
2234 
2235     FT_TRACE4(( "..end..\n\n" ));
2236 
2237   Fail:
2238     return error;
2239 
2240   MM_Error:
2241     FT_TRACE4(( "cff_decoder_parse_charstrings:"
2242                 " invalid opcode found in top DICT charstring\n"));
2243     return FT_THROW( Invalid_File_Format );
2244 
2245   Syntax_Error:
2246     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2247     return FT_THROW( Invalid_File_Format );
2248 
2249   Stack_Underflow:
2250     FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2251     return FT_THROW( Too_Few_Arguments );
2252 
2253   Stack_Overflow:
2254     FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2255     return FT_THROW( Stack_Overflow );
2256   }
2257 
2258 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2259 
2260 
2261   /**************************************************************************
2262    *
2263    * @Function:
2264    *   cff_decoder_init
2265    *
2266    * @Description:
2267    *   Initializes a given glyph decoder.
2268    *
2269    * @InOut:
2270    *   decoder ::
2271    *     A pointer to the glyph builder to initialize.
2272    *
2273    * @Input:
2274    *   face ::
2275    *     The current face object.
2276    *
2277    *   size ::
2278    *     The current size object.
2279    *
2280    *   slot ::
2281    *     The current glyph object.
2282    *
2283    *   hinting ::
2284    *     Whether hinting is active.
2285    *
2286    *   hint_mode ::
2287    *     The hinting mode.
2288    */
2289   FT_LOCAL_DEF( void )
cff_decoder_init(CFF_Decoder * decoder,TT_Face face,CFF_Size size,CFF_GlyphSlot slot,FT_Bool hinting,FT_Render_Mode hint_mode,CFF_Decoder_Get_Glyph_Callback get_callback,CFF_Decoder_Free_Glyph_Callback free_callback)2290   cff_decoder_init( CFF_Decoder*                     decoder,
2291                     TT_Face                          face,
2292                     CFF_Size                         size,
2293                     CFF_GlyphSlot                    slot,
2294                     FT_Bool                          hinting,
2295                     FT_Render_Mode                   hint_mode,
2296                     CFF_Decoder_Get_Glyph_Callback   get_callback,
2297                     CFF_Decoder_Free_Glyph_Callback  free_callback )
2298   {
2299     CFF_Font  cff = (CFF_Font)face->extra.data;
2300 
2301 
2302     /* clear everything */
2303     FT_ZERO( decoder );
2304 
2305     /* initialize builder */
2306     cff_builder_init( &decoder->builder, face, size, slot, hinting );
2307 
2308     /* initialize Type2 decoder */
2309     decoder->cff          = cff;
2310     decoder->num_globals  = cff->global_subrs_index.count;
2311     decoder->globals      = cff->global_subrs;
2312     decoder->globals_bias = cff_compute_bias(
2313                               cff->top_font.font_dict.charstring_type,
2314                               decoder->num_globals );
2315 
2316     decoder->hint_mode = hint_mode;
2317 
2318     decoder->get_glyph_callback  = get_callback;
2319     decoder->free_glyph_callback = free_callback;
2320   }
2321 
2322 
2323   /* this function is used to select the subfont */
2324   /* and the locals subrs array                  */
2325   FT_LOCAL_DEF( FT_Error )
cff_decoder_prepare(CFF_Decoder * decoder,CFF_Size size,FT_UInt glyph_index)2326   cff_decoder_prepare( CFF_Decoder*  decoder,
2327                        CFF_Size      size,
2328                        FT_UInt       glyph_index )
2329   {
2330     CFF_Builder  *builder = &decoder->builder;
2331     CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
2332     CFF_SubFont   sub     = &cff->top_font;
2333     FT_Error      error   = FT_Err_Ok;
2334 
2335     FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)cff->cffload;
2336 
2337 
2338     /* manage CID fonts */
2339     if ( cff->num_subfonts )
2340     {
2341       FT_Byte  fd_index = cffload->fd_select_get( &cff->fd_select,
2342                                                   glyph_index );
2343 
2344 
2345       if ( fd_index >= cff->num_subfonts )
2346       {
2347         FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
2348         error = FT_THROW( Invalid_File_Format );
2349         goto Exit;
2350       }
2351 
2352       FT_TRACE3(( "  in subfont %d:\n", fd_index ));
2353 
2354       sub = cff->subfonts[fd_index];
2355 
2356       if ( builder->hints_funcs && size )
2357       {
2358         FT_Size       ftsize   = FT_SIZE( size );
2359         CFF_Internal  internal = (CFF_Internal)ftsize->internal->module_data;
2360 
2361 
2362         /* for CFFs without subfonts, this value has already been set */
2363         builder->hints_globals = (void *)internal->subfonts[fd_index];
2364       }
2365     }
2366 
2367     decoder->num_locals  = sub->local_subrs_index.count;
2368     decoder->locals      = sub->local_subrs;
2369     decoder->locals_bias = cff_compute_bias(
2370                              decoder->cff->top_font.font_dict.charstring_type,
2371                              decoder->num_locals );
2372 
2373     decoder->glyph_width   = sub->private_dict.default_width;
2374     decoder->nominal_width = sub->private_dict.nominal_width;
2375 
2376     decoder->current_subfont = sub;
2377 
2378   Exit:
2379     return error;
2380   }
2381 
2382 
2383 /* END */
2384