• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cffgload.c                                                             */
4 /*                                                                         */
5 /*    OpenType Glyph Loader (body).                                        */
6 /*                                                                         */
7 /*  Copyright 1996-2011 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_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_INTERNAL_SFNT_H
23 #include FT_OUTLINE_H
24 
25 #include "cffobjs.h"
26 #include "cffload.h"
27 #include "cffgload.h"
28 
29 #include "cfferrs.h"
30 
31 
32   /*************************************************************************/
33   /*                                                                       */
34   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
35   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
36   /* messages during execution.                                            */
37   /*                                                                       */
38 #undef  FT_COMPONENT
39 #define FT_COMPONENT  trace_cffgload
40 
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   /*************************************************************************/
214   /*************************************************************************/
215   /*************************************************************************/
216   /**********                                                      *********/
217   /**********                                                      *********/
218   /**********             GENERIC CHARSTRING PARSING               *********/
219   /**********                                                      *********/
220   /**********                                                      *********/
221   /*************************************************************************/
222   /*************************************************************************/
223   /*************************************************************************/
224 
225 
226   /*************************************************************************/
227   /*                                                                       */
228   /* <Function>                                                            */
229   /*    cff_builder_init                                                   */
230   /*                                                                       */
231   /* <Description>                                                         */
232   /*    Initializes a given glyph builder.                                 */
233   /*                                                                       */
234   /* <InOut>                                                               */
235   /*    builder :: A pointer to the glyph builder to initialize.           */
236   /*                                                                       */
237   /* <Input>                                                               */
238   /*    face    :: The current face object.                                */
239   /*                                                                       */
240   /*    size    :: The current size object.                                */
241   /*                                                                       */
242   /*    glyph   :: The current glyph object.                               */
243   /*                                                                       */
244   /*    hinting :: Whether hinting is active.                              */
245   /*                                                                       */
246   static void
cff_builder_init(CFF_Builder * builder,TT_Face face,CFF_Size size,CFF_GlyphSlot glyph,FT_Bool hinting)247   cff_builder_init( CFF_Builder*   builder,
248                     TT_Face        face,
249                     CFF_Size       size,
250                     CFF_GlyphSlot  glyph,
251                     FT_Bool        hinting )
252   {
253     builder->path_begun  = 0;
254     builder->load_points = 1;
255 
256     builder->face   = face;
257     builder->glyph  = glyph;
258     builder->memory = face->root.memory;
259 
260     if ( glyph )
261     {
262       FT_GlyphLoader  loader = glyph->root.internal->loader;
263 
264 
265       builder->loader  = loader;
266       builder->base    = &loader->base.outline;
267       builder->current = &loader->current.outline;
268       FT_GlyphLoader_Rewind( loader );
269 
270       builder->hints_globals = 0;
271       builder->hints_funcs   = 0;
272 
273       if ( hinting && size )
274       {
275         CFF_Internal  internal = (CFF_Internal)size->root.internal;
276 
277 
278         builder->hints_globals = (void *)internal->topfont;
279         builder->hints_funcs   = glyph->root.internal->glyph_hints;
280       }
281     }
282 
283     builder->pos_x = 0;
284     builder->pos_y = 0;
285 
286     builder->left_bearing.x = 0;
287     builder->left_bearing.y = 0;
288     builder->advance.x      = 0;
289     builder->advance.y      = 0;
290   }
291 
292 
293   /*************************************************************************/
294   /*                                                                       */
295   /* <Function>                                                            */
296   /*    cff_builder_done                                                   */
297   /*                                                                       */
298   /* <Description>                                                         */
299   /*    Finalizes a given glyph builder.  Its contents can still be used   */
300   /*    after the call, but the function saves important information       */
301   /*    within the corresponding glyph slot.                               */
302   /*                                                                       */
303   /* <Input>                                                               */
304   /*    builder :: A pointer to the glyph builder to finalize.             */
305   /*                                                                       */
306   static void
cff_builder_done(CFF_Builder * builder)307   cff_builder_done( CFF_Builder*  builder )
308   {
309     CFF_GlyphSlot  glyph = builder->glyph;
310 
311 
312     if ( glyph )
313       glyph->root.outline = *builder->base;
314   }
315 
316 
317   /*************************************************************************/
318   /*                                                                       */
319   /* <Function>                                                            */
320   /*    cff_compute_bias                                                   */
321   /*                                                                       */
322   /* <Description>                                                         */
323   /*    Computes the bias value in dependence of the number of glyph       */
324   /*    subroutines.                                                       */
325   /*                                                                       */
326   /* <Input>                                                               */
327   /*    in_charstring_type :: The `CharstringType' value of the top DICT   */
328   /*                          dictionary.                                  */
329   /*                                                                       */
330   /*    num_subrs          :: The number of glyph subroutines.             */
331   /*                                                                       */
332   /* <Return>                                                              */
333   /*    The bias value.                                                    */
334   static FT_Int
cff_compute_bias(FT_Int in_charstring_type,FT_UInt num_subrs)335   cff_compute_bias( FT_Int   in_charstring_type,
336                     FT_UInt  num_subrs )
337   {
338     FT_Int  result;
339 
340 
341     if ( in_charstring_type == 1 )
342       result = 0;
343     else if ( num_subrs < 1240 )
344       result = 107;
345     else if ( num_subrs < 33900U )
346       result = 1131;
347     else
348       result = 32768U;
349 
350     return result;
351   }
352 
353 
354   /*************************************************************************/
355   /*                                                                       */
356   /* <Function>                                                            */
357   /*    cff_decoder_init                                                   */
358   /*                                                                       */
359   /* <Description>                                                         */
360   /*    Initializes a given glyph decoder.                                 */
361   /*                                                                       */
362   /* <InOut>                                                               */
363   /*    decoder :: A pointer to the glyph builder to initialize.           */
364   /*                                                                       */
365   /* <Input>                                                               */
366   /*    face      :: The current face object.                              */
367   /*                                                                       */
368   /*    size      :: The current size object.                              */
369   /*                                                                       */
370   /*    slot      :: The current glyph object.                             */
371   /*                                                                       */
372   /*    hinting   :: Whether hinting is active.                            */
373   /*                                                                       */
374   /*    hint_mode :: The hinting mode.                                     */
375   /*                                                                       */
376   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)377   cff_decoder_init( CFF_Decoder*    decoder,
378                     TT_Face         face,
379                     CFF_Size        size,
380                     CFF_GlyphSlot   slot,
381                     FT_Bool         hinting,
382                     FT_Render_Mode  hint_mode )
383   {
384     CFF_Font  cff = (CFF_Font)face->extra.data;
385 
386 
387     /* clear everything */
388     FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
389 
390     /* initialize builder */
391     cff_builder_init( &decoder->builder, face, size, slot, hinting );
392 
393     /* initialize Type2 decoder */
394     decoder->cff          = cff;
395     decoder->num_globals  = cff->global_subrs_index.count;
396     decoder->globals      = cff->global_subrs;
397     decoder->globals_bias = cff_compute_bias(
398                               cff->top_font.font_dict.charstring_type,
399                               decoder->num_globals );
400 
401     decoder->hint_mode    = hint_mode;
402   }
403 
404 
405   /* this function is used to select the subfont */
406   /* and the locals subrs array                  */
407   FT_LOCAL_DEF( FT_Error )
cff_decoder_prepare(CFF_Decoder * decoder,CFF_Size size,FT_UInt glyph_index)408   cff_decoder_prepare( CFF_Decoder*  decoder,
409                        CFF_Size      size,
410                        FT_UInt       glyph_index )
411   {
412     CFF_Builder  *builder = &decoder->builder;
413     CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
414     CFF_SubFont   sub     = &cff->top_font;
415     FT_Error      error   = CFF_Err_Ok;
416 
417 
418     /* manage CID fonts */
419     if ( cff->num_subfonts )
420     {
421       FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
422 
423 
424       if ( fd_index >= cff->num_subfonts )
425       {
426         FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
427         error = CFF_Err_Invalid_File_Format;
428         goto Exit;
429       }
430 
431       FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
432 
433       sub = cff->subfonts[fd_index];
434 
435       if ( builder->hints_funcs && size )
436       {
437         CFF_Internal  internal = (CFF_Internal)size->root.internal;
438 
439 
440         /* for CFFs without subfonts, this value has already been set */
441         builder->hints_globals = (void *)internal->subfonts[fd_index];
442       }
443     }
444 #ifdef FT_DEBUG_LEVEL_TRACE
445     else
446       FT_TRACE3(( "glyph index %d:\n", glyph_index ));
447 #endif
448 
449     decoder->num_locals    = sub->local_subrs_index.count;
450     decoder->locals        = sub->local_subrs;
451     decoder->locals_bias   = cff_compute_bias(
452                                decoder->cff->top_font.font_dict.charstring_type,
453                                decoder->num_locals );
454 
455     decoder->glyph_width   = sub->private_dict.default_width;
456     decoder->nominal_width = sub->private_dict.nominal_width;
457 
458   Exit:
459     return error;
460   }
461 
462 
463   /* check that there is enough space for `count' more points */
464   static FT_Error
check_points(CFF_Builder * builder,FT_Int count)465   check_points( CFF_Builder*  builder,
466                 FT_Int        count )
467   {
468     return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
469   }
470 
471 
472   /* add a new point, do not check space */
473   static void
cff_builder_add_point(CFF_Builder * builder,FT_Pos x,FT_Pos y,FT_Byte flag)474   cff_builder_add_point( CFF_Builder*  builder,
475                          FT_Pos        x,
476                          FT_Pos        y,
477                          FT_Byte       flag )
478   {
479     FT_Outline*  outline = builder->current;
480 
481 
482     if ( builder->load_points )
483     {
484       FT_Vector*  point   = outline->points + outline->n_points;
485       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
486 
487 
488       point->x = x >> 16;
489       point->y = y >> 16;
490       *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
491     }
492 
493     outline->n_points++;
494   }
495 
496 
497   /* check space for a new on-curve point, then add it */
498   static FT_Error
cff_builder_add_point1(CFF_Builder * builder,FT_Pos x,FT_Pos y)499   cff_builder_add_point1( CFF_Builder*  builder,
500                           FT_Pos        x,
501                           FT_Pos        y )
502   {
503     FT_Error  error;
504 
505 
506     error = check_points( builder, 1 );
507     if ( !error )
508       cff_builder_add_point( builder, x, y, 1 );
509 
510     return error;
511   }
512 
513 
514   /* check space for a new contour, then add it */
515   static FT_Error
cff_builder_add_contour(CFF_Builder * builder)516   cff_builder_add_contour( CFF_Builder*  builder )
517   {
518     FT_Outline*  outline = builder->current;
519     FT_Error     error;
520 
521 
522     if ( !builder->load_points )
523     {
524       outline->n_contours++;
525       return CFF_Err_Ok;
526     }
527 
528     error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
529     if ( !error )
530     {
531       if ( outline->n_contours > 0 )
532         outline->contours[outline->n_contours - 1] =
533           (short)( outline->n_points - 1 );
534 
535       outline->n_contours++;
536     }
537 
538     return error;
539   }
540 
541 
542   /* if a path was begun, add its first on-curve point */
543   static FT_Error
cff_builder_start_point(CFF_Builder * builder,FT_Pos x,FT_Pos y)544   cff_builder_start_point( CFF_Builder*  builder,
545                            FT_Pos        x,
546                            FT_Pos        y )
547   {
548     FT_Error  error = CFF_Err_Ok;
549 
550 
551     /* test whether we are building a new contour */
552     if ( !builder->path_begun )
553     {
554       builder->path_begun = 1;
555       error = cff_builder_add_contour( builder );
556       if ( !error )
557         error = cff_builder_add_point1( builder, x, y );
558     }
559 
560     return error;
561   }
562 
563 
564   /* close the current contour */
565   static void
cff_builder_close_contour(CFF_Builder * builder)566   cff_builder_close_contour( CFF_Builder*  builder )
567   {
568     FT_Outline*  outline = builder->current;
569     FT_Int       first;
570 
571 
572     if ( !outline )
573       return;
574 
575     first = outline->n_contours <= 1
576             ? 0 : outline->contours[outline->n_contours - 2] + 1;
577 
578     /* We must not include the last point in the path if it */
579     /* is located on the first point.                       */
580     if ( outline->n_points > 1 )
581     {
582       FT_Vector*  p1      = outline->points + first;
583       FT_Vector*  p2      = outline->points + outline->n_points - 1;
584       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;
585 
586 
587       /* `delete' last point only if it coincides with the first    */
588       /* point and if it is not a control point (which can happen). */
589       if ( p1->x == p2->x && p1->y == p2->y )
590         if ( *control == FT_CURVE_TAG_ON )
591           outline->n_points--;
592     }
593 
594     if ( outline->n_contours > 0 )
595     {
596       /* Don't add contours only consisting of one point, i.e., */
597       /* check whether begin point and last point are the same. */
598       if ( first == outline->n_points - 1 )
599       {
600         outline->n_contours--;
601         outline->n_points--;
602       }
603       else
604         outline->contours[outline->n_contours - 1] =
605           (short)( outline->n_points - 1 );
606     }
607   }
608 
609 
610   static FT_Int
cff_lookup_glyph_by_stdcharcode(CFF_Font cff,FT_Int charcode)611   cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,
612                                    FT_Int    charcode )
613   {
614     FT_UInt    n;
615     FT_UShort  glyph_sid;
616 
617 
618     /* CID-keyed fonts don't have glyph names */
619     if ( !cff->charset.sids )
620       return -1;
621 
622     /* check range of standard char code */
623     if ( charcode < 0 || charcode > 255 )
624       return -1;
625 
626     /* Get code to SID mapping from `cff_standard_encoding'. */
627     glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );
628 
629     for ( n = 0; n < cff->num_glyphs; n++ )
630     {
631       if ( cff->charset.sids[n] == glyph_sid )
632         return n;
633     }
634 
635     return -1;
636   }
637 
638 
639   static FT_Error
cff_get_glyph_data(TT_Face face,FT_UInt glyph_index,FT_Byte ** pointer,FT_ULong * length)640   cff_get_glyph_data( TT_Face    face,
641                       FT_UInt    glyph_index,
642                       FT_Byte**  pointer,
643                       FT_ULong*  length )
644   {
645 #ifdef FT_CONFIG_OPTION_INCREMENTAL
646     /* For incremental fonts get the character data using the */
647     /* callback function.                                     */
648     if ( face->root.internal->incremental_interface )
649     {
650       FT_Data   data;
651       FT_Error  error =
652                   face->root.internal->incremental_interface->funcs->get_glyph_data(
653                     face->root.internal->incremental_interface->object,
654                     glyph_index, &data );
655 
656 
657       *pointer = (FT_Byte*)data.pointer;
658       *length = data.length;
659 
660       return error;
661     }
662     else
663 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
664 
665     {
666       CFF_Font  cff  = (CFF_Font)(face->extra.data);
667 
668 
669       return cff_index_access_element( &cff->charstrings_index, glyph_index,
670                                        pointer, length );
671     }
672   }
673 
674 
675   static void
cff_free_glyph_data(TT_Face face,FT_Byte ** pointer,FT_ULong length)676   cff_free_glyph_data( TT_Face    face,
677                        FT_Byte**  pointer,
678                        FT_ULong   length )
679   {
680 #ifndef FT_CONFIG_OPTION_INCREMENTAL
681     FT_UNUSED( length );
682 #endif
683 
684 #ifdef FT_CONFIG_OPTION_INCREMENTAL
685     /* For incremental fonts get the character data using the */
686     /* callback function.                                     */
687     if ( face->root.internal->incremental_interface )
688     {
689       FT_Data data;
690 
691 
692       data.pointer = *pointer;
693       data.length  = length;
694 
695       face->root.internal->incremental_interface->funcs->free_glyph_data(
696         face->root.internal->incremental_interface->object, &data );
697     }
698     else
699 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
700 
701     {
702       CFF_Font  cff = (CFF_Font)(face->extra.data);
703 
704 
705       cff_index_forget_element( &cff->charstrings_index, pointer );
706     }
707   }
708 
709 
710   static FT_Error
cff_operator_seac(CFF_Decoder * decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)711   cff_operator_seac( CFF_Decoder*  decoder,
712                      FT_Pos        asb,
713                      FT_Pos        adx,
714                      FT_Pos        ady,
715                      FT_Int        bchar,
716                      FT_Int        achar )
717   {
718     FT_Error      error;
719     CFF_Builder*  builder = &decoder->builder;
720     FT_Int        bchar_index, achar_index;
721     TT_Face       face = decoder->builder.face;
722     FT_Vector     left_bearing, advance;
723     FT_Byte*      charstring;
724     FT_ULong      charstring_len;
725     FT_Pos        glyph_width;
726 
727 
728     if ( decoder->seac )
729     {
730       FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
731       return CFF_Err_Syntax_Error;
732     }
733 
734     adx += decoder->builder.left_bearing.x;
735     ady += decoder->builder.left_bearing.y;
736 
737 #ifdef FT_CONFIG_OPTION_INCREMENTAL
738     /* Incremental fonts don't necessarily have valid charsets.        */
739     /* They use the character code, not the glyph index, in this case. */
740     if ( face->root.internal->incremental_interface )
741     {
742       bchar_index = bchar;
743       achar_index = achar;
744     }
745     else
746 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
747     {
748       CFF_Font cff = (CFF_Font)(face->extra.data);
749 
750 
751       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
752       achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
753     }
754 
755     if ( bchar_index < 0 || achar_index < 0 )
756     {
757       FT_ERROR(( "cff_operator_seac:"
758                  " invalid seac character code arguments\n" ));
759       return CFF_Err_Syntax_Error;
760     }
761 
762     /* If we are trying to load a composite glyph, do not load the */
763     /* accent character and return the array of subglyphs.         */
764     if ( builder->no_recurse )
765     {
766       FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;
767       FT_GlyphLoader  loader = glyph->internal->loader;
768       FT_SubGlyph     subg;
769 
770 
771       /* reallocate subglyph array if necessary */
772       error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
773       if ( error )
774         goto Exit;
775 
776       subg = loader->current.subglyphs;
777 
778       /* subglyph 0 = base character */
779       subg->index = bchar_index;
780       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
781                     FT_SUBGLYPH_FLAG_USE_MY_METRICS;
782       subg->arg1  = 0;
783       subg->arg2  = 0;
784       subg++;
785 
786       /* subglyph 1 = accent character */
787       subg->index = achar_index;
788       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
789       subg->arg1  = (FT_Int)( adx >> 16 );
790       subg->arg2  = (FT_Int)( ady >> 16 );
791 
792       /* set up remaining glyph fields */
793       glyph->num_subglyphs = 2;
794       glyph->subglyphs     = loader->base.subglyphs;
795       glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
796 
797       loader->current.num_subglyphs = 2;
798     }
799 
800     FT_GlyphLoader_Prepare( builder->loader );
801 
802     /* First load `bchar' in builder */
803     error = cff_get_glyph_data( face, bchar_index,
804                                 &charstring, &charstring_len );
805     if ( !error )
806     {
807       /* the seac operator must not be nested */
808       decoder->seac = TRUE;
809       error = cff_decoder_parse_charstrings( decoder, charstring,
810                                              charstring_len );
811       decoder->seac = FALSE;
812 
813       cff_free_glyph_data( face, &charstring, charstring_len );
814 
815       if ( error )
816         goto Exit;
817     }
818 
819     /* Save the left bearing, advance and glyph width of the base */
820     /* character as they will be erased by the next load.         */
821 
822     left_bearing = builder->left_bearing;
823     advance      = builder->advance;
824     glyph_width  = decoder->glyph_width;
825 
826     builder->left_bearing.x = 0;
827     builder->left_bearing.y = 0;
828 
829     builder->pos_x = adx - asb;
830     builder->pos_y = ady;
831 
832     /* Now load `achar' on top of the base outline. */
833     error = cff_get_glyph_data( face, achar_index,
834                                 &charstring, &charstring_len );
835     if ( !error )
836     {
837       /* the seac operator must not be nested */
838       decoder->seac = TRUE;
839       error = cff_decoder_parse_charstrings( decoder, charstring,
840                                              charstring_len );
841       decoder->seac = FALSE;
842 
843       cff_free_glyph_data( face, &charstring, charstring_len );
844 
845       if ( error )
846         goto Exit;
847     }
848 
849     /* Restore the left side bearing, advance and glyph width */
850     /* of the base character.                                 */
851     builder->left_bearing = left_bearing;
852     builder->advance      = advance;
853     decoder->glyph_width  = glyph_width;
854 
855     builder->pos_x = 0;
856     builder->pos_y = 0;
857 
858   Exit:
859     return error;
860   }
861 
862 
863   /*************************************************************************/
864   /*                                                                       */
865   /* <Function>                                                            */
866   /*    cff_decoder_parse_charstrings                                      */
867   /*                                                                       */
868   /* <Description>                                                         */
869   /*    Parses a given Type 2 charstrings program.                         */
870   /*                                                                       */
871   /* <InOut>                                                               */
872   /*    decoder         :: The current Type 1 decoder.                     */
873   /*                                                                       */
874   /* <Input>                                                               */
875   /*    charstring_base :: The base of the charstring stream.              */
876   /*                                                                       */
877   /*    charstring_len  :: The length in bytes of the charstring stream.   */
878   /*                                                                       */
879   /* <Return>                                                              */
880   /*    FreeType error code.  0 means success.                             */
881   /*                                                                       */
882   FT_LOCAL_DEF( FT_Error )
cff_decoder_parse_charstrings(CFF_Decoder * decoder,FT_Byte * charstring_base,FT_ULong charstring_len)883   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
884                                  FT_Byte*      charstring_base,
885                                  FT_ULong      charstring_len )
886   {
887     FT_Error           error;
888     CFF_Decoder_Zone*  zone;
889     FT_Byte*           ip;
890     FT_Byte*           limit;
891     CFF_Builder*       builder = &decoder->builder;
892     FT_Pos             x, y;
893     FT_Fixed           seed;
894     FT_Fixed*          stack;
895     FT_Int             charstring_type =
896                          decoder->cff->top_font.font_dict.charstring_type;
897 
898     T2_Hints_Funcs     hinter;
899 
900 
901     /* set default width */
902     decoder->num_hints  = 0;
903     decoder->read_width = 1;
904 
905     /* compute random seed from stack address of parameter */
906     seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
907                          (FT_PtrDist)(char*)&decoder           ^
908                          (FT_PtrDist)(char*)&charstring_base ) &
909                          FT_ULONG_MAX ) ;
910     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
911     if ( seed == 0 )
912       seed = 0x7384;
913 
914     /* initialize the decoder */
915     decoder->top  = decoder->stack;
916     decoder->zone = decoder->zones;
917     zone          = decoder->zones;
918     stack         = decoder->top;
919 
920     hinter = (T2_Hints_Funcs)builder->hints_funcs;
921 
922     builder->path_begun = 0;
923 
924     zone->base           = charstring_base;
925     limit = zone->limit  = charstring_base + charstring_len;
926     ip    = zone->cursor = zone->base;
927 
928     error = CFF_Err_Ok;
929 
930     x = builder->pos_x;
931     y = builder->pos_y;
932 
933     /* begin hints recording session, if any */
934     if ( hinter )
935       hinter->open( hinter->hints );
936 
937     /* now execute loop */
938     while ( ip < limit )
939     {
940       CFF_Operator  op;
941       FT_Byte       v;
942 
943 
944       /********************************************************************/
945       /*                                                                  */
946       /* Decode operator or operand                                       */
947       /*                                                                  */
948       v = *ip++;
949       if ( v >= 32 || v == 28 )
950       {
951         FT_Int    shift = 16;
952         FT_Int32  val;
953 
954 
955         /* this is an operand, push it on the stack */
956         if ( v == 28 )
957         {
958           if ( ip + 1 >= limit )
959             goto Syntax_Error;
960           val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );
961           ip += 2;
962         }
963         else if ( v < 247 )
964           val = (FT_Int32)v - 139;
965         else if ( v < 251 )
966         {
967           if ( ip >= limit )
968             goto Syntax_Error;
969           val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
970         }
971         else if ( v < 255 )
972         {
973           if ( ip >= limit )
974             goto Syntax_Error;
975           val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
976         }
977         else
978         {
979           if ( ip + 3 >= limit )
980             goto Syntax_Error;
981           val = ( (FT_Int32)ip[0] << 24 ) |
982                 ( (FT_Int32)ip[1] << 16 ) |
983                 ( (FT_Int32)ip[2] <<  8 ) |
984                             ip[3];
985           ip    += 4;
986           if ( charstring_type == 2 )
987             shift = 0;
988         }
989         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
990           goto Stack_Overflow;
991 
992         val           <<= shift;
993         *decoder->top++ = val;
994 
995 #ifdef FT_DEBUG_LEVEL_TRACE
996         if ( !( val & 0xFFFFL ) )
997           FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));
998         else
999           FT_TRACE4(( " %.2f", val / 65536.0 ));
1000 #endif
1001 
1002       }
1003       else
1004       {
1005         /* The specification says that normally arguments are to be taken */
1006         /* from the bottom of the stack.  However, this seems not to be   */
1007         /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
1008         /* arguments similar to a PS interpreter.                         */
1009 
1010         FT_Fixed*  args     = decoder->top;
1011         FT_Int     num_args = (FT_Int)( args - decoder->stack );
1012         FT_Int     req_args;
1013 
1014 
1015         /* find operator */
1016         op = cff_op_unknown;
1017 
1018         switch ( v )
1019         {
1020         case 1:
1021           op = cff_op_hstem;
1022           break;
1023         case 3:
1024           op = cff_op_vstem;
1025           break;
1026         case 4:
1027           op = cff_op_vmoveto;
1028           break;
1029         case 5:
1030           op = cff_op_rlineto;
1031           break;
1032         case 6:
1033           op = cff_op_hlineto;
1034           break;
1035         case 7:
1036           op = cff_op_vlineto;
1037           break;
1038         case 8:
1039           op = cff_op_rrcurveto;
1040           break;
1041         case 9:
1042           op = cff_op_closepath;
1043           break;
1044         case 10:
1045           op = cff_op_callsubr;
1046           break;
1047         case 11:
1048           op = cff_op_return;
1049           break;
1050         case 12:
1051           {
1052             if ( ip >= limit )
1053               goto Syntax_Error;
1054             v = *ip++;
1055 
1056             switch ( v )
1057             {
1058             case 0:
1059               op = cff_op_dotsection;
1060               break;
1061             case 1: /* this is actually the Type1 vstem3 operator */
1062               op = cff_op_vstem;
1063               break;
1064             case 2: /* this is actually the Type1 hstem3 operator */
1065               op = cff_op_hstem;
1066               break;
1067             case 3:
1068               op = cff_op_and;
1069               break;
1070             case 4:
1071               op = cff_op_or;
1072               break;
1073             case 5:
1074               op = cff_op_not;
1075               break;
1076             case 6:
1077               op = cff_op_seac;
1078               break;
1079             case 7:
1080               op = cff_op_sbw;
1081               break;
1082             case 8:
1083               op = cff_op_store;
1084               break;
1085             case 9:
1086               op = cff_op_abs;
1087               break;
1088             case 10:
1089               op = cff_op_add;
1090               break;
1091             case 11:
1092               op = cff_op_sub;
1093               break;
1094             case 12:
1095               op = cff_op_div;
1096               break;
1097             case 13:
1098               op = cff_op_load;
1099               break;
1100             case 14:
1101               op = cff_op_neg;
1102               break;
1103             case 15:
1104               op = cff_op_eq;
1105               break;
1106             case 16:
1107               op = cff_op_callothersubr;
1108               break;
1109             case 17:
1110               op = cff_op_pop;
1111               break;
1112             case 18:
1113               op = cff_op_drop;
1114               break;
1115             case 20:
1116               op = cff_op_put;
1117               break;
1118             case 21:
1119               op = cff_op_get;
1120               break;
1121             case 22:
1122               op = cff_op_ifelse;
1123               break;
1124             case 23:
1125               op = cff_op_random;
1126               break;
1127             case 24:
1128               op = cff_op_mul;
1129               break;
1130             case 26:
1131               op = cff_op_sqrt;
1132               break;
1133             case 27:
1134               op = cff_op_dup;
1135               break;
1136             case 28:
1137               op = cff_op_exch;
1138               break;
1139             case 29:
1140               op = cff_op_index;
1141               break;
1142             case 30:
1143               op = cff_op_roll;
1144               break;
1145             case 33:
1146               op = cff_op_setcurrentpoint;
1147               break;
1148             case 34:
1149               op = cff_op_hflex;
1150               break;
1151             case 35:
1152               op = cff_op_flex;
1153               break;
1154             case 36:
1155               op = cff_op_hflex1;
1156               break;
1157             case 37:
1158               op = cff_op_flex1;
1159               break;
1160             default:
1161               FT_TRACE4(( " unknown op (12, %d)\n", v ));
1162               break;
1163             }
1164           }
1165           break;
1166         case 13:
1167           op = cff_op_hsbw;
1168           break;
1169         case 14:
1170           op = cff_op_endchar;
1171           break;
1172         case 16:
1173           op = cff_op_blend;
1174           break;
1175         case 18:
1176           op = cff_op_hstemhm;
1177           break;
1178         case 19:
1179           op = cff_op_hintmask;
1180           break;
1181         case 20:
1182           op = cff_op_cntrmask;
1183           break;
1184         case 21:
1185           op = cff_op_rmoveto;
1186           break;
1187         case 22:
1188           op = cff_op_hmoveto;
1189           break;
1190         case 23:
1191           op = cff_op_vstemhm;
1192           break;
1193         case 24:
1194           op = cff_op_rcurveline;
1195           break;
1196         case 25:
1197           op = cff_op_rlinecurve;
1198           break;
1199         case 26:
1200           op = cff_op_vvcurveto;
1201           break;
1202         case 27:
1203           op = cff_op_hhcurveto;
1204           break;
1205         case 29:
1206           op = cff_op_callgsubr;
1207           break;
1208         case 30:
1209           op = cff_op_vhcurveto;
1210           break;
1211         case 31:
1212           op = cff_op_hvcurveto;
1213           break;
1214         default:
1215           FT_TRACE4(( " unknown op (%d)\n", v ));
1216           break;
1217         }
1218 
1219         if ( op == cff_op_unknown )
1220           continue;
1221 
1222         /* check arguments */
1223         req_args = cff_argument_counts[op];
1224         if ( req_args & CFF_COUNT_CHECK_WIDTH )
1225         {
1226           if ( num_args > 0 && decoder->read_width )
1227           {
1228             /* If `nominal_width' is non-zero, the number is really a      */
1229             /* difference against `nominal_width'.  Else, the number here  */
1230             /* is truly a width, not a difference against `nominal_width'. */
1231             /* If the font does not set `nominal_width', then              */
1232             /* `nominal_width' defaults to zero, and so we can set         */
1233             /* `glyph_width' to `nominal_width' plus number on the stack   */
1234             /* -- for either case.                                         */
1235 
1236             FT_Int  set_width_ok;
1237 
1238 
1239             switch ( op )
1240             {
1241             case cff_op_hmoveto:
1242             case cff_op_vmoveto:
1243               set_width_ok = num_args & 2;
1244               break;
1245 
1246             case cff_op_hstem:
1247             case cff_op_vstem:
1248             case cff_op_hstemhm:
1249             case cff_op_vstemhm:
1250             case cff_op_rmoveto:
1251             case cff_op_hintmask:
1252             case cff_op_cntrmask:
1253               set_width_ok = num_args & 1;
1254               break;
1255 
1256             case cff_op_endchar:
1257               /* If there is a width specified for endchar, we either have */
1258               /* 1 argument or 5 arguments.  We like to argue.             */
1259               set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
1260               break;
1261 
1262             default:
1263               set_width_ok = 0;
1264               break;
1265             }
1266 
1267             if ( set_width_ok )
1268             {
1269               decoder->glyph_width = decoder->nominal_width +
1270                                        ( stack[0] >> 16 );
1271 
1272               if ( decoder->width_only )
1273               {
1274                 /* we only want the advance width; stop here */
1275                 break;
1276               }
1277 
1278               /* Consumed an argument. */
1279               num_args--;
1280             }
1281           }
1282 
1283           decoder->read_width = 0;
1284           req_args            = 0;
1285         }
1286 
1287         req_args &= 0x000F;
1288         if ( num_args < req_args )
1289           goto Stack_Underflow;
1290         args     -= req_args;
1291         num_args -= req_args;
1292 
1293         /* At this point, `args' points to the first argument of the  */
1294         /* operand in case `req_args' isn't zero.  Otherwise, we have */
1295         /* to adjust `args' manually.                                 */
1296 
1297         /* Note that we only pop arguments from the stack which we    */
1298         /* really need and can digest so that we can continue in case */
1299         /* of superfluous stack elements.                             */
1300 
1301         switch ( op )
1302         {
1303         case cff_op_hstem:
1304         case cff_op_vstem:
1305         case cff_op_hstemhm:
1306         case cff_op_vstemhm:
1307           /* the number of arguments is always even here */
1308           FT_TRACE4((
1309               op == cff_op_hstem   ? " hstem\n"   :
1310             ( op == cff_op_vstem   ? " vstem\n"   :
1311             ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
1312 
1313           if ( hinter )
1314             hinter->stems( hinter->hints,
1315                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
1316                            num_args / 2,
1317                            args - ( num_args & ~1 ) );
1318 
1319           decoder->num_hints += num_args / 2;
1320           args = stack;
1321           break;
1322 
1323         case cff_op_hintmask:
1324         case cff_op_cntrmask:
1325           FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
1326 
1327           /* implement vstem when needed --                        */
1328           /* the specification doesn't say it, but this also works */
1329           /* with the 'cntrmask' operator                          */
1330           /*                                                       */
1331           if ( num_args > 0 )
1332           {
1333             if ( hinter )
1334               hinter->stems( hinter->hints,
1335                              0,
1336                              num_args / 2,
1337                              args - ( num_args & ~1 ) );
1338 
1339             decoder->num_hints += num_args / 2;
1340           }
1341 
1342           /* In a valid charstring there must be at least one byte */
1343           /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
1344           /* instruction).  Additionally, there must be space for  */
1345           /* `num_hints' bits.                                     */
1346 
1347           if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
1348             goto Syntax_Error;
1349 
1350           if ( hinter )
1351           {
1352             if ( op == cff_op_hintmask )
1353               hinter->hintmask( hinter->hints,
1354                                 builder->current->n_points,
1355                                 decoder->num_hints,
1356                                 ip );
1357             else
1358               hinter->counter( hinter->hints,
1359                                decoder->num_hints,
1360                                ip );
1361           }
1362 
1363 #ifdef FT_DEBUG_LEVEL_TRACE
1364           {
1365             FT_UInt maskbyte;
1366 
1367 
1368             FT_TRACE4(( " (maskbytes:" ));
1369 
1370             for ( maskbyte = 0;
1371                   maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1372                   maskbyte++, ip++ )
1373               FT_TRACE4(( " 0x%02X", *ip ));
1374 
1375             FT_TRACE4(( ")\n" ));
1376           }
1377 #else
1378           ip += ( decoder->num_hints + 7 ) >> 3;
1379 #endif
1380           args = stack;
1381           break;
1382 
1383         case cff_op_rmoveto:
1384           FT_TRACE4(( " rmoveto\n" ));
1385 
1386           cff_builder_close_contour( builder );
1387           builder->path_begun = 0;
1388           x   += args[-2];
1389           y   += args[-1];
1390           args = stack;
1391           break;
1392 
1393         case cff_op_vmoveto:
1394           FT_TRACE4(( " vmoveto\n" ));
1395 
1396           cff_builder_close_contour( builder );
1397           builder->path_begun = 0;
1398           y   += args[-1];
1399           args = stack;
1400           break;
1401 
1402         case cff_op_hmoveto:
1403           FT_TRACE4(( " hmoveto\n" ));
1404 
1405           cff_builder_close_contour( builder );
1406           builder->path_begun = 0;
1407           x   += args[-1];
1408           args = stack;
1409           break;
1410 
1411         case cff_op_rlineto:
1412           FT_TRACE4(( " rlineto\n" ));
1413 
1414           if ( cff_builder_start_point ( builder, x, y ) ||
1415                check_points( builder, num_args / 2 )     )
1416             goto Fail;
1417 
1418           if ( num_args < 2 )
1419             goto Stack_Underflow;
1420 
1421           args -= num_args & ~1;
1422           while ( args < decoder->top )
1423           {
1424             x += args[0];
1425             y += args[1];
1426             cff_builder_add_point( builder, x, y, 1 );
1427             args += 2;
1428           }
1429           args = stack;
1430           break;
1431 
1432         case cff_op_hlineto:
1433         case cff_op_vlineto:
1434           {
1435             FT_Int  phase = ( op == cff_op_hlineto );
1436 
1437 
1438             FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1439                                              : " vlineto\n" ));
1440 
1441             if ( num_args < 0 )
1442               goto Stack_Underflow;
1443 
1444             /* there exist subsetted fonts (found in PDFs) */
1445             /* which call `hlineto' without arguments      */
1446             if ( num_args == 0 )
1447               break;
1448 
1449             if ( cff_builder_start_point ( builder, x, y ) ||
1450                  check_points( builder, num_args )         )
1451               goto Fail;
1452 
1453             args = stack;
1454             while ( args < decoder->top )
1455             {
1456               if ( phase )
1457                 x += args[0];
1458               else
1459                 y += args[0];
1460 
1461               if ( cff_builder_add_point1( builder, x, y ) )
1462                 goto Fail;
1463 
1464               args++;
1465               phase ^= 1;
1466             }
1467             args = stack;
1468           }
1469           break;
1470 
1471         case cff_op_rrcurveto:
1472           {
1473             FT_Int  nargs;
1474 
1475 
1476             FT_TRACE4(( " rrcurveto\n" ));
1477 
1478             if ( num_args < 6 )
1479               goto Stack_Underflow;
1480 
1481             nargs = num_args - num_args % 6;
1482 
1483             if ( cff_builder_start_point ( builder, x, y ) ||
1484                  check_points( builder, nargs / 2 )     )
1485               goto Fail;
1486 
1487             args -= nargs;
1488             while ( args < decoder->top )
1489             {
1490               x += args[0];
1491               y += args[1];
1492               cff_builder_add_point( builder, x, y, 0 );
1493               x += args[2];
1494               y += args[3];
1495               cff_builder_add_point( builder, x, y, 0 );
1496               x += args[4];
1497               y += args[5];
1498               cff_builder_add_point( builder, x, y, 1 );
1499               args += 6;
1500             }
1501             args = stack;
1502           }
1503           break;
1504 
1505         case cff_op_vvcurveto:
1506           {
1507             FT_Int  nargs;
1508 
1509 
1510             FT_TRACE4(( " vvcurveto\n" ));
1511 
1512             if ( num_args < 4 )
1513               goto Stack_Underflow;
1514 
1515             /* if num_args isn't of the form 4n or 4n+1, */
1516             /* we reduce it to 4n+1                      */
1517 
1518             nargs = num_args - num_args % 4;
1519             if ( num_args - nargs > 0 )
1520               nargs += 1;
1521 
1522             if ( cff_builder_start_point( builder, x, y ) )
1523               goto Fail;
1524 
1525             args -= nargs;
1526 
1527             if ( nargs & 1 )
1528             {
1529               x += args[0];
1530               args++;
1531               nargs--;
1532             }
1533 
1534             if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1535               goto Fail;
1536 
1537             while ( args < decoder->top )
1538             {
1539               y += args[0];
1540               cff_builder_add_point( builder, x, y, 0 );
1541               x += args[1];
1542               y += args[2];
1543               cff_builder_add_point( builder, x, y, 0 );
1544               y += args[3];
1545               cff_builder_add_point( builder, x, y, 1 );
1546               args += 4;
1547             }
1548             args = stack;
1549           }
1550           break;
1551 
1552         case cff_op_hhcurveto:
1553           {
1554             FT_Int  nargs;
1555 
1556 
1557             FT_TRACE4(( " hhcurveto\n" ));
1558 
1559             if ( num_args < 4 )
1560               goto Stack_Underflow;
1561 
1562             /* if num_args isn't of the form 4n or 4n+1, */
1563             /* we reduce it to 4n+1                      */
1564 
1565             nargs = num_args - num_args % 4;
1566             if ( num_args - nargs > 0 )
1567               nargs += 1;
1568 
1569             if ( cff_builder_start_point( builder, x, y ) )
1570               goto Fail;
1571 
1572             args -= nargs;
1573             if ( nargs & 1 )
1574             {
1575               y += args[0];
1576               args++;
1577               nargs--;
1578             }
1579 
1580             if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1581               goto Fail;
1582 
1583             while ( args < decoder->top )
1584             {
1585               x += args[0];
1586               cff_builder_add_point( builder, x, y, 0 );
1587               x += args[1];
1588               y += args[2];
1589               cff_builder_add_point( builder, x, y, 0 );
1590               x += args[3];
1591               cff_builder_add_point( builder, x, y, 1 );
1592               args += 4;
1593             }
1594             args = stack;
1595           }
1596           break;
1597 
1598         case cff_op_vhcurveto:
1599         case cff_op_hvcurveto:
1600           {
1601             FT_Int  phase;
1602             FT_Int  nargs;
1603 
1604 
1605             FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1606                                                : " hvcurveto\n" ));
1607 
1608             if ( cff_builder_start_point( builder, x, y ) )
1609               goto Fail;
1610 
1611             if ( num_args < 4 )
1612               goto Stack_Underflow;
1613 
1614             /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1615             /* we reduce it to the largest one which fits             */
1616 
1617             nargs = num_args - num_args % 4;
1618             if ( num_args - nargs > 0 )
1619               nargs += 1;
1620 
1621             args -= nargs;
1622             if ( check_points( builder, ( nargs / 4 ) * 3 ) )
1623               goto Stack_Underflow;
1624 
1625             phase = ( op == cff_op_hvcurveto );
1626 
1627             while ( nargs >= 4 )
1628             {
1629               nargs -= 4;
1630               if ( phase )
1631               {
1632                 x += args[0];
1633                 cff_builder_add_point( builder, x, y, 0 );
1634                 x += args[1];
1635                 y += args[2];
1636                 cff_builder_add_point( builder, x, y, 0 );
1637                 y += args[3];
1638                 if ( nargs == 1 )
1639                   x += args[4];
1640                 cff_builder_add_point( builder, x, y, 1 );
1641               }
1642               else
1643               {
1644                 y += args[0];
1645                 cff_builder_add_point( builder, x, y, 0 );
1646                 x += args[1];
1647                 y += args[2];
1648                 cff_builder_add_point( builder, x, y, 0 );
1649                 x += args[3];
1650                 if ( nargs == 1 )
1651                   y += args[4];
1652                 cff_builder_add_point( builder, x, y, 1 );
1653               }
1654               args  += 4;
1655               phase ^= 1;
1656             }
1657             args = stack;
1658           }
1659           break;
1660 
1661         case cff_op_rlinecurve:
1662           {
1663             FT_Int  num_lines;
1664             FT_Int  nargs;
1665 
1666 
1667             FT_TRACE4(( " rlinecurve\n" ));
1668 
1669             if ( num_args < 8 )
1670               goto Stack_Underflow;
1671 
1672             nargs     = num_args & ~1;
1673             num_lines = ( nargs - 6 ) / 2;
1674 
1675             if ( cff_builder_start_point( builder, x, y ) ||
1676                  check_points( builder, num_lines + 3 )   )
1677               goto Fail;
1678 
1679             args -= nargs;
1680 
1681             /* first, add the line segments */
1682             while ( num_lines > 0 )
1683             {
1684               x += args[0];
1685               y += args[1];
1686               cff_builder_add_point( builder, x, y, 1 );
1687               args += 2;
1688               num_lines--;
1689             }
1690 
1691             /* then the curve */
1692             x += args[0];
1693             y += args[1];
1694             cff_builder_add_point( builder, x, y, 0 );
1695             x += args[2];
1696             y += args[3];
1697             cff_builder_add_point( builder, x, y, 0 );
1698             x += args[4];
1699             y += args[5];
1700             cff_builder_add_point( builder, x, y, 1 );
1701             args = stack;
1702           }
1703           break;
1704 
1705         case cff_op_rcurveline:
1706           {
1707             FT_Int  num_curves;
1708             FT_Int  nargs;
1709 
1710 
1711             FT_TRACE4(( " rcurveline\n" ));
1712 
1713             if ( num_args < 8 )
1714               goto Stack_Underflow;
1715 
1716             nargs      = num_args - 2;
1717             nargs      = nargs - nargs % 6 + 2;
1718             num_curves = ( nargs - 2 ) / 6;
1719 
1720             if ( cff_builder_start_point ( builder, x, y ) ||
1721                  check_points( builder, num_curves * 3 + 2 ) )
1722               goto Fail;
1723 
1724             args -= nargs;
1725 
1726             /* first, add the curves */
1727             while ( num_curves > 0 )
1728             {
1729               x += args[0];
1730               y += args[1];
1731               cff_builder_add_point( builder, x, y, 0 );
1732               x += args[2];
1733               y += args[3];
1734               cff_builder_add_point( builder, x, y, 0 );
1735               x += args[4];
1736               y += args[5];
1737               cff_builder_add_point( builder, x, y, 1 );
1738               args += 6;
1739               num_curves--;
1740             }
1741 
1742             /* then the final line */
1743             x += args[0];
1744             y += args[1];
1745             cff_builder_add_point( builder, x, y, 1 );
1746             args = stack;
1747           }
1748           break;
1749 
1750         case cff_op_hflex1:
1751           {
1752             FT_Pos start_y;
1753 
1754 
1755             FT_TRACE4(( " hflex1\n" ));
1756 
1757             /* adding five more points: 4 control points, 1 on-curve point */
1758             /* -- make sure we have enough space for the start point if it */
1759             /* needs to be added                                           */
1760             if ( cff_builder_start_point( builder, x, y ) ||
1761                  check_points( builder, 6 )               )
1762               goto Fail;
1763 
1764             /* record the starting point's y position for later use */
1765             start_y = y;
1766 
1767             /* first control point */
1768             x += args[0];
1769             y += args[1];
1770             cff_builder_add_point( builder, x, y, 0 );
1771 
1772             /* second control point */
1773             x += args[2];
1774             y += args[3];
1775             cff_builder_add_point( builder, x, y, 0 );
1776 
1777             /* join point; on curve, with y-value the same as the last */
1778             /* control point's y-value                                 */
1779             x += args[4];
1780             cff_builder_add_point( builder, x, y, 1 );
1781 
1782             /* third control point, with y-value the same as the join */
1783             /* point's y-value                                        */
1784             x += args[5];
1785             cff_builder_add_point( builder, x, y, 0 );
1786 
1787             /* fourth control point */
1788             x += args[6];
1789             y += args[7];
1790             cff_builder_add_point( builder, x, y, 0 );
1791 
1792             /* ending point, with y-value the same as the start   */
1793             x += args[8];
1794             y  = start_y;
1795             cff_builder_add_point( builder, x, y, 1 );
1796 
1797             args = stack;
1798             break;
1799           }
1800 
1801         case cff_op_hflex:
1802           {
1803             FT_Pos start_y;
1804 
1805 
1806             FT_TRACE4(( " hflex\n" ));
1807 
1808             /* adding six more points; 4 control points, 2 on-curve points */
1809             if ( cff_builder_start_point( builder, x, y ) ||
1810                  check_points( builder, 6 )               )
1811               goto Fail;
1812 
1813             /* record the starting point's y-position for later use */
1814             start_y = y;
1815 
1816             /* first control point */
1817             x += args[0];
1818             cff_builder_add_point( builder, x, y, 0 );
1819 
1820             /* second control point */
1821             x += args[1];
1822             y += args[2];
1823             cff_builder_add_point( builder, x, y, 0 );
1824 
1825             /* join point; on curve, with y-value the same as the last */
1826             /* control point's y-value                                 */
1827             x += args[3];
1828             cff_builder_add_point( builder, x, y, 1 );
1829 
1830             /* third control point, with y-value the same as the join */
1831             /* point's y-value                                        */
1832             x += args[4];
1833             cff_builder_add_point( builder, x, y, 0 );
1834 
1835             /* fourth control point */
1836             x += args[5];
1837             y  = start_y;
1838             cff_builder_add_point( builder, x, y, 0 );
1839 
1840             /* ending point, with y-value the same as the start point's */
1841             /* y-value -- we don't add this point, though               */
1842             x += args[6];
1843             cff_builder_add_point( builder, x, y, 1 );
1844 
1845             args = stack;
1846             break;
1847           }
1848 
1849         case cff_op_flex1:
1850           {
1851             FT_Pos     start_x, start_y; /* record start x, y values for */
1852                                          /* alter use                    */
1853             FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
1854                                          /* algorithm below              */
1855             FT_Int     horizontal, count;
1856             FT_Fixed*  temp;
1857 
1858 
1859             FT_TRACE4(( " flex1\n" ));
1860 
1861             /* adding six more points; 4 control points, 2 on-curve points */
1862             if ( cff_builder_start_point( builder, x, y ) ||
1863                  check_points( builder, 6 )               )
1864               goto Fail;
1865 
1866             /* record the starting point's x, y position for later use */
1867             start_x = x;
1868             start_y = y;
1869 
1870             /* XXX: figure out whether this is supposed to be a horizontal */
1871             /*      or vertical flex; the Type 2 specification is vague... */
1872 
1873             temp = args;
1874 
1875             /* grab up to the last argument */
1876             for ( count = 5; count > 0; count-- )
1877             {
1878               dx += temp[0];
1879               dy += temp[1];
1880               temp += 2;
1881             }
1882 
1883             if ( dx < 0 )
1884               dx = -dx;
1885             if ( dy < 0 )
1886               dy = -dy;
1887 
1888             /* strange test, but here it is... */
1889             horizontal = ( dx > dy );
1890 
1891             for ( count = 5; count > 0; count-- )
1892             {
1893               x += args[0];
1894               y += args[1];
1895               cff_builder_add_point( builder, x, y,
1896                                      (FT_Bool)( count == 3 ) );
1897               args += 2;
1898             }
1899 
1900             /* is last operand an x- or y-delta? */
1901             if ( horizontal )
1902             {
1903               x += args[0];
1904               y  = start_y;
1905             }
1906             else
1907             {
1908               x  = start_x;
1909               y += args[0];
1910             }
1911 
1912             cff_builder_add_point( builder, x, y, 1 );
1913 
1914             args = stack;
1915             break;
1916            }
1917 
1918         case cff_op_flex:
1919           {
1920             FT_UInt  count;
1921 
1922 
1923             FT_TRACE4(( " flex\n" ));
1924 
1925             if ( cff_builder_start_point( builder, x, y ) ||
1926                  check_points( builder, 6 )               )
1927               goto Fail;
1928 
1929             for ( count = 6; count > 0; count-- )
1930             {
1931               x += args[0];
1932               y += args[1];
1933               cff_builder_add_point( builder, x, y,
1934                                      (FT_Bool)( count == 4 || count == 1 ) );
1935               args += 2;
1936             }
1937 
1938             args = stack;
1939           }
1940           break;
1941 
1942         case cff_op_seac:
1943             FT_TRACE4(( " seac\n" ));
1944 
1945             error = cff_operator_seac( decoder,
1946                                        args[0], args[1], args[2],
1947                                        (FT_Int)( args[3] >> 16 ),
1948                                        (FT_Int)( args[4] >> 16 ) );
1949 
1950             /* add current outline to the glyph slot */
1951             FT_GlyphLoader_Add( builder->loader );
1952 
1953             /* return now! */
1954             FT_TRACE4(( "\n" ));
1955             return error;
1956 
1957         case cff_op_endchar:
1958           FT_TRACE4(( " endchar\n" ));
1959 
1960           /* We are going to emulate the seac operator. */
1961           if ( num_args >= 4 )
1962           {
1963             /* Save glyph width so that the subglyphs don't overwrite it. */
1964             FT_Pos  glyph_width = decoder->glyph_width;
1965 
1966             error = cff_operator_seac( decoder,
1967                                        0L, args[-4], args[-3],
1968                                        (FT_Int)( args[-2] >> 16 ),
1969                                        (FT_Int)( args[-1] >> 16 ) );
1970 
1971             decoder->glyph_width = glyph_width;
1972           }
1973           else
1974           {
1975             if ( !error )
1976               error = CFF_Err_Ok;
1977 
1978             cff_builder_close_contour( builder );
1979 
1980             /* close hints recording session */
1981             if ( hinter )
1982             {
1983               if ( hinter->close( hinter->hints,
1984                                   builder->current->n_points ) )
1985                 goto Syntax_Error;
1986 
1987               /* apply hints to the loaded glyph outline now */
1988               hinter->apply( hinter->hints,
1989                              builder->current,
1990                              (PSH_Globals)builder->hints_globals,
1991                              decoder->hint_mode );
1992             }
1993 
1994             /* add current outline to the glyph slot */
1995             FT_GlyphLoader_Add( builder->loader );
1996           }
1997 
1998           /* return now! */
1999           FT_TRACE4(( "\n" ));
2000           return error;
2001 
2002         case cff_op_abs:
2003           FT_TRACE4(( " abs\n" ));
2004 
2005           if ( args[0] < 0 )
2006             args[0] = -args[0];
2007           args++;
2008           break;
2009 
2010         case cff_op_add:
2011           FT_TRACE4(( " add\n" ));
2012 
2013           args[0] += args[1];
2014           args++;
2015           break;
2016 
2017         case cff_op_sub:
2018           FT_TRACE4(( " sub\n" ));
2019 
2020           args[0] -= args[1];
2021           args++;
2022           break;
2023 
2024         case cff_op_div:
2025           FT_TRACE4(( " div\n" ));
2026 
2027           args[0] = FT_DivFix( args[0], args[1] );
2028           args++;
2029           break;
2030 
2031         case cff_op_neg:
2032           FT_TRACE4(( " neg\n" ));
2033 
2034           args[0] = -args[0];
2035           args++;
2036           break;
2037 
2038         case cff_op_random:
2039           {
2040             FT_Fixed  Rand;
2041 
2042 
2043             FT_TRACE4(( " rand\n" ));
2044 
2045             Rand = seed;
2046             if ( Rand >= 0x8000L )
2047               Rand++;
2048 
2049             args[0] = Rand;
2050             seed    = FT_MulFix( seed, 0x10000L - seed );
2051             if ( seed == 0 )
2052               seed += 0x2873;
2053             args++;
2054           }
2055           break;
2056 
2057         case cff_op_mul:
2058           FT_TRACE4(( " mul\n" ));
2059 
2060           args[0] = FT_MulFix( args[0], args[1] );
2061           args++;
2062           break;
2063 
2064         case cff_op_sqrt:
2065           FT_TRACE4(( " sqrt\n" ));
2066 
2067           if ( args[0] > 0 )
2068           {
2069             FT_Int    count = 9;
2070             FT_Fixed  root  = args[0];
2071             FT_Fixed  new_root;
2072 
2073 
2074             for (;;)
2075             {
2076               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
2077               if ( new_root == root || count <= 0 )
2078                 break;
2079               root = new_root;
2080             }
2081             args[0] = new_root;
2082           }
2083           else
2084             args[0] = 0;
2085           args++;
2086           break;
2087 
2088         case cff_op_drop:
2089           /* nothing */
2090           FT_TRACE4(( " drop\n" ));
2091 
2092           break;
2093 
2094         case cff_op_exch:
2095           {
2096             FT_Fixed  tmp;
2097 
2098 
2099             FT_TRACE4(( " exch\n" ));
2100 
2101             tmp     = args[0];
2102             args[0] = args[1];
2103             args[1] = tmp;
2104             args   += 2;
2105           }
2106           break;
2107 
2108         case cff_op_index:
2109           {
2110             FT_Int  idx = (FT_Int)( args[0] >> 16 );
2111 
2112 
2113             FT_TRACE4(( " index\n" ));
2114 
2115             if ( idx < 0 )
2116               idx = 0;
2117             else if ( idx > num_args - 2 )
2118               idx = num_args - 2;
2119             args[0] = args[-( idx + 1 )];
2120             args++;
2121           }
2122           break;
2123 
2124         case cff_op_roll:
2125           {
2126             FT_Int  count = (FT_Int)( args[0] >> 16 );
2127             FT_Int  idx   = (FT_Int)( args[1] >> 16 );
2128 
2129 
2130             FT_TRACE4(( " roll\n" ));
2131 
2132             if ( count <= 0 )
2133               count = 1;
2134 
2135             args -= count;
2136             if ( args < stack )
2137               goto Stack_Underflow;
2138 
2139             if ( idx >= 0 )
2140             {
2141               while ( idx > 0 )
2142               {
2143                 FT_Fixed  tmp = args[count - 1];
2144                 FT_Int    i;
2145 
2146 
2147                 for ( i = count - 2; i >= 0; i-- )
2148                   args[i + 1] = args[i];
2149                 args[0] = tmp;
2150                 idx--;
2151               }
2152             }
2153             else
2154             {
2155               while ( idx < 0 )
2156               {
2157                 FT_Fixed  tmp = args[0];
2158                 FT_Int    i;
2159 
2160 
2161                 for ( i = 0; i < count - 1; i++ )
2162                   args[i] = args[i + 1];
2163                 args[count - 1] = tmp;
2164                 idx++;
2165               }
2166             }
2167             args += count;
2168           }
2169           break;
2170 
2171         case cff_op_dup:
2172           FT_TRACE4(( " dup\n" ));
2173 
2174           args[1] = args[0];
2175           args += 2;
2176           break;
2177 
2178         case cff_op_put:
2179           {
2180             FT_Fixed  val = args[0];
2181             FT_Int    idx = (FT_Int)( args[1] >> 16 );
2182 
2183 
2184             FT_TRACE4(( " put\n" ));
2185 
2186             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2187               decoder->buildchar[idx] = val;
2188           }
2189           break;
2190 
2191         case cff_op_get:
2192           {
2193             FT_Int    idx = (FT_Int)( args[0] >> 16 );
2194             FT_Fixed  val = 0;
2195 
2196 
2197             FT_TRACE4(( " get\n" ));
2198 
2199             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2200               val = decoder->buildchar[idx];
2201 
2202             args[0] = val;
2203             args++;
2204           }
2205           break;
2206 
2207         case cff_op_store:
2208           FT_TRACE4(( " store\n"));
2209 
2210           goto Unimplemented;
2211 
2212         case cff_op_load:
2213           FT_TRACE4(( " load\n" ));
2214 
2215           goto Unimplemented;
2216 
2217         case cff_op_dotsection:
2218           /* this operator is deprecated and ignored by the parser */
2219           FT_TRACE4(( " dotsection\n" ));
2220           break;
2221 
2222         case cff_op_closepath:
2223           /* this is an invalid Type 2 operator; however, there        */
2224           /* exist fonts which are incorrectly converted from probably */
2225           /* Type 1 to CFF, and some parsers seem to accept it         */
2226 
2227           FT_TRACE4(( " closepath (invalid op)\n" ));
2228 
2229           args = stack;
2230           break;
2231 
2232         case cff_op_hsbw:
2233           /* this is an invalid Type 2 operator; however, there        */
2234           /* exist fonts which are incorrectly converted from probably */
2235           /* Type 1 to CFF, and some parsers seem to accept it         */
2236 
2237           FT_TRACE4(( " hsbw (invalid op)\n" ));
2238 
2239           decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
2240 
2241           decoder->builder.left_bearing.x = args[0];
2242           decoder->builder.left_bearing.y = 0;
2243 
2244           x    = decoder->builder.pos_x + args[0];
2245           y    = decoder->builder.pos_y;
2246           args = stack;
2247           break;
2248 
2249         case cff_op_sbw:
2250           /* this is an invalid Type 2 operator; however, there        */
2251           /* exist fonts which are incorrectly converted from probably */
2252           /* Type 1 to CFF, and some parsers seem to accept it         */
2253 
2254           FT_TRACE4(( " sbw (invalid op)\n" ));
2255 
2256           decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
2257 
2258           decoder->builder.left_bearing.x = args[0];
2259           decoder->builder.left_bearing.y = args[1];
2260 
2261           x    = decoder->builder.pos_x + args[0];
2262           y    = decoder->builder.pos_y + args[1];
2263           args = stack;
2264           break;
2265 
2266         case cff_op_setcurrentpoint:
2267           /* this is an invalid Type 2 operator; however, there        */
2268           /* exist fonts which are incorrectly converted from probably */
2269           /* Type 1 to CFF, and some parsers seem to accept it         */
2270 
2271           FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2272 
2273           x    = decoder->builder.pos_x + args[0];
2274           y    = decoder->builder.pos_y + args[1];
2275           args = stack;
2276           break;
2277 
2278         case cff_op_callothersubr:
2279           /* this is an invalid Type 2 operator; however, there        */
2280           /* exist fonts which are incorrectly converted from probably */
2281           /* Type 1 to CFF, and some parsers seem to accept it         */
2282 
2283           FT_TRACE4(( " callothersubr (invalid op)\n" ));
2284 
2285           /* subsequent `pop' operands should add the arguments,       */
2286           /* this is the implementation described for `unknown' other  */
2287           /* subroutines in the Type1 spec.                            */
2288           /*                                                           */
2289           /* XXX Fix return arguments (see discussion below).          */
2290           args -= 2 + ( args[-2] >> 16 );
2291           if ( args < stack )
2292             goto Stack_Underflow;
2293           break;
2294 
2295         case cff_op_pop:
2296           /* this is an invalid Type 2 operator; however, there        */
2297           /* exist fonts which are incorrectly converted from probably */
2298           /* Type 1 to CFF, and some parsers seem to accept it         */
2299 
2300           FT_TRACE4(( " pop (invalid op)\n" ));
2301 
2302           /* XXX Increasing `args' is wrong: After a certain number of */
2303           /* `pop's we get a stack overflow.  Reason for doing it is   */
2304           /* code like this (actually found in a CFF font):            */
2305           /*                                                           */
2306           /*   17 1 3 callothersubr                                    */
2307           /*   pop                                                     */
2308           /*   callsubr                                                */
2309           /*                                                           */
2310           /* Since we handle `callothersubr' as a no-op, and           */
2311           /* `callsubr' needs at least one argument, `pop' can't be a  */
2312           /* no-op too as it basically should be.                      */
2313           /*                                                           */
2314           /* The right solution would be to provide real support for   */
2315           /* `callothersubr' as done in `t1decode.c', however, given   */
2316           /* the fact that CFF fonts with `pop' are invalid, it is     */
2317           /* questionable whether it is worth the time.                */
2318           args++;
2319           break;
2320 
2321         case cff_op_and:
2322           {
2323             FT_Fixed  cond = args[0] && args[1];
2324 
2325 
2326             FT_TRACE4(( " and\n" ));
2327 
2328             args[0] = cond ? 0x10000L : 0;
2329             args++;
2330           }
2331           break;
2332 
2333         case cff_op_or:
2334           {
2335             FT_Fixed  cond = args[0] || args[1];
2336 
2337 
2338             FT_TRACE4(( " or\n" ));
2339 
2340             args[0] = cond ? 0x10000L : 0;
2341             args++;
2342           }
2343           break;
2344 
2345         case cff_op_eq:
2346           {
2347             FT_Fixed  cond = !args[0];
2348 
2349 
2350             FT_TRACE4(( " eq\n" ));
2351 
2352             args[0] = cond ? 0x10000L : 0;
2353             args++;
2354           }
2355           break;
2356 
2357         case cff_op_ifelse:
2358           {
2359             FT_Fixed  cond = ( args[2] <= args[3] );
2360 
2361 
2362             FT_TRACE4(( " ifelse\n" ));
2363 
2364             if ( !cond )
2365               args[0] = args[1];
2366             args++;
2367           }
2368           break;
2369 
2370         case cff_op_callsubr:
2371           {
2372             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2373                                       decoder->locals_bias );
2374 
2375 
2376             FT_TRACE4(( " callsubr(%d)\n", idx ));
2377 
2378             if ( idx >= decoder->num_locals )
2379             {
2380               FT_ERROR(( "cff_decoder_parse_charstrings:"
2381                          " invalid local subr index\n" ));
2382               goto Syntax_Error;
2383             }
2384 
2385             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2386             {
2387               FT_ERROR(( "cff_decoder_parse_charstrings:"
2388                          " too many nested subrs\n" ));
2389               goto Syntax_Error;
2390             }
2391 
2392             zone->cursor = ip;  /* save current instruction pointer */
2393 
2394             zone++;
2395             zone->base   = decoder->locals[idx];
2396             zone->limit  = decoder->locals[idx + 1];
2397             zone->cursor = zone->base;
2398 
2399             if ( !zone->base || zone->limit == zone->base )
2400             {
2401               FT_ERROR(( "cff_decoder_parse_charstrings:"
2402                          " invoking empty subrs\n" ));
2403               goto Syntax_Error;
2404             }
2405 
2406             decoder->zone = zone;
2407             ip            = zone->base;
2408             limit         = zone->limit;
2409           }
2410           break;
2411 
2412         case cff_op_callgsubr:
2413           {
2414             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2415                                       decoder->globals_bias );
2416 
2417 
2418             FT_TRACE4(( " callgsubr(%d)\n", idx ));
2419 
2420             if ( idx >= decoder->num_globals )
2421             {
2422               FT_ERROR(( "cff_decoder_parse_charstrings:"
2423                          " invalid global subr index\n" ));
2424               goto Syntax_Error;
2425             }
2426 
2427             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2428             {
2429               FT_ERROR(( "cff_decoder_parse_charstrings:"
2430                          " too many nested subrs\n" ));
2431               goto Syntax_Error;
2432             }
2433 
2434             zone->cursor = ip;  /* save current instruction pointer */
2435 
2436             zone++;
2437             zone->base   = decoder->globals[idx];
2438             zone->limit  = decoder->globals[idx + 1];
2439             zone->cursor = zone->base;
2440 
2441             if ( !zone->base || zone->limit == zone->base )
2442             {
2443               FT_ERROR(( "cff_decoder_parse_charstrings:"
2444                          " invoking empty subrs\n" ));
2445               goto Syntax_Error;
2446             }
2447 
2448             decoder->zone = zone;
2449             ip            = zone->base;
2450             limit         = zone->limit;
2451           }
2452           break;
2453 
2454         case cff_op_return:
2455           FT_TRACE4(( " return\n" ));
2456 
2457           if ( decoder->zone <= decoder->zones )
2458           {
2459             FT_ERROR(( "cff_decoder_parse_charstrings:"
2460                        " unexpected return\n" ));
2461             goto Syntax_Error;
2462           }
2463 
2464           decoder->zone--;
2465           zone  = decoder->zone;
2466           ip    = zone->cursor;
2467           limit = zone->limit;
2468           break;
2469 
2470         default:
2471         Unimplemented:
2472           FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2473 
2474           if ( ip[-1] == 12 )
2475             FT_ERROR(( " %d", ip[0] ));
2476           FT_ERROR(( "\n" ));
2477 
2478           return CFF_Err_Unimplemented_Feature;
2479         }
2480 
2481         decoder->top = args;
2482 
2483         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2484           goto Stack_Overflow;
2485 
2486       } /* general operator processing */
2487 
2488     } /* while ip < limit */
2489 
2490     FT_TRACE4(( "..end..\n\n" ));
2491 
2492   Fail:
2493     return error;
2494 
2495   Syntax_Error:
2496     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2497     return CFF_Err_Invalid_File_Format;
2498 
2499   Stack_Underflow:
2500     FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2501     return CFF_Err_Too_Few_Arguments;
2502 
2503   Stack_Overflow:
2504     FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2505     return CFF_Err_Stack_Overflow;
2506   }
2507 
2508 
2509   /*************************************************************************/
2510   /*************************************************************************/
2511   /*************************************************************************/
2512   /**********                                                      *********/
2513   /**********                                                      *********/
2514   /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
2515   /**********                                                      *********/
2516   /**********    The following code is in charge of computing      *********/
2517   /**********    the maximum advance width of the font.  It        *********/
2518   /**********    quickly processes each glyph charstring to        *********/
2519   /**********    extract the value from either a `sbw' or `seac'   *********/
2520   /**********    operator.                                         *********/
2521   /**********                                                      *********/
2522   /*************************************************************************/
2523   /*************************************************************************/
2524   /*************************************************************************/
2525 
2526 
2527 #if 0 /* unused until we support pure CFF fonts */
2528 
2529 
2530   FT_LOCAL_DEF( FT_Error )
2531   cff_compute_max_advance( TT_Face  face,
2532                            FT_Int*  max_advance )
2533   {
2534     FT_Error     error = CFF_Err_Ok;
2535     CFF_Decoder  decoder;
2536     FT_Int       glyph_index;
2537     CFF_Font     cff = (CFF_Font)face->other;
2538 
2539 
2540     *max_advance = 0;
2541 
2542     /* Initialize load decoder */
2543     cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
2544 
2545     decoder.builder.metrics_only = 1;
2546     decoder.builder.load_points  = 0;
2547 
2548     /* For each glyph, parse the glyph charstring and extract */
2549     /* the advance width.                                     */
2550     for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
2551           glyph_index++ )
2552     {
2553       FT_Byte*  charstring;
2554       FT_ULong  charstring_len;
2555 
2556 
2557       /* now get load the unscaled outline */
2558       error = cff_get_glyph_data( face, glyph_index,
2559                                   &charstring, &charstring_len );
2560       if ( !error )
2561       {
2562         error = cff_decoder_prepare( &decoder, size, glyph_index );
2563         if ( !error )
2564           error = cff_decoder_parse_charstrings( &decoder,
2565                                                  charstring,
2566                                                  charstring_len );
2567 
2568         cff_free_glyph_data( face, &charstring, &charstring_len );
2569       }
2570 
2571       /* ignore the error if one has occurred -- skip to next glyph */
2572       error = CFF_Err_Ok;
2573     }
2574 
2575     *max_advance = decoder.builder.advance.x;
2576 
2577     return CFF_Err_Ok;
2578   }
2579 
2580 
2581 #endif /* 0 */
2582 
2583 
2584   FT_LOCAL_DEF( FT_Error )
cff_slot_load(CFF_GlyphSlot glyph,CFF_Size size,FT_UInt glyph_index,FT_Int32 load_flags)2585   cff_slot_load( CFF_GlyphSlot  glyph,
2586                  CFF_Size       size,
2587                  FT_UInt        glyph_index,
2588                  FT_Int32       load_flags )
2589   {
2590     FT_Error     error;
2591     CFF_Decoder  decoder;
2592     TT_Face      face = (TT_Face)glyph->root.face;
2593     FT_Bool      hinting, force_scaling;
2594     CFF_Font     cff  = (CFF_Font)face->extra.data;
2595 
2596     FT_Matrix    font_matrix;
2597     FT_Vector    font_offset;
2598 
2599 
2600     force_scaling = FALSE;
2601 
2602     /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2603     /* it immediately to the real glyph_index -- if it isn't a      */
2604     /* subsetted font, glyph_indices and CIDs are identical, though */
2605     if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
2606          cff->charset.cids                               )
2607     {
2608       /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
2609       if ( glyph_index != 0 )
2610       {
2611         glyph_index = cff_charset_cid_to_gindex( &cff->charset,
2612                                                  glyph_index );
2613         if ( glyph_index == 0 )
2614           return CFF_Err_Invalid_Argument;
2615       }
2616     }
2617     else if ( glyph_index >= cff->num_glyphs )
2618       return CFF_Err_Invalid_Argument;
2619 
2620     if ( load_flags & FT_LOAD_NO_RECURSE )
2621       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
2622 
2623     glyph->x_scale = 0x10000L;
2624     glyph->y_scale = 0x10000L;
2625     if ( size )
2626     {
2627       glyph->x_scale = size->root.metrics.x_scale;
2628       glyph->y_scale = size->root.metrics.y_scale;
2629     }
2630 
2631 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2632 
2633     /* try to load embedded bitmap if any              */
2634     /*                                                 */
2635     /* XXX: The convention should be emphasized in     */
2636     /*      the documents because it can be confusing. */
2637     if ( size )
2638     {
2639       CFF_Face      cff_face = (CFF_Face)size->root.face;
2640       SFNT_Service  sfnt     = (SFNT_Service)cff_face->sfnt;
2641       FT_Stream     stream   = cff_face->root.stream;
2642 
2643 
2644       if ( size->strike_index != 0xFFFFFFFFUL      &&
2645            sfnt->load_eblc                         &&
2646            ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
2647       {
2648         TT_SBit_MetricsRec  metrics;
2649 
2650 
2651         error = sfnt->load_sbit_image( face,
2652                                        size->strike_index,
2653                                        glyph_index,
2654                                        (FT_Int)load_flags,
2655                                        stream,
2656                                        &glyph->root.bitmap,
2657                                        &metrics );
2658 
2659         if ( !error )
2660         {
2661           glyph->root.outline.n_points   = 0;
2662           glyph->root.outline.n_contours = 0;
2663 
2664           glyph->root.metrics.width  = (FT_Pos)metrics.width  << 6;
2665           glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
2666 
2667           glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
2668           glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
2669           glyph->root.metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
2670 
2671           glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
2672           glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
2673           glyph->root.metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
2674 
2675           glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
2676 
2677           if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2678           {
2679             glyph->root.bitmap_left = metrics.vertBearingX;
2680             glyph->root.bitmap_top  = metrics.vertBearingY;
2681           }
2682           else
2683           {
2684             glyph->root.bitmap_left = metrics.horiBearingX;
2685             glyph->root.bitmap_top  = metrics.horiBearingY;
2686           }
2687           return error;
2688         }
2689       }
2690     }
2691 
2692 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2693 
2694     /* return immediately if we only want the embedded bitmaps */
2695     if ( load_flags & FT_LOAD_SBITS_ONLY )
2696       return CFF_Err_Invalid_Argument;
2697 
2698     /* if we have a CID subfont, use its matrix (which has already */
2699     /* been multiplied with the root matrix)                       */
2700 
2701     /* this scaling is only relevant if the PS hinter isn't active */
2702     if ( cff->num_subfonts )
2703     {
2704       FT_ULong  top_upm, sub_upm;
2705       FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,
2706                                               glyph_index );
2707 
2708       if ( fd_index >= cff->num_subfonts )
2709         fd_index = (FT_Byte)( cff->num_subfonts - 1 );
2710 
2711       top_upm = cff->top_font.font_dict.units_per_em;
2712       sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
2713 
2714 
2715       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
2716       font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
2717 
2718       if ( top_upm != sub_upm )
2719       {
2720         glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
2721         glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
2722 
2723         force_scaling = TRUE;
2724       }
2725     }
2726     else
2727     {
2728       font_matrix = cff->top_font.font_dict.font_matrix;
2729       font_offset = cff->top_font.font_dict.font_offset;
2730     }
2731 
2732     glyph->root.outline.n_points   = 0;
2733     glyph->root.outline.n_contours = 0;
2734 
2735     hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
2736                        ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
2737 
2738     glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;  /* by default */
2739 
2740     {
2741       FT_Byte*  charstring;
2742       FT_ULong  charstring_len;
2743 
2744 
2745       cff_decoder_init( &decoder, face, size, glyph, hinting,
2746                         FT_LOAD_TARGET_MODE( load_flags ) );
2747 
2748       if ( load_flags & FT_LOAD_ADVANCE_ONLY )
2749         decoder.width_only = TRUE;
2750 
2751       decoder.builder.no_recurse =
2752         (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
2753 
2754       /* now load the unscaled outline */
2755       error = cff_get_glyph_data( face, glyph_index,
2756                                   &charstring, &charstring_len );
2757       if ( error )
2758         goto Glyph_Build_Finished;
2759 
2760       error = cff_decoder_prepare( &decoder, size, glyph_index );
2761       if ( error )
2762         goto Glyph_Build_Finished;
2763 
2764       error = cff_decoder_parse_charstrings( &decoder,
2765                                              charstring,
2766                                              charstring_len );
2767 
2768       cff_free_glyph_data( face, &charstring, charstring_len );
2769 
2770       if ( error )
2771         goto Glyph_Build_Finished;
2772 
2773 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2774       /* Control data and length may not be available for incremental */
2775       /* fonts.                                                       */
2776       if ( face->root.internal->incremental_interface )
2777       {
2778         glyph->root.control_data = 0;
2779         glyph->root.control_len = 0;
2780       }
2781       else
2782 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2783 
2784       /* We set control_data and control_len if charstrings is loaded. */
2785       /* See how charstring loads at cff_index_access_element() in     */
2786       /* cffload.c.                                                    */
2787       {
2788         CFF_Index  csindex = &cff->charstrings_index;
2789 
2790 
2791         if ( csindex->offsets )
2792         {
2793           glyph->root.control_data = csindex->bytes +
2794                                      csindex->offsets[glyph_index] - 1;
2795           glyph->root.control_len  = charstring_len;
2796         }
2797       }
2798 
2799   Glyph_Build_Finished:
2800       /* save new glyph tables, if no error */
2801       if ( !error )
2802         cff_builder_done( &decoder.builder );
2803       /* XXX: anything to do for broken glyph entry? */
2804     }
2805 
2806 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2807 
2808     /* Incremental fonts can optionally override the metrics. */
2809     if ( !error                                                               &&
2810          face->root.internal->incremental_interface                           &&
2811          face->root.internal->incremental_interface->funcs->get_glyph_metrics )
2812     {
2813       FT_Incremental_MetricsRec  metrics;
2814 
2815 
2816       metrics.bearing_x = decoder.builder.left_bearing.x;
2817       metrics.bearing_y = 0;
2818       metrics.advance   = decoder.builder.advance.x;
2819       metrics.advance_v = decoder.builder.advance.y;
2820 
2821       error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
2822                 face->root.internal->incremental_interface->object,
2823                 glyph_index, FALSE, &metrics );
2824 
2825       decoder.builder.left_bearing.x = metrics.bearing_x;
2826       decoder.builder.advance.x      = metrics.advance;
2827       decoder.builder.advance.y      = metrics.advance_v;
2828     }
2829 
2830 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2831 
2832     if ( !error )
2833     {
2834       /* Now, set the metrics -- this is rather simple, as   */
2835       /* the left side bearing is the xMin, and the top side */
2836       /* bearing the yMax.                                   */
2837 
2838       /* For composite glyphs, return only left side bearing and */
2839       /* advance width.                                          */
2840       if ( load_flags & FT_LOAD_NO_RECURSE )
2841       {
2842         FT_Slot_Internal  internal = glyph->root.internal;
2843 
2844 
2845         glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
2846         glyph->root.metrics.horiAdvance  = decoder.glyph_width;
2847         internal->glyph_matrix           = font_matrix;
2848         internal->glyph_delta            = font_offset;
2849         internal->glyph_transformed      = 1;
2850       }
2851       else
2852       {
2853         FT_BBox            cbox;
2854         FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
2855         FT_Vector          advance;
2856         FT_Bool            has_vertical_info;
2857 
2858 
2859         /* copy the _unscaled_ advance width */
2860         metrics->horiAdvance                    = decoder.glyph_width;
2861         glyph->root.linearHoriAdvance           = decoder.glyph_width;
2862         glyph->root.internal->glyph_transformed = 0;
2863 
2864 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2865         has_vertical_info = FT_BOOL( face->vertical_info                   &&
2866                                      face->vertical.number_Of_VMetrics > 0 &&
2867                                      face->vertical.long_metrics           );
2868 #else
2869         has_vertical_info = FT_BOOL( face->vertical_info                   &&
2870                                      face->vertical.number_Of_VMetrics > 0 );
2871 #endif
2872 
2873         /* get the vertical metrics from the vtmx table if we have one */
2874         if ( has_vertical_info )
2875         {
2876           FT_Short   vertBearingY = 0;
2877           FT_UShort  vertAdvance  = 0;
2878 
2879 
2880           ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
2881                                                      glyph_index,
2882                                                      &vertBearingY,
2883                                                      &vertAdvance );
2884           metrics->vertBearingY = vertBearingY;
2885           metrics->vertAdvance  = vertAdvance;
2886         }
2887         else
2888         {
2889           /* make up vertical ones */
2890           if ( face->os2.version != 0xFFFFU )
2891             metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
2892                                              face->os2.sTypoDescender );
2893           else
2894             metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
2895                                              face->horizontal.Descender );
2896         }
2897 
2898         glyph->root.linearVertAdvance = metrics->vertAdvance;
2899 
2900         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
2901 
2902         glyph->root.outline.flags = 0;
2903         if ( size && size->root.metrics.y_ppem < 24 )
2904           glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2905 
2906         glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
2907 
2908         if ( !( font_matrix.xx == 0x10000L &&
2909                 font_matrix.yy == 0x10000L &&
2910                 font_matrix.xy == 0        &&
2911                 font_matrix.yx == 0        ) )
2912           FT_Outline_Transform( &glyph->root.outline, &font_matrix );
2913 
2914         if ( !( font_offset.x == 0 &&
2915                 font_offset.y == 0 ) )
2916           FT_Outline_Translate( &glyph->root.outline,
2917                                 font_offset.x, font_offset.y );
2918 
2919         advance.x = metrics->horiAdvance;
2920         advance.y = 0;
2921         FT_Vector_Transform( &advance, &font_matrix );
2922         metrics->horiAdvance = advance.x + font_offset.x;
2923 
2924         advance.x = 0;
2925         advance.y = metrics->vertAdvance;
2926         FT_Vector_Transform( &advance, &font_matrix );
2927         metrics->vertAdvance = advance.y + font_offset.y;
2928 
2929         if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
2930         {
2931           /* scale the outline and the metrics */
2932           FT_Int       n;
2933           FT_Outline*  cur     = &glyph->root.outline;
2934           FT_Vector*   vec     = cur->points;
2935           FT_Fixed     x_scale = glyph->x_scale;
2936           FT_Fixed     y_scale = glyph->y_scale;
2937 
2938 
2939           /* First of all, scale the points */
2940           if ( !hinting || !decoder.builder.hints_funcs )
2941             for ( n = cur->n_points; n > 0; n--, vec++ )
2942             {
2943               vec->x = FT_MulFix( vec->x, x_scale );
2944               vec->y = FT_MulFix( vec->y, y_scale );
2945             }
2946 
2947           /* Then scale the metrics */
2948           metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
2949           metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
2950         }
2951 
2952         /* compute the other metrics */
2953         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
2954 
2955         metrics->width  = cbox.xMax - cbox.xMin;
2956         metrics->height = cbox.yMax - cbox.yMin;
2957 
2958         metrics->horiBearingX = cbox.xMin;
2959         metrics->horiBearingY = cbox.yMax;
2960 
2961         if ( has_vertical_info )
2962           metrics->vertBearingX = metrics->horiBearingX -
2963                                     metrics->horiAdvance / 2;
2964         else
2965         {
2966           if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2967             ft_synthesize_vertical_metrics( metrics,
2968                                             metrics->vertAdvance );
2969         }
2970       }
2971     }
2972 
2973     return error;
2974   }
2975 
2976 
2977 /* END */
2978