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