• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * t1decode.c
4  *
5  *   PostScript Type 1 decoding routines (body).
6  *
7  * Copyright 2000-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_INTERNAL_CALC_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
23 #include FT_INTERNAL_HASH_H
24 #include FT_OUTLINE_H
25 
26 #include "t1decode.h"
27 #include "psobjs.h"
28 
29 #include "psauxerr.h"
30 
31 /* ensure proper sign extension */
32 #define Fix2Int( f )  ( (FT_Int)(FT_Short)( (f) >> 16 ) )
33 
34   /**************************************************************************
35    *
36    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
37    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
38    * messages during execution.
39    */
40 #undef  FT_COMPONENT
41 #define FT_COMPONENT  trace_t1decode
42 
43 
44   typedef enum  T1_Operator_
45   {
46     op_none = 0,
47     op_endchar,
48     op_hsbw,
49     op_seac,
50     op_sbw,
51     op_closepath,
52     op_hlineto,
53     op_hmoveto,
54     op_hvcurveto,
55     op_rlineto,
56     op_rmoveto,
57     op_rrcurveto,
58     op_vhcurveto,
59     op_vlineto,
60     op_vmoveto,
61     op_dotsection,
62     op_hstem,
63     op_hstem3,
64     op_vstem,
65     op_vstem3,
66     op_div,
67     op_callothersubr,
68     op_callsubr,
69     op_pop,
70     op_return,
71     op_setcurrentpoint,
72     op_unknown15,
73 
74     op_max    /* never remove this one */
75 
76   } T1_Operator;
77 
78 
79   static
80   const FT_Int  t1_args_count[op_max] =
81   {
82     0, /* none */
83     0, /* endchar */
84     2, /* hsbw */
85     5, /* seac */
86     4, /* sbw */
87     0, /* closepath */
88     1, /* hlineto */
89     1, /* hmoveto */
90     4, /* hvcurveto */
91     2, /* rlineto */
92     2, /* rmoveto */
93     6, /* rrcurveto */
94     4, /* vhcurveto */
95     1, /* vlineto */
96     1, /* vmoveto */
97     0, /* dotsection */
98     2, /* hstem */
99     6, /* hstem3 */
100     2, /* vstem */
101     6, /* vstem3 */
102     2, /* div */
103    -1, /* callothersubr */
104     1, /* callsubr */
105     0, /* pop */
106     0, /* return */
107     2, /* setcurrentpoint */
108     2  /* opcode 15 (undocumented and obsolete) */
109   };
110 
111 
112   /**************************************************************************
113    *
114    * @Function:
115    *   t1_lookup_glyph_by_stdcharcode_ps
116    *
117    * @Description:
118    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
119    *   implement the SEAC Type 1 operator in the Adobe engine
120    *
121    * @Input:
122    *   face ::
123    *     The current face object.
124    *
125    *   charcode ::
126    *     The character code to look for.
127    *
128    * @Return:
129    *   A glyph index in the font face.  Returns -1 if the corresponding
130    *   glyph wasn't found.
131    */
132   FT_LOCAL_DEF( FT_Int )
t1_lookup_glyph_by_stdcharcode_ps(PS_Decoder * decoder,FT_Int charcode)133   t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder*  decoder,
134                                      FT_Int       charcode )
135   {
136     FT_UInt             n;
137     const FT_String*    glyph_name;
138     FT_Service_PsCMaps  psnames = decoder->psnames;
139 
140 
141     /* check range of standard char code */
142     if ( charcode < 0 || charcode > 255 )
143       return -1;
144 
145     glyph_name = psnames->adobe_std_strings(
146                    psnames->adobe_std_encoding[charcode]);
147 
148     for ( n = 0; n < decoder->num_glyphs; n++ )
149     {
150       FT_String*  name = (FT_String*)decoder->glyph_names[n];
151 
152 
153       if ( name                               &&
154            name[0] == glyph_name[0]           &&
155            ft_strcmp( name, glyph_name ) == 0 )
156         return (FT_Int)n;
157     }
158 
159     return -1;
160   }
161 
162 
163 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
164 
165   /**************************************************************************
166    *
167    * @Function:
168    *   t1_lookup_glyph_by_stdcharcode
169    *
170    * @Description:
171    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
172    *   implement the SEAC Type 1 operator.
173    *
174    * @Input:
175    *   face ::
176    *     The current face object.
177    *
178    *   charcode ::
179    *     The character code to look for.
180    *
181    * @Return:
182    *   A glyph index in the font face.  Returns -1 if the corresponding
183    *   glyph wasn't found.
184    */
185   static FT_Int
t1_lookup_glyph_by_stdcharcode(T1_Decoder decoder,FT_Int charcode)186   t1_lookup_glyph_by_stdcharcode( T1_Decoder  decoder,
187                                   FT_Int      charcode )
188   {
189     FT_UInt             n;
190     const FT_String*    glyph_name;
191     FT_Service_PsCMaps  psnames = decoder->psnames;
192 
193 
194     /* check range of standard char code */
195     if ( charcode < 0 || charcode > 255 )
196       return -1;
197 
198     glyph_name = psnames->adobe_std_strings(
199                    psnames->adobe_std_encoding[charcode]);
200 
201     for ( n = 0; n < decoder->num_glyphs; n++ )
202     {
203       FT_String*  name = (FT_String*)decoder->glyph_names[n];
204 
205 
206       if ( name                               &&
207            name[0] == glyph_name[0]           &&
208            ft_strcmp( name, glyph_name ) == 0 )
209         return (FT_Int)n;
210     }
211 
212     return -1;
213   }
214 
215 
216   /* parse a single Type 1 glyph */
217   FT_LOCAL_DEF( FT_Error )
t1_decoder_parse_glyph(T1_Decoder decoder,FT_UInt glyph)218   t1_decoder_parse_glyph( T1_Decoder  decoder,
219                           FT_UInt     glyph )
220   {
221     return decoder->parse_callback( decoder, glyph );
222   }
223 
224 
225   /**************************************************************************
226    *
227    * @Function:
228    *   t1operator_seac
229    *
230    * @Description:
231    *   Implements the `seac' Type 1 operator for a Type 1 decoder.
232    *
233    * @Input:
234    *   decoder ::
235    *     The current CID decoder.
236    *
237    *   asb ::
238    *     The accent's side bearing.
239    *
240    *   adx ::
241    *     The horizontal offset of the accent.
242    *
243    *   ady ::
244    *     The vertical offset of the accent.
245    *
246    *   bchar ::
247    *     The base character's StandardEncoding charcode.
248    *
249    *   achar ::
250    *     The accent character's StandardEncoding charcode.
251    *
252    * @Return:
253    *   FreeType error code.  0 means success.
254    */
255   static FT_Error
t1operator_seac(T1_Decoder decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)256   t1operator_seac( T1_Decoder  decoder,
257                    FT_Pos      asb,
258                    FT_Pos      adx,
259                    FT_Pos      ady,
260                    FT_Int      bchar,
261                    FT_Int      achar )
262   {
263     FT_Error     error;
264     FT_Int       bchar_index, achar_index;
265 #if 0
266     FT_Int       n_base_points;
267     FT_Outline*  base = decoder->builder.base;
268 #endif
269     FT_Vector    left_bearing, advance;
270 
271 #ifdef FT_CONFIG_OPTION_INCREMENTAL
272     T1_Face      face  = (T1_Face)decoder->builder.face;
273 #endif
274 
275 
276     if ( decoder->seac )
277     {
278       FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
279       return FT_THROW( Syntax_Error );
280     }
281 
282     if ( decoder->builder.metrics_only )
283     {
284       FT_ERROR(( "t1operator_seac: unexpected seac\n" ));
285       return FT_THROW( Syntax_Error );
286     }
287 
288     /* seac weirdness */
289     adx += decoder->builder.left_bearing.x;
290 
291     /* `glyph_names' is set to 0 for CID fonts which do not */
292     /* include an encoding.  How can we deal with these?    */
293 #ifdef FT_CONFIG_OPTION_INCREMENTAL
294     if ( decoder->glyph_names == 0                   &&
295          !face->root.internal->incremental_interface )
296 #else
297     if ( decoder->glyph_names == 0 )
298 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
299     {
300       FT_ERROR(( "t1operator_seac:"
301                  " glyph names table not available in this font\n" ));
302       return FT_THROW( Syntax_Error );
303     }
304 
305 #ifdef FT_CONFIG_OPTION_INCREMENTAL
306     if ( face->root.internal->incremental_interface )
307     {
308       /* the caller must handle the font encoding also */
309       bchar_index = bchar;
310       achar_index = achar;
311     }
312     else
313 #endif
314     {
315       bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
316       achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
317     }
318 
319     if ( bchar_index < 0 || achar_index < 0 )
320     {
321       FT_ERROR(( "t1operator_seac:"
322                  " invalid seac character code arguments\n" ));
323       return FT_THROW( Syntax_Error );
324     }
325 
326     /* if we are trying to load a composite glyph, do not load the */
327     /* accent character and return the array of subglyphs.         */
328     if ( decoder->builder.no_recurse )
329     {
330       FT_GlyphSlot    glyph  = (FT_GlyphSlot)decoder->builder.glyph;
331       FT_GlyphLoader  loader = glyph->internal->loader;
332       FT_SubGlyph     subg;
333 
334 
335       /* reallocate subglyph array if necessary */
336       error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
337       if ( error )
338         goto Exit;
339 
340       subg = loader->current.subglyphs;
341 
342       /* subglyph 0 = base character */
343       subg->index = bchar_index;
344       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
345                     FT_SUBGLYPH_FLAG_USE_MY_METRICS;
346       subg->arg1  = 0;
347       subg->arg2  = 0;
348       subg++;
349 
350       /* subglyph 1 = accent character */
351       subg->index = achar_index;
352       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
353       subg->arg1  = (FT_Int)FIXED_TO_INT( adx - asb );
354       subg->arg2  = (FT_Int)FIXED_TO_INT( ady );
355 
356       /* set up remaining glyph fields */
357       glyph->num_subglyphs = 2;
358       glyph->subglyphs     = loader->base.subglyphs;
359       glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
360 
361       loader->current.num_subglyphs = 2;
362       goto Exit;
363     }
364 
365     /* First load `bchar' in builder */
366     /* now load the unscaled outline */
367 
368     FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
369 
370     /* the seac operator must not be nested */
371     decoder->seac = TRUE;
372     error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
373     decoder->seac = FALSE;
374     if ( error )
375       goto Exit;
376 
377     /* save the left bearing and width of the base character */
378     /* as they will be erased by the next load.              */
379 
380     left_bearing = decoder->builder.left_bearing;
381     advance      = decoder->builder.advance;
382 
383     decoder->builder.left_bearing.x = 0;
384     decoder->builder.left_bearing.y = 0;
385 
386     decoder->builder.pos_x = adx - asb;
387     decoder->builder.pos_y = ady;
388 
389     /* Now load `achar' on top of */
390     /* the base outline           */
391 
392     /* the seac operator must not be nested */
393     decoder->seac = TRUE;
394     error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
395     decoder->seac = FALSE;
396     if ( error )
397       goto Exit;
398 
399     /* restore the left side bearing and   */
400     /* advance width of the base character */
401 
402     decoder->builder.left_bearing = left_bearing;
403     decoder->builder.advance      = advance;
404 
405     decoder->builder.pos_x = 0;
406     decoder->builder.pos_y = 0;
407 
408   Exit:
409     return error;
410   }
411 
412 
413   /**************************************************************************
414    *
415    * @Function:
416    *   t1_decoder_parse_charstrings
417    *
418    * @Description:
419    *   Parses a given Type 1 charstrings program.
420    *
421    * @Input:
422    *   decoder ::
423    *     The current Type 1 decoder.
424    *
425    *   charstring_base ::
426    *     The base address of the charstring stream.
427    *
428    *   charstring_len ::
429    *     The length in bytes of the charstring stream.
430    *
431    * @Return:
432    *   FreeType error code.  0 means success.
433    */
434   FT_LOCAL_DEF( FT_Error )
t1_decoder_parse_charstrings(T1_Decoder decoder,FT_Byte * charstring_base,FT_UInt charstring_len)435   t1_decoder_parse_charstrings( T1_Decoder  decoder,
436                                 FT_Byte*    charstring_base,
437                                 FT_UInt     charstring_len )
438   {
439     FT_Error         error;
440     T1_Decoder_Zone  zone;
441     FT_Byte*         ip;
442     FT_Byte*         limit;
443     T1_Builder       builder = &decoder->builder;
444     FT_Pos           x, y, orig_x, orig_y;
445     FT_Int           known_othersubr_result_cnt   = 0;
446     FT_Int           unknown_othersubr_result_cnt = 0;
447     FT_Bool          large_int;
448     FT_Fixed         seed;
449 
450     T1_Hints_Funcs   hinter;
451 
452 #ifdef FT_DEBUG_LEVEL_TRACE
453     FT_Bool          bol = TRUE;
454 #endif
455 
456 
457     /* compute random seed from stack address of parameter */
458     seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed            ^
459                          (FT_Offset)(char*)&decoder         ^
460                          (FT_Offset)(char*)&charstring_base ) &
461                          FT_ULONG_MAX                         );
462     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
463     if ( seed == 0 )
464       seed = 0x7384;
465 
466     /* First of all, initialize the decoder */
467     decoder->top  = decoder->stack;
468     decoder->zone = decoder->zones;
469     zone          = decoder->zones;
470 
471     builder->parse_state = T1_Parse_Start;
472 
473     hinter = (T1_Hints_Funcs)builder->hints_funcs;
474 
475     /* a font that reads BuildCharArray without setting */
476     /* its values first is buggy, but ...               */
477     FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
478                ( decoder->buildchar == NULL )  );
479 
480     if ( decoder->buildchar && decoder->len_buildchar > 0 )
481       FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
482 
483     zone->base           = charstring_base;
484     limit = zone->limit  = charstring_base + charstring_len;
485     ip    = zone->cursor = zone->base;
486 
487     error = FT_Err_Ok;
488 
489     x = orig_x = builder->pos_x;
490     y = orig_y = builder->pos_y;
491 
492     /* begin hints recording session, if any */
493     if ( hinter )
494       hinter->open( hinter->hints );
495 
496     large_int = FALSE;
497 
498     /* now, execute loop */
499     while ( ip < limit )
500     {
501       FT_Long*     top   = decoder->top;
502       T1_Operator  op    = op_none;
503       FT_Int32     value = 0;
504 
505 
506       FT_ASSERT( known_othersubr_result_cnt == 0   ||
507                  unknown_othersubr_result_cnt == 0 );
508 
509 #ifdef FT_DEBUG_LEVEL_TRACE
510       if ( bol )
511       {
512         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
513         bol = FALSE;
514       }
515 #endif
516 
517       /**********************************************************************
518        *
519        * Decode operator or operand
520        *
521        */
522 
523       /* first of all, decompress operator or value */
524       switch ( *ip++ )
525       {
526       case 1:
527         op = op_hstem;
528         break;
529 
530       case 3:
531         op = op_vstem;
532         break;
533       case 4:
534         op = op_vmoveto;
535         break;
536       case 5:
537         op = op_rlineto;
538         break;
539       case 6:
540         op = op_hlineto;
541         break;
542       case 7:
543         op = op_vlineto;
544         break;
545       case 8:
546         op = op_rrcurveto;
547         break;
548       case 9:
549         op = op_closepath;
550         break;
551       case 10:
552         op = op_callsubr;
553         break;
554       case 11:
555         op = op_return;
556         break;
557 
558       case 13:
559         op = op_hsbw;
560         break;
561       case 14:
562         op = op_endchar;
563         break;
564 
565       case 15:          /* undocumented, obsolete operator */
566         op = op_unknown15;
567         break;
568 
569       case 21:
570         op = op_rmoveto;
571         break;
572       case 22:
573         op = op_hmoveto;
574         break;
575 
576       case 30:
577         op = op_vhcurveto;
578         break;
579       case 31:
580         op = op_hvcurveto;
581         break;
582 
583       case 12:
584         if ( ip >= limit )
585         {
586           FT_ERROR(( "t1_decoder_parse_charstrings:"
587                      " invalid escape (12+EOF)\n" ));
588           goto Syntax_Error;
589         }
590 
591         switch ( *ip++ )
592         {
593         case 0:
594           op = op_dotsection;
595           break;
596         case 1:
597           op = op_vstem3;
598           break;
599         case 2:
600           op = op_hstem3;
601           break;
602         case 6:
603           op = op_seac;
604           break;
605         case 7:
606           op = op_sbw;
607           break;
608         case 12:
609           op = op_div;
610           break;
611         case 16:
612           op = op_callothersubr;
613           break;
614         case 17:
615           op = op_pop;
616           break;
617         case 33:
618           op = op_setcurrentpoint;
619           break;
620 
621         default:
622           FT_ERROR(( "t1_decoder_parse_charstrings:"
623                      " invalid escape (12+%d)\n",
624                      ip[-1] ));
625           goto Syntax_Error;
626         }
627         break;
628 
629       case 255:    /* four bytes integer */
630         if ( ip + 4 > limit )
631         {
632           FT_ERROR(( "t1_decoder_parse_charstrings:"
633                      " unexpected EOF in integer\n" ));
634           goto Syntax_Error;
635         }
636 
637         value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
638                             ( (FT_UInt32)ip[1] << 16 ) |
639                             ( (FT_UInt32)ip[2] << 8  ) |
640                               (FT_UInt32)ip[3]         );
641         ip += 4;
642 
643         /* According to the specification, values > 32000 or < -32000 must */
644         /* be followed by a `div' operator to make the result be in the    */
645         /* range [-32000;32000].  We expect that the second argument of    */
646         /* `div' is not a large number.  Additionally, we don't handle     */
647         /* stuff like `<large1> <large2> <num> div <num> div' or           */
648         /* <large1> <large2> <num> div div'.  This is probably not allowed */
649         /* anyway.                                                         */
650         if ( value > 32000 || value < -32000 )
651         {
652           if ( large_int )
653           {
654             FT_ERROR(( "t1_decoder_parse_charstrings:"
655                        " no `div' after large integer\n" ));
656           }
657           else
658             large_int = TRUE;
659         }
660         else
661         {
662           if ( !large_int )
663             value = (FT_Int32)( (FT_UInt32)value << 16 );
664         }
665 
666         break;
667 
668       default:
669         if ( ip[-1] >= 32 )
670         {
671           if ( ip[-1] < 247 )
672             value = (FT_Int32)ip[-1] - 139;
673           else
674           {
675             if ( ++ip > limit )
676             {
677               FT_ERROR(( "t1_decoder_parse_charstrings:"
678                          " unexpected EOF in integer\n" ));
679               goto Syntax_Error;
680             }
681 
682             if ( ip[-2] < 251 )
683               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
684             else
685               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
686           }
687 
688           if ( !large_int )
689             value = (FT_Int32)( (FT_UInt32)value << 16 );
690         }
691         else
692         {
693           FT_ERROR(( "t1_decoder_parse_charstrings:"
694                      " invalid byte (%d)\n", ip[-1] ));
695           goto Syntax_Error;
696         }
697       }
698 
699       if ( unknown_othersubr_result_cnt > 0 )
700       {
701         switch ( op )
702         {
703         case op_callsubr:
704         case op_return:
705         case op_none:
706         case op_pop:
707           break;
708 
709         default:
710           /* all operands have been transferred by previous pops */
711           unknown_othersubr_result_cnt = 0;
712           break;
713         }
714       }
715 
716       if ( large_int && !( op == op_none || op == op_div ) )
717       {
718         FT_ERROR(( "t1_decoder_parse_charstrings:"
719                    " no `div' after large integer\n" ));
720 
721         large_int = FALSE;
722       }
723 
724       /**********************************************************************
725        *
726        * Push value on stack, or process operator
727        *
728        */
729       if ( op == op_none )
730       {
731         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
732         {
733           FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
734           goto Syntax_Error;
735         }
736 
737 #ifdef FT_DEBUG_LEVEL_TRACE
738         if ( large_int )
739           FT_TRACE4(( " %d", value ));
740         else
741           FT_TRACE4(( " %d", value / 65536 ));
742 #endif
743 
744         *top++       = value;
745         decoder->top = top;
746       }
747       else if ( op == op_callothersubr )  /* callothersubr */
748       {
749         FT_Int  subr_no;
750         FT_Int  arg_cnt;
751 
752 
753 #ifdef FT_DEBUG_LEVEL_TRACE
754         FT_TRACE4(( " callothersubr\n" ));
755         bol = TRUE;
756 #endif
757 
758         if ( top - decoder->stack < 2 )
759           goto Stack_Underflow;
760 
761         top -= 2;
762 
763         subr_no = Fix2Int( top[1] );
764         arg_cnt = Fix2Int( top[0] );
765 
766         /************************************************************
767          *
768          * remove all operands to callothersubr from the stack
769          *
770          * for handled othersubrs, where we know the number of
771          * arguments, we increase the stack by the value of
772          * known_othersubr_result_cnt
773          *
774          * for unhandled othersubrs the following pops adjust the
775          * stack pointer as necessary
776          */
777 
778         if ( arg_cnt > top - decoder->stack )
779           goto Stack_Underflow;
780 
781         top -= arg_cnt;
782 
783         known_othersubr_result_cnt   = 0;
784         unknown_othersubr_result_cnt = 0;
785 
786         /* XXX TODO: The checks to `arg_count == <whatever>'       */
787         /* might not be correct; an othersubr expects a certain    */
788         /* number of operands on the PostScript stack (as opposed  */
789         /* to the T1 stack) but it doesn't have to put them there  */
790         /* by itself; previous othersubrs might have left the      */
791         /* operands there if they were not followed by an          */
792         /* appropriate number of pops                              */
793         /*                                                         */
794         /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
795         /* accept a font that contains charstrings like            */
796         /*                                                         */
797         /*     100 200 2 20 callothersubr                          */
798         /*     300 1 20 callothersubr pop                          */
799         /*                                                         */
800         /* Perhaps this is the reason why BuildCharArray exists.   */
801 
802         switch ( subr_no )
803         {
804         case 0:                     /* end flex feature */
805           if ( arg_cnt != 3 )
806             goto Unexpected_OtherSubr;
807 
808           if ( !decoder->flex_state           ||
809                decoder->num_flex_vectors != 7 )
810           {
811             FT_ERROR(( "t1_decoder_parse_charstrings:"
812                        " unexpected flex end\n" ));
813             goto Syntax_Error;
814           }
815 
816           /* the two `results' are popped by the following setcurrentpoint */
817           top[0] = x;
818           top[1] = y;
819           known_othersubr_result_cnt = 2;
820           break;
821 
822         case 1:                     /* start flex feature */
823           if ( arg_cnt != 0 )
824             goto Unexpected_OtherSubr;
825 
826           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
827                FT_SET_ERROR( t1_builder_check_points( builder, 6 ) )   )
828             goto Fail;
829 
830           decoder->flex_state        = 1;
831           decoder->num_flex_vectors  = 0;
832           break;
833 
834         case 2:                     /* add flex vectors */
835           {
836             FT_Int  idx;
837 
838 
839             if ( arg_cnt != 0 )
840               goto Unexpected_OtherSubr;
841 
842             if ( !decoder->flex_state )
843             {
844               FT_ERROR(( "t1_decoder_parse_charstrings:"
845                          " missing flex start\n" ));
846               goto Syntax_Error;
847             }
848 
849             /* note that we should not add a point for index 0; */
850             /* this will move our current position to the flex  */
851             /* point without adding any point to the outline    */
852             idx = decoder->num_flex_vectors++;
853             if ( idx > 0 && idx < 7 )
854             {
855               /* in malformed fonts it is possible to have other */
856               /* opcodes in the middle of a flex (which don't    */
857               /* increase `num_flex_vectors'); we thus have to   */
858               /* check whether we can add a point                */
859               if ( FT_SET_ERROR( t1_builder_check_points( builder, 1 ) ) )
860                 goto Syntax_Error;
861 
862               t1_builder_add_point( builder,
863                                     x,
864                                     y,
865                                     (FT_Byte)( idx == 3 || idx == 6 ) );
866             }
867           }
868           break;
869 
870         case 3:                     /* change hints */
871           if ( arg_cnt != 1 )
872             goto Unexpected_OtherSubr;
873 
874           known_othersubr_result_cnt = 1;
875 
876           if ( hinter )
877             hinter->reset( hinter->hints,
878                            (FT_UInt)builder->current->n_points );
879           break;
880 
881         case 12:
882         case 13:
883           /* counter control hints, clear stack */
884           top = decoder->stack;
885           break;
886 
887         case 14:
888         case 15:
889         case 16:
890         case 17:
891         case 18:                    /* multiple masters */
892           {
893             PS_Blend  blend = decoder->blend;
894             FT_UInt   num_points, nn, mm;
895             FT_Long*  delta;
896             FT_Long*  values;
897 
898 
899             if ( !blend )
900             {
901               FT_ERROR(( "t1_decoder_parse_charstrings:"
902                          " unexpected multiple masters operator\n" ));
903               goto Syntax_Error;
904             }
905 
906             num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
907             if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
908             {
909               FT_ERROR(( "t1_decoder_parse_charstrings:"
910                          " incorrect number of multiple masters arguments\n" ));
911               goto Syntax_Error;
912             }
913 
914             /* We want to compute                                    */
915             /*                                                       */
916             /*   a0*w0 + a1*w1 + ... + ak*wk                         */
917             /*                                                       */
918             /* but we only have a0, a1-a0, a2-a0, ..., ak-a0.        */
919             /*                                                       */
920             /* However, given that w0 + w1 + ... + wk == 1, we can   */
921             /* rewrite it easily as                                  */
922             /*                                                       */
923             /*   a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk     */
924             /*                                                       */
925             /* where k == num_designs-1.                             */
926             /*                                                       */
927             /* I guess that's why it's written in this `compact'     */
928             /* form.                                                 */
929             /*                                                       */
930             delta  = top + num_points;
931             values = top;
932             for ( nn = 0; nn < num_points; nn++ )
933             {
934               FT_Long  tmp = values[0];
935 
936 
937               for ( mm = 1; mm < blend->num_designs; mm++ )
938                 tmp = ADD_LONG( tmp,
939                                 FT_MulFix( *delta++,
940                                            blend->weight_vector[mm] ) );
941 
942               *values++ = tmp;
943             }
944 
945             known_othersubr_result_cnt = (FT_Int)num_points;
946             break;
947           }
948 
949         case 19:
950           /* <idx> 1 19 callothersubr                             */
951           /* => replace elements starting from index cvi( <idx> ) */
952           /*    of BuildCharArray with WeightVector               */
953           {
954             FT_Int    idx;
955             PS_Blend  blend = decoder->blend;
956 
957 
958             if ( arg_cnt != 1 || !blend )
959               goto Unexpected_OtherSubr;
960 
961             idx = Fix2Int( top[0] );
962 
963             if ( idx < 0                                                    ||
964                  (FT_UInt)idx + blend->num_designs > decoder->len_buildchar )
965               goto Unexpected_OtherSubr;
966 
967             ft_memcpy( &decoder->buildchar[idx],
968                        blend->weight_vector,
969                        blend->num_designs *
970                          sizeof ( blend->weight_vector[0] ) );
971           }
972           break;
973 
974         case 20:
975           /* <arg1> <arg2> 2 20 callothersubr pop   */
976           /* ==> push <arg1> + <arg2> onto T1 stack */
977           if ( arg_cnt != 2 )
978             goto Unexpected_OtherSubr;
979 
980           top[0] = ADD_LONG( top[0], top[1] );
981 
982           known_othersubr_result_cnt = 1;
983           break;
984 
985         case 21:
986           /* <arg1> <arg2> 2 21 callothersubr pop   */
987           /* ==> push <arg1> - <arg2> onto T1 stack */
988           if ( arg_cnt != 2 )
989             goto Unexpected_OtherSubr;
990 
991           top[0] = SUB_LONG( top[0], top[1] );
992 
993           known_othersubr_result_cnt = 1;
994           break;
995 
996         case 22:
997           /* <arg1> <arg2> 2 22 callothersubr pop   */
998           /* ==> push <arg1> * <arg2> onto T1 stack */
999           if ( arg_cnt != 2 )
1000             goto Unexpected_OtherSubr;
1001 
1002           top[0] = FT_MulFix( top[0], top[1] );
1003 
1004           known_othersubr_result_cnt = 1;
1005           break;
1006 
1007         case 23:
1008           /* <arg1> <arg2> 2 23 callothersubr pop   */
1009           /* ==> push <arg1> / <arg2> onto T1 stack */
1010           if ( arg_cnt != 2 || top[1] == 0 )
1011             goto Unexpected_OtherSubr;
1012 
1013           top[0] = FT_DivFix( top[0], top[1] );
1014 
1015           known_othersubr_result_cnt = 1;
1016           break;
1017 
1018         case 24:
1019           /* <val> <idx> 2 24 callothersubr               */
1020           /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
1021           {
1022             FT_Int    idx;
1023             PS_Blend  blend = decoder->blend;
1024 
1025 
1026             if ( arg_cnt != 2 || !blend )
1027               goto Unexpected_OtherSubr;
1028 
1029             idx = Fix2Int( top[1] );
1030 
1031             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1032               goto Unexpected_OtherSubr;
1033 
1034             decoder->buildchar[idx] = top[0];
1035           }
1036           break;
1037 
1038         case 25:
1039           /* <idx> 1 25 callothersubr pop        */
1040           /* ==> push BuildCharArray[cvi( idx )] */
1041           /*     onto T1 stack                   */
1042           {
1043             FT_Int    idx;
1044             PS_Blend  blend = decoder->blend;
1045 
1046 
1047             if ( arg_cnt != 1 || !blend )
1048               goto Unexpected_OtherSubr;
1049 
1050             idx = Fix2Int( top[0] );
1051 
1052             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1053               goto Unexpected_OtherSubr;
1054 
1055             top[0] = decoder->buildchar[idx];
1056           }
1057 
1058           known_othersubr_result_cnt = 1;
1059           break;
1060 
1061 #if 0
1062         case 26:
1063           /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
1064           /*                      leave mark on T1 stack                    */
1065           /* <val> <idx>      ==> set BuildCharArray[cvi( <idx> )] = <val>  */
1066           XXX which routine has left its mark on the (PostScript) stack?;
1067           break;
1068 #endif
1069 
1070         case 27:
1071           /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
1072           /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
1073           /*     otherwise push <res2>                          */
1074           if ( arg_cnt != 4 )
1075             goto Unexpected_OtherSubr;
1076 
1077           if ( top[2] > top[3] )
1078             top[0] = top[1];
1079 
1080           known_othersubr_result_cnt = 1;
1081           break;
1082 
1083         case 28:
1084           /* 0 28 callothersubr pop                               */
1085           /* => push random value from interval [0, 1) onto stack */
1086           if ( arg_cnt != 0 )
1087             goto Unexpected_OtherSubr;
1088 
1089           {
1090             FT_Fixed  Rand;
1091 
1092 
1093             Rand = seed;
1094             if ( Rand >= 0x8000L )
1095               Rand++;
1096 
1097             top[0] = Rand;
1098 
1099             seed = FT_MulFix( seed, 0x10000L - seed );
1100             if ( seed == 0 )
1101               seed += 0x2873;
1102           }
1103 
1104           known_othersubr_result_cnt = 1;
1105           break;
1106 
1107         default:
1108           if ( arg_cnt >= 0 && subr_no >= 0 )
1109           {
1110             FT_ERROR(( "t1_decoder_parse_charstrings:"
1111                        " unknown othersubr [%d %d], wish me luck\n",
1112                        arg_cnt, subr_no ));
1113             unknown_othersubr_result_cnt = arg_cnt;
1114             break;
1115           }
1116           /* fall through */
1117 
1118         Unexpected_OtherSubr:
1119           FT_ERROR(( "t1_decoder_parse_charstrings:"
1120                      " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
1121           goto Syntax_Error;
1122         }
1123 
1124         top += known_othersubr_result_cnt;
1125 
1126         decoder->top = top;
1127       }
1128       else  /* general operator */
1129       {
1130         FT_Int  num_args = t1_args_count[op];
1131 
1132 
1133         FT_ASSERT( num_args >= 0 );
1134 
1135         if ( top - decoder->stack < num_args )
1136           goto Stack_Underflow;
1137 
1138         /* XXX Operators usually take their operands from the        */
1139         /*     bottom of the stack, i.e., the operands are           */
1140         /*     decoder->stack[0], ..., decoder->stack[num_args - 1]; */
1141         /*     only div, callsubr, and callothersubr are different.  */
1142         /*     In practice it doesn't matter (?).                    */
1143 
1144 #ifdef FT_DEBUG_LEVEL_TRACE
1145 
1146         switch ( op )
1147         {
1148         case op_callsubr:
1149         case op_div:
1150         case op_callothersubr:
1151         case op_pop:
1152         case op_return:
1153           break;
1154 
1155         default:
1156           if ( top - decoder->stack != num_args )
1157             FT_TRACE0(( "t1_decoder_parse_charstrings:"
1158                         " too much operands on the stack"
1159                         " (seen %d, expected %d)\n",
1160                         top - decoder->stack, num_args ));
1161             break;
1162         }
1163 
1164 #endif /* FT_DEBUG_LEVEL_TRACE */
1165 
1166         top -= num_args;
1167 
1168         switch ( op )
1169         {
1170         case op_endchar:
1171           FT_TRACE4(( " endchar\n" ));
1172 
1173           t1_builder_close_contour( builder );
1174 
1175           /* close hints recording session */
1176           if ( hinter )
1177           {
1178             if ( hinter->close( hinter->hints,
1179                                 (FT_UInt)builder->current->n_points ) )
1180               goto Syntax_Error;
1181 
1182             /* apply hints to the loaded glyph outline now */
1183             error = hinter->apply( hinter->hints,
1184                                    builder->current,
1185                                    (PSH_Globals)builder->hints_globals,
1186                                    decoder->hint_mode );
1187             if ( error )
1188               goto Fail;
1189           }
1190 
1191           /* add current outline to the glyph slot */
1192           FT_GlyphLoader_Add( builder->loader );
1193 
1194           /* the compiler should optimize away this empty loop but ... */
1195 
1196 #ifdef FT_DEBUG_LEVEL_TRACE
1197 
1198           if ( decoder->len_buildchar > 0 )
1199           {
1200             FT_UInt  i;
1201 
1202 
1203             FT_TRACE4(( "BuildCharArray = [ " ));
1204 
1205             for ( i = 0; i < decoder->len_buildchar; i++ )
1206               FT_TRACE4(( "%d ", decoder->buildchar[i] ));
1207 
1208             FT_TRACE4(( "]\n" ));
1209           }
1210 
1211 #endif /* FT_DEBUG_LEVEL_TRACE */
1212 
1213           FT_TRACE4(( "\n" ));
1214 
1215           /* return now! */
1216           return FT_Err_Ok;
1217 
1218         case op_hsbw:
1219           FT_TRACE4(( " hsbw" ));
1220 
1221           builder->parse_state = T1_Parse_Have_Width;
1222 
1223           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1224                                               top[0] );
1225 
1226           builder->advance.x = top[1];
1227           builder->advance.y = 0;
1228 
1229           orig_x = x = ADD_LONG( builder->pos_x, top[0] );
1230           orig_y = y = builder->pos_y;
1231 
1232           FT_UNUSED( orig_y );
1233 
1234           /* the `metrics_only' indicates that we only want to compute */
1235           /* the glyph's metrics (lsb + advance width), not load the   */
1236           /* rest of it; so exit immediately                           */
1237           if ( builder->metrics_only )
1238           {
1239             FT_TRACE4(( "\n" ));
1240             return FT_Err_Ok;
1241           }
1242 
1243           break;
1244 
1245         case op_seac:
1246           return t1operator_seac( decoder,
1247                                   top[0],
1248                                   top[1],
1249                                   top[2],
1250                                   Fix2Int( top[3] ),
1251                                   Fix2Int( top[4] ) );
1252 
1253         case op_sbw:
1254           FT_TRACE4(( " sbw" ));
1255 
1256           builder->parse_state = T1_Parse_Have_Width;
1257 
1258           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1259                                               top[0] );
1260           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1261                                               top[1] );
1262 
1263           builder->advance.x = top[2];
1264           builder->advance.y = top[3];
1265 
1266           x = ADD_LONG( builder->pos_x, top[0] );
1267           y = ADD_LONG( builder->pos_y, top[1] );
1268 
1269           /* the `metrics_only' indicates that we only want to compute */
1270           /* the glyph's metrics (lsb + advance width), not load the   */
1271           /* rest of it; so exit immediately                           */
1272           if ( builder->metrics_only )
1273           {
1274             FT_TRACE4(( "\n" ));
1275             return FT_Err_Ok;
1276           }
1277 
1278           break;
1279 
1280         case op_closepath:
1281           FT_TRACE4(( " closepath" ));
1282 
1283           /* if there is no path, `closepath' is a no-op */
1284           if ( builder->parse_state == T1_Parse_Have_Path   ||
1285                builder->parse_state == T1_Parse_Have_Moveto )
1286             t1_builder_close_contour( builder );
1287 
1288           builder->parse_state = T1_Parse_Have_Width;
1289           break;
1290 
1291         case op_hlineto:
1292           FT_TRACE4(( " hlineto" ));
1293 
1294           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1295             goto Fail;
1296 
1297           x = ADD_LONG( x, top[0] );
1298           goto Add_Line;
1299 
1300         case op_hmoveto:
1301           FT_TRACE4(( " hmoveto" ));
1302 
1303           x = ADD_LONG( x, top[0] );
1304 
1305           if ( !decoder->flex_state )
1306           {
1307             if ( builder->parse_state == T1_Parse_Start )
1308               goto Syntax_Error;
1309             builder->parse_state = T1_Parse_Have_Moveto;
1310           }
1311           break;
1312 
1313         case op_hvcurveto:
1314           FT_TRACE4(( " hvcurveto" ));
1315 
1316           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1317                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1318             goto Fail;
1319 
1320           x = ADD_LONG( x, top[0] );
1321           t1_builder_add_point( builder, x, y, 0 );
1322 
1323           x = ADD_LONG( x, top[1] );
1324           y = ADD_LONG( y, top[2] );
1325           t1_builder_add_point( builder, x, y, 0 );
1326 
1327           y = ADD_LONG( y, top[3] );
1328           t1_builder_add_point( builder, x, y, 1 );
1329           break;
1330 
1331         case op_rlineto:
1332           FT_TRACE4(( " rlineto" ));
1333 
1334           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1335             goto Fail;
1336 
1337           x = ADD_LONG( x, top[0] );
1338           y = ADD_LONG( y, top[1] );
1339 
1340         Add_Line:
1341           if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
1342             goto Fail;
1343           break;
1344 
1345         case op_rmoveto:
1346           FT_TRACE4(( " rmoveto" ));
1347 
1348           x = ADD_LONG( x, top[0] );
1349           y = ADD_LONG( y, top[1] );
1350 
1351           if ( !decoder->flex_state )
1352           {
1353             if ( builder->parse_state == T1_Parse_Start )
1354               goto Syntax_Error;
1355             builder->parse_state = T1_Parse_Have_Moveto;
1356           }
1357           break;
1358 
1359         case op_rrcurveto:
1360           FT_TRACE4(( " rrcurveto" ));
1361 
1362           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1363                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1364             goto Fail;
1365 
1366           x = ADD_LONG( x, top[0] );
1367           y = ADD_LONG( y, top[1] );
1368           t1_builder_add_point( builder, x, y, 0 );
1369 
1370           x = ADD_LONG( x, top[2] );
1371           y = ADD_LONG( y, top[3] );
1372           t1_builder_add_point( builder, x, y, 0 );
1373 
1374           x = ADD_LONG( x, top[4] );
1375           y = ADD_LONG( y, top[5] );
1376           t1_builder_add_point( builder, x, y, 1 );
1377           break;
1378 
1379         case op_vhcurveto:
1380           FT_TRACE4(( " vhcurveto" ));
1381 
1382           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1383                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
1384             goto Fail;
1385 
1386           y = ADD_LONG( y, top[0] );
1387           t1_builder_add_point( builder, x, y, 0 );
1388 
1389           x = ADD_LONG( x, top[1] );
1390           y = ADD_LONG( y, top[2] );
1391           t1_builder_add_point( builder, x, y, 0 );
1392 
1393           x = ADD_LONG( x, top[3] );
1394           t1_builder_add_point( builder, x, y, 1 );
1395           break;
1396 
1397         case op_vlineto:
1398           FT_TRACE4(( " vlineto" ));
1399 
1400           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1401             goto Fail;
1402 
1403           y = ADD_LONG( y, top[0] );
1404           goto Add_Line;
1405 
1406         case op_vmoveto:
1407           FT_TRACE4(( " vmoveto" ));
1408 
1409           y = ADD_LONG( y, top[0] );
1410 
1411           if ( !decoder->flex_state )
1412           {
1413             if ( builder->parse_state == T1_Parse_Start )
1414               goto Syntax_Error;
1415             builder->parse_state = T1_Parse_Have_Moveto;
1416           }
1417           break;
1418 
1419         case op_div:
1420           FT_TRACE4(( " div" ));
1421 
1422           /* if `large_int' is set, we divide unscaled numbers; */
1423           /* otherwise, we divide numbers in 16.16 format --    */
1424           /* in both cases, it is the same operation            */
1425           *top = FT_DivFix( top[0], top[1] );
1426           top++;
1427 
1428           large_int = FALSE;
1429           break;
1430 
1431         case op_callsubr:
1432           {
1433             FT_Int  idx;
1434 
1435 
1436             FT_TRACE4(( " callsubr" ));
1437 
1438             idx = Fix2Int( top[0] );
1439 
1440             if ( decoder->subrs_hash )
1441             {
1442               size_t*  val = ft_hash_num_lookup( idx,
1443                                                  decoder->subrs_hash );
1444 
1445 
1446               if ( val )
1447                 idx = *val;
1448               else
1449                 idx = -1;
1450             }
1451 
1452             if ( idx < 0 || idx >= decoder->num_subrs )
1453             {
1454               FT_ERROR(( "t1_decoder_parse_charstrings:"
1455                          " invalid subrs index\n" ));
1456               goto Syntax_Error;
1457             }
1458 
1459             if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
1460             {
1461               FT_ERROR(( "t1_decoder_parse_charstrings:"
1462                          " too many nested subrs\n" ));
1463               goto Syntax_Error;
1464             }
1465 
1466             zone->cursor = ip;  /* save current instruction pointer */
1467 
1468             zone++;
1469 
1470             /* The Type 1 driver stores subroutines without the seed bytes. */
1471             /* The CID driver stores subroutines with seed bytes.  This     */
1472             /* case is taken care of when decoder->subrs_len == 0.          */
1473             zone->base = decoder->subrs[idx];
1474 
1475             if ( decoder->subrs_len )
1476               zone->limit = zone->base + decoder->subrs_len[idx];
1477             else
1478             {
1479               /* We are using subroutines from a CID font.  We must adjust */
1480               /* for the seed bytes.                                       */
1481               zone->base  += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
1482               zone->limit  = decoder->subrs[idx + 1];
1483             }
1484 
1485             zone->cursor = zone->base;
1486 
1487             if ( !zone->base )
1488             {
1489               FT_ERROR(( "t1_decoder_parse_charstrings:"
1490                          " invoking empty subrs\n" ));
1491               goto Syntax_Error;
1492             }
1493 
1494             decoder->zone = zone;
1495             ip            = zone->base;
1496             limit         = zone->limit;
1497             break;
1498           }
1499 
1500         case op_pop:
1501           FT_TRACE4(( " pop" ));
1502 
1503           if ( known_othersubr_result_cnt > 0 )
1504           {
1505             known_othersubr_result_cnt--;
1506             /* ignore, we pushed the operands ourselves */
1507             break;
1508           }
1509 
1510           if ( unknown_othersubr_result_cnt == 0 )
1511           {
1512             FT_ERROR(( "t1_decoder_parse_charstrings:"
1513                        " no more operands for othersubr\n" ));
1514             goto Syntax_Error;
1515           }
1516 
1517           unknown_othersubr_result_cnt--;
1518           top++;   /* `push' the operand to callothersubr onto the stack */
1519           break;
1520 
1521         case op_return:
1522           FT_TRACE4(( " return" ));
1523 
1524           if ( zone <= decoder->zones )
1525           {
1526             FT_ERROR(( "t1_decoder_parse_charstrings:"
1527                        " unexpected return\n" ));
1528             goto Syntax_Error;
1529           }
1530 
1531           zone--;
1532           ip            = zone->cursor;
1533           limit         = zone->limit;
1534           decoder->zone = zone;
1535           break;
1536 
1537         case op_dotsection:
1538           FT_TRACE4(( " dotsection" ));
1539 
1540           break;
1541 
1542         case op_hstem:
1543           FT_TRACE4(( " hstem" ));
1544 
1545           /* record horizontal hint */
1546           if ( hinter )
1547           {
1548             /* top[0] += builder->left_bearing.y; */
1549             hinter->stem( hinter->hints, 1, top );
1550           }
1551           break;
1552 
1553         case op_hstem3:
1554           FT_TRACE4(( " hstem3" ));
1555 
1556           /* record horizontal counter-controlled hints */
1557           if ( hinter )
1558             hinter->stem3( hinter->hints, 1, top );
1559           break;
1560 
1561         case op_vstem:
1562           FT_TRACE4(( " vstem" ));
1563 
1564           /* record vertical hint */
1565           if ( hinter )
1566           {
1567             top[0] = ADD_LONG( top[0], orig_x );
1568             hinter->stem( hinter->hints, 0, top );
1569           }
1570           break;
1571 
1572         case op_vstem3:
1573           FT_TRACE4(( " vstem3" ));
1574 
1575           /* record vertical counter-controlled hints */
1576           if ( hinter )
1577           {
1578             FT_Pos  dx = orig_x;
1579 
1580 
1581             top[0] = ADD_LONG( top[0], dx );
1582             top[2] = ADD_LONG( top[2], dx );
1583             top[4] = ADD_LONG( top[4], dx );
1584             hinter->stem3( hinter->hints, 0, top );
1585           }
1586           break;
1587 
1588         case op_setcurrentpoint:
1589           FT_TRACE4(( " setcurrentpoint" ));
1590 
1591           /* From the T1 specification, section 6.4:                */
1592           /*                                                        */
1593           /*   The setcurrentpoint command is used only in          */
1594           /*   conjunction with results from OtherSubrs procedures. */
1595 
1596           /* known_othersubr_result_cnt != 0 is already handled     */
1597           /* above.                                                 */
1598 
1599           /* Note, however, that both Ghostscript and Adobe         */
1600           /* Distiller handle this situation by silently ignoring   */
1601           /* the inappropriate `setcurrentpoint' instruction.  So   */
1602           /* we do the same.                                        */
1603 #if 0
1604 
1605           if ( decoder->flex_state != 1 )
1606           {
1607             FT_ERROR(( "t1_decoder_parse_charstrings:"
1608                        " unexpected `setcurrentpoint'\n" ));
1609             goto Syntax_Error;
1610           }
1611           else
1612             ...
1613 #endif
1614 
1615           x = top[0];
1616           y = top[1];
1617           decoder->flex_state = 0;
1618           break;
1619 
1620         case op_unknown15:
1621           FT_TRACE4(( " opcode_15" ));
1622           /* nothing to do except to pop the two arguments */
1623           break;
1624 
1625         default:
1626           FT_ERROR(( "t1_decoder_parse_charstrings:"
1627                      " unhandled opcode %d\n", op ));
1628           goto Syntax_Error;
1629         }
1630 
1631         /* XXX Operators usually clear the operand stack;  */
1632         /*     only div, callsubr, callothersubr, pop, and */
1633         /*     return are different.                       */
1634         /*     In practice it doesn't matter (?).          */
1635 
1636         decoder->top = top;
1637 
1638 #ifdef FT_DEBUG_LEVEL_TRACE
1639         FT_TRACE4(( "\n" ));
1640         bol = TRUE;
1641 #endif
1642 
1643       } /* general operator processing */
1644 
1645     } /* while ip < limit */
1646 
1647     FT_TRACE4(( "..end..\n\n" ));
1648 
1649   Fail:
1650     return error;
1651 
1652   Syntax_Error:
1653     return FT_THROW( Syntax_Error );
1654 
1655   Stack_Underflow:
1656     return FT_THROW( Stack_Underflow );
1657   }
1658 
1659 
1660 #else /* !T1_CONFIG_OPTION_OLD_ENGINE */
1661 
1662 
1663   /**************************************************************************
1664    *
1665    * @Function:
1666    *   t1_decoder_parse_metrics
1667    *
1668    * @Description:
1669    *   Parses a given Type 1 charstrings program to extract width
1670    *
1671    * @Input:
1672    *   decoder ::
1673    *     The current Type 1 decoder.
1674    *
1675    *   charstring_base ::
1676    *     The base address of the charstring stream.
1677    *
1678    *   charstring_len ::
1679    *     The length in bytes of the charstring stream.
1680    *
1681    * @Return:
1682    *   FreeType error code.  0 means success.
1683    */
1684   FT_LOCAL_DEF( FT_Error )
t1_decoder_parse_metrics(T1_Decoder decoder,FT_Byte * charstring_base,FT_UInt charstring_len)1685   t1_decoder_parse_metrics( T1_Decoder  decoder,
1686                             FT_Byte*    charstring_base,
1687                             FT_UInt     charstring_len )
1688   {
1689     T1_Decoder_Zone  zone;
1690     FT_Byte*         ip;
1691     FT_Byte*         limit;
1692     T1_Builder       builder = &decoder->builder;
1693 
1694 #ifdef FT_DEBUG_LEVEL_TRACE
1695     FT_Bool          bol = TRUE;
1696 #endif
1697 
1698 
1699     /* First of all, initialize the decoder */
1700     decoder->top  = decoder->stack;
1701     decoder->zone = decoder->zones;
1702     zone          = decoder->zones;
1703 
1704     builder->parse_state = T1_Parse_Start;
1705 
1706     zone->base           = charstring_base;
1707     limit = zone->limit  = charstring_base + charstring_len;
1708     ip    = zone->cursor = zone->base;
1709 
1710     /* now, execute loop */
1711     while ( ip < limit )
1712     {
1713       FT_Long*     top   = decoder->top;
1714       T1_Operator  op    = op_none;
1715       FT_Int32     value = 0;
1716 
1717 
1718 #ifdef FT_DEBUG_LEVEL_TRACE
1719       if ( bol )
1720       {
1721         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
1722         bol = FALSE;
1723       }
1724 #endif
1725 
1726       /**********************************************************************
1727        *
1728        * Decode operator or operand
1729        *
1730        */
1731 
1732       /* first of all, decompress operator or value */
1733       switch ( *ip++ )
1734       {
1735       case 1:
1736       case 3:
1737       case 4:
1738       case 5:
1739       case 6:
1740       case 7:
1741       case 8:
1742       case 9:
1743       case 10:
1744       case 11:
1745       case 14:
1746       case 15:
1747       case 21:
1748       case 22:
1749       case 30:
1750       case 31:
1751         goto No_Width;
1752 
1753       case 13:
1754         op = op_hsbw;
1755         break;
1756 
1757       case 12:
1758         if ( ip >= limit )
1759         {
1760           FT_ERROR(( "t1_decoder_parse_metrics:"
1761                      " invalid escape (12+EOF)\n" ));
1762           goto Syntax_Error;
1763         }
1764 
1765         switch ( *ip++ )
1766         {
1767         case 7:
1768           op = op_sbw;
1769           break;
1770 
1771         default:
1772           goto No_Width;
1773         }
1774         break;
1775 
1776       case 255:    /* four bytes integer */
1777         if ( ip + 4 > limit )
1778         {
1779           FT_ERROR(( "t1_decoder_parse_metrics:"
1780                      " unexpected EOF in integer\n" ));
1781           goto Syntax_Error;
1782         }
1783 
1784         value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
1785                             ( (FT_UInt32)ip[1] << 16 ) |
1786                             ( (FT_UInt32)ip[2] << 8  ) |
1787                               (FT_UInt32)ip[3]         );
1788         ip += 4;
1789 
1790         /* According to the specification, values > 32000 or < -32000 must */
1791         /* be followed by a `div' operator to make the result be in the    */
1792         /* range [-32000;32000].  We expect that the second argument of    */
1793         /* `div' is not a large number.  Additionally, we don't handle     */
1794         /* stuff like `<large1> <large2> <num> div <num> div' or           */
1795         /* <large1> <large2> <num> div div'.  This is probably not allowed */
1796         /* anyway.                                                         */
1797         if ( value > 32000 || value < -32000 )
1798         {
1799           FT_ERROR(( "t1_decoder_parse_metrics:"
1800                      " large integer found for width\n" ));
1801           goto Syntax_Error;
1802         }
1803         else
1804         {
1805           value = (FT_Int32)( (FT_UInt32)value << 16 );
1806         }
1807 
1808         break;
1809 
1810       default:
1811         if ( ip[-1] >= 32 )
1812         {
1813           if ( ip[-1] < 247 )
1814             value = (FT_Int32)ip[-1] - 139;
1815           else
1816           {
1817             if ( ++ip > limit )
1818             {
1819               FT_ERROR(( "t1_decoder_parse_metrics:"
1820                          " unexpected EOF in integer\n" ));
1821               goto Syntax_Error;
1822             }
1823 
1824             if ( ip[-2] < 251 )
1825               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
1826             else
1827               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
1828           }
1829 
1830           value = (FT_Int32)( (FT_UInt32)value << 16 );
1831         }
1832         else
1833         {
1834           FT_ERROR(( "t1_decoder_parse_metrics:"
1835                      " invalid byte (%d)\n", ip[-1] ));
1836           goto Syntax_Error;
1837         }
1838       }
1839 
1840       /**********************************************************************
1841        *
1842        * Push value on stack, or process operator
1843        *
1844        */
1845       if ( op == op_none )
1846       {
1847         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
1848         {
1849           FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
1850           goto Syntax_Error;
1851         }
1852 
1853 #ifdef FT_DEBUG_LEVEL_TRACE
1854           FT_TRACE4(( " %d", value / 65536 ));
1855 #endif
1856 
1857         *top++       = value;
1858         decoder->top = top;
1859       }
1860       else  /* general operator */
1861       {
1862         FT_Int  num_args = t1_args_count[op];
1863 
1864 
1865         FT_ASSERT( num_args >= 0 );
1866 
1867         if ( top - decoder->stack < num_args )
1868           goto Stack_Underflow;
1869 
1870 #ifdef FT_DEBUG_LEVEL_TRACE
1871 
1872         if ( top - decoder->stack != num_args )
1873           FT_TRACE0(( "t1_decoder_parse_metrics:"
1874                       " too much operands on the stack"
1875                       " (seen %d, expected %d)\n",
1876                       top - decoder->stack, num_args ));
1877 
1878 #endif /* FT_DEBUG_LEVEL_TRACE */
1879 
1880         top -= num_args;
1881 
1882         switch ( op )
1883         {
1884         case op_hsbw:
1885           FT_TRACE4(( " hsbw" ));
1886 
1887           builder->parse_state = T1_Parse_Have_Width;
1888 
1889           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1890                                               top[0] );
1891 
1892           builder->advance.x = top[1];
1893           builder->advance.y = 0;
1894 
1895           /* we only want to compute the glyph's metrics */
1896           /* (lsb + advance width), not load the rest of */
1897           /* it; so exit immediately                     */
1898           FT_TRACE4(( "\n" ));
1899           return FT_Err_Ok;
1900 
1901         case op_sbw:
1902           FT_TRACE4(( " sbw" ));
1903 
1904           builder->parse_state = T1_Parse_Have_Width;
1905 
1906           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1907                                               top[0] );
1908           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1909                                               top[1] );
1910 
1911           builder->advance.x = top[2];
1912           builder->advance.y = top[3];
1913 
1914           /* we only want to compute the glyph's metrics */
1915           /* (lsb + advance width), not load the rest of */
1916           /* it; so exit immediately                     */
1917           FT_TRACE4(( "\n" ));
1918           return FT_Err_Ok;
1919 
1920         default:
1921           FT_ERROR(( "t1_decoder_parse_metrics:"
1922                      " unhandled opcode %d\n", op ));
1923           goto Syntax_Error;
1924         }
1925 
1926       } /* general operator processing */
1927 
1928     } /* while ip < limit */
1929 
1930     FT_TRACE4(( "..end..\n\n" ));
1931 
1932   No_Width:
1933     FT_ERROR(( "t1_decoder_parse_metrics:"
1934                " no width, found op %d instead\n",
1935                ip[-1] ));
1936   Syntax_Error:
1937     return FT_THROW( Syntax_Error );
1938 
1939   Stack_Underflow:
1940     return FT_THROW( Stack_Underflow );
1941   }
1942 
1943 #endif /* !T1_CONFIG_OPTION_OLD_ENGINE */
1944 
1945 
1946   /* initialize T1 decoder */
1947   FT_LOCAL_DEF( FT_Error )
t1_decoder_init(T1_Decoder decoder,FT_Face face,FT_Size size,FT_GlyphSlot slot,FT_Byte ** glyph_names,PS_Blend blend,FT_Bool hinting,FT_Render_Mode hint_mode,T1_Decoder_Callback parse_callback)1948   t1_decoder_init( T1_Decoder           decoder,
1949                    FT_Face              face,
1950                    FT_Size              size,
1951                    FT_GlyphSlot         slot,
1952                    FT_Byte**            glyph_names,
1953                    PS_Blend             blend,
1954                    FT_Bool              hinting,
1955                    FT_Render_Mode       hint_mode,
1956                    T1_Decoder_Callback  parse_callback )
1957   {
1958     FT_ZERO( decoder );
1959 
1960     /* retrieve PSNames interface from list of current modules */
1961     {
1962       FT_Service_PsCMaps  psnames;
1963 
1964 
1965       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1966       if ( !psnames )
1967       {
1968         FT_ERROR(( "t1_decoder_init:"
1969                    " the `psnames' module is not available\n" ));
1970         return FT_THROW( Unimplemented_Feature );
1971       }
1972 
1973       decoder->psnames = psnames;
1974     }
1975 
1976     t1_builder_init( &decoder->builder, face, size, slot, hinting );
1977 
1978     /* decoder->buildchar and decoder->len_buildchar have to be  */
1979     /* initialized by the caller since we cannot know the length */
1980     /* of the BuildCharArray                                     */
1981 
1982     decoder->num_glyphs     = (FT_UInt)face->num_glyphs;
1983     decoder->glyph_names    = glyph_names;
1984     decoder->hint_mode      = hint_mode;
1985     decoder->blend          = blend;
1986     decoder->parse_callback = parse_callback;
1987 
1988     decoder->funcs          = t1_decoder_funcs;
1989 
1990     return FT_Err_Ok;
1991   }
1992 
1993 
1994   /* finalize T1 decoder */
1995   FT_LOCAL_DEF( void )
t1_decoder_done(T1_Decoder decoder)1996   t1_decoder_done( T1_Decoder  decoder )
1997   {
1998     FT_Memory  memory = decoder->builder.memory;
1999 
2000 
2001     t1_builder_done( &decoder->builder );
2002 
2003     if ( decoder->cf2_instance.finalizer )
2004     {
2005       decoder->cf2_instance.finalizer( decoder->cf2_instance.data );
2006       FT_FREE( decoder->cf2_instance.data );
2007     }
2008   }
2009 
2010 
2011 /* END */
2012