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