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