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