ReactOS  0.4.13-dev-657-g10798fa
cffdecode.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* cffdecode.c */
4 /* */
5 /* PostScript CFF (Type 2) decoding routines (body). */
6 /* */
7 /* Copyright 2017-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_FREETYPE_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_SERVICE_H
23 #include FT_SERVICE_CFF_TABLE_LOAD_H
24 
25 #include "cffdecode.h"
26 #include "psobjs.h"
27 
28 #include "psauxerr.h"
29 
30 
31  /*************************************************************************/
32  /* */
33  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
34  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
35  /* messages during execution. */
36  /* */
37 #undef FT_COMPONENT
38 #define FT_COMPONENT trace_cffdecode
39 
40 
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
42 
43  typedef enum CFF_Operator_
44  {
45  cff_op_unknown = 0,
46 
47  cff_op_rmoveto,
48  cff_op_hmoveto,
49  cff_op_vmoveto,
50 
51  cff_op_rlineto,
52  cff_op_hlineto,
53  cff_op_vlineto,
54 
55  cff_op_rrcurveto,
56  cff_op_hhcurveto,
57  cff_op_hvcurveto,
58  cff_op_rcurveline,
59  cff_op_rlinecurve,
60  cff_op_vhcurveto,
61  cff_op_vvcurveto,
62 
63  cff_op_flex,
64  cff_op_hflex,
65  cff_op_hflex1,
66  cff_op_flex1,
67 
68  cff_op_endchar,
69 
70  cff_op_hstem,
71  cff_op_vstem,
72  cff_op_hstemhm,
73  cff_op_vstemhm,
74 
75  cff_op_hintmask,
76  cff_op_cntrmask,
77  cff_op_dotsection, /* deprecated, acts as no-op */
78 
79  cff_op_abs,
80  cff_op_add,
81  cff_op_sub,
82  cff_op_div,
83  cff_op_neg,
84  cff_op_random,
85  cff_op_mul,
86  cff_op_sqrt,
87 
88  cff_op_blend,
89 
90  cff_op_drop,
91  cff_op_exch,
92  cff_op_index,
93  cff_op_roll,
94  cff_op_dup,
95 
96  cff_op_put,
97  cff_op_get,
98  cff_op_store,
99  cff_op_load,
100 
101  cff_op_and,
102  cff_op_or,
103  cff_op_not,
104  cff_op_eq,
105  cff_op_ifelse,
106 
107  cff_op_callsubr,
108  cff_op_callgsubr,
109  cff_op_return,
110 
111  /* Type 1 opcodes: invalid but seen in real life */
112  cff_op_hsbw,
113  cff_op_closepath,
114  cff_op_callothersubr,
115  cff_op_pop,
116  cff_op_seac,
117  cff_op_sbw,
118  cff_op_setcurrentpoint,
119 
120  /* do not remove */
121  cff_op_max
122 
123  } CFF_Operator;
124 
125 
126 #define CFF_COUNT_CHECK_WIDTH 0x80
127 #define CFF_COUNT_EXACT 0x40
128 #define CFF_COUNT_CLEAR_STACK 0x20
129 
130  /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
131  /* used for checking the width and requested numbers of arguments */
132  /* only; they are set to zero afterwards */
133 
134  /* the other two flags are informative only and unused currently */
135 
136  static const FT_Byte cff_argument_counts[] =
137  {
138  0, /* unknown */
139 
140  2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
141  1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
142  1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
143 
144  0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
145  0 | CFF_COUNT_CLEAR_STACK,
146  0 | CFF_COUNT_CLEAR_STACK,
147 
148  0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
149  0 | CFF_COUNT_CLEAR_STACK,
150  0 | CFF_COUNT_CLEAR_STACK,
151  0 | CFF_COUNT_CLEAR_STACK,
152  0 | CFF_COUNT_CLEAR_STACK,
153  0 | CFF_COUNT_CLEAR_STACK,
154  0 | CFF_COUNT_CLEAR_STACK,
155 
156  13, /* flex */
157  7,
158  9,
159  11,
160 
161  0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
162 
163  2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
164  2 | CFF_COUNT_CHECK_WIDTH,
165  2 | CFF_COUNT_CHECK_WIDTH,
166  2 | CFF_COUNT_CHECK_WIDTH,
167 
168  0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
169  0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
170  0, /* dotsection */
171 
172  1, /* abs */
173  2,
174  2,
175  2,
176  1,
177  0,
178  2,
179  1,
180 
181  1, /* blend */
182 
183  1, /* drop */
184  2,
185  1,
186  2,
187  1,
188 
189  2, /* put */
190  1,
191  4,
192  3,
193 
194  2, /* and */
195  2,
196  1,
197  2,
198  4,
199 
200  1, /* callsubr */
201  1,
202  0,
203 
204  2, /* hsbw */
205  0,
206  0,
207  0,
208  5, /* seac */
209  4, /* sbw */
210  2 /* setcurrentpoint */
211  };
212 
213 
214  static FT_Error
215  cff_operator_seac( CFF_Decoder* decoder,
216  FT_Pos asb,
217  FT_Pos adx,
218  FT_Pos ady,
219  FT_Int bchar,
220  FT_Int achar )
221  {
222  FT_Error error;
223  CFF_Builder* builder = &decoder->builder;
224  FT_Int bchar_index, achar_index;
225  TT_Face face = decoder->builder.face;
226  FT_Vector left_bearing, advance;
227  FT_Byte* charstring;
228  FT_ULong charstring_len;
229  FT_Pos glyph_width;
230 
231 
232  if ( decoder->seac )
233  {
234  FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
235  return FT_THROW( Syntax_Error );
236  }
237 
238  adx += decoder->builder.left_bearing.x;
239  ady += decoder->builder.left_bearing.y;
240 
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
242  /* Incremental fonts don't necessarily have valid charsets. */
243  /* They use the character code, not the glyph index, in this case. */
244  if ( face->root.internal->incremental_interface )
245  {
246  bchar_index = bchar;
247  achar_index = achar;
248  }
249  else
250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
251  {
252  CFF_Font cff = (CFF_Font)(face->extra.data);
253 
254 
255  bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
256  achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
257  }
258 
259  if ( bchar_index < 0 || achar_index < 0 )
260  {
261  FT_ERROR(( "cff_operator_seac:"
262  " invalid seac character code arguments\n" ));
263  return FT_THROW( Syntax_Error );
264  }
265 
266  /* If we are trying to load a composite glyph, do not load the */
267  /* accent character and return the array of subglyphs. */
268  if ( builder->no_recurse )
269  {
270  FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
271  FT_GlyphLoader loader = glyph->internal->loader;
272  FT_SubGlyph subg;
273 
274 
275  /* reallocate subglyph array if necessary */
276  error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
277  if ( error )
278  goto Exit;
279 
280  subg = loader->current.subglyphs;
281 
282  /* subglyph 0 = base character */
283  subg->index = bchar_index;
286  subg->arg1 = 0;
287  subg->arg2 = 0;
288  subg++;
289 
290  /* subglyph 1 = accent character */
291  subg->index = achar_index;
293  subg->arg1 = (FT_Int)( adx >> 16 );
294  subg->arg2 = (FT_Int)( ady >> 16 );
295 
296  /* set up remaining glyph fields */
297  glyph->num_subglyphs = 2;
298  glyph->subglyphs = loader->base.subglyphs;
299  glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
300 
301  loader->current.num_subglyphs = 2;
302  }
303 
304  FT_GlyphLoader_Prepare( builder->loader );
305 
306  /* First load `bchar' in builder */
307  error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
308  &charstring, &charstring_len );
309  if ( !error )
310  {
311  /* the seac operator must not be nested */
312  decoder->seac = TRUE;
313  error = cff_decoder_parse_charstrings( decoder, charstring,
314  charstring_len, 0 );
315  decoder->seac = FALSE;
316 
317  decoder->free_glyph_callback( face, &charstring, charstring_len );
318 
319  if ( error )
320  goto Exit;
321  }
322 
323  /* Save the left bearing, advance and glyph width of the base */
324  /* character as they will be erased by the next load. */
325 
326  left_bearing = builder->left_bearing;
327  advance = builder->advance;
328  glyph_width = decoder->glyph_width;
329 
330  builder->left_bearing.x = 0;
331  builder->left_bearing.y = 0;
332 
333  builder->pos_x = adx - asb;
334  builder->pos_y = ady;
335 
336  /* Now load `achar' on top of the base outline. */
337  error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
338  &charstring, &charstring_len );
339  if ( !error )
340  {
341  /* the seac operator must not be nested */
342  decoder->seac = TRUE;
343  error = cff_decoder_parse_charstrings( decoder, charstring,
344  charstring_len, 0 );
345  decoder->seac = FALSE;
346 
347  decoder->free_glyph_callback( face, &charstring, charstring_len );
348 
349  if ( error )
350  goto Exit;
351  }
352 
353  /* Restore the left side bearing, advance and glyph width */
354  /* of the base character. */
355  builder->left_bearing = left_bearing;
356  builder->advance = advance;
357  decoder->glyph_width = glyph_width;
358 
359  builder->pos_x = 0;
360  builder->pos_y = 0;
361 
362  Exit:
363  return error;
364  }
365 
366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
367 
368 
369  /*************************************************************************/
370  /*************************************************************************/
371  /*************************************************************************/
372  /********** *********/
373  /********** *********/
374  /********** GENERIC CHARSTRING PARSING *********/
375  /********** *********/
376  /********** *********/
377  /*************************************************************************/
378  /*************************************************************************/
379  /*************************************************************************/
380 
381  /*************************************************************************/
382  /* */
383  /* <Function> */
384  /* cff_compute_bias */
385  /* */
386  /* <Description> */
387  /* Computes the bias value in dependence of the number of glyph */
388  /* subroutines. */
389  /* */
390  /* <Input> */
391  /* in_charstring_type :: The `CharstringType' value of the top DICT */
392  /* dictionary. */
393  /* */
394  /* num_subrs :: The number of glyph subroutines. */
395  /* */
396  /* <Return> */
397  /* The bias value. */
398  static FT_Int
399  cff_compute_bias( FT_Int in_charstring_type,
400  FT_UInt num_subrs )
401  {
402  FT_Int result;
403 
404 
405  if ( in_charstring_type == 1 )
406  result = 0;
407  else if ( num_subrs < 1240 )
408  result = 107;
409  else if ( num_subrs < 33900U )
410  result = 1131;
411  else
412  result = 32768U;
413 
414  return result;
415  }
416 
417 
420  FT_Int charcode )
421  {
422  FT_UInt n;
423  FT_UShort glyph_sid;
424 
425  FT_Service_CFFLoad cffload;
426 
427 
428  /* CID-keyed fonts don't have glyph names */
429  if ( !cff->charset.sids )
430  return -1;
431 
432  /* check range of standard char code */
433  if ( charcode < 0 || charcode > 255 )
434  return -1;
435 
436 #if 0
437  /* retrieve cffload from list of current modules */
438  FT_Service_CFFLoad cffload;
439 
440 
441  FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
442  if ( !cffload )
443  {
444  FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
445  " the `cffload' module is not available\n" ));
446  return FT_THROW( Unimplemented_Feature );
447  }
448 #endif
449 
450  cffload = (FT_Service_CFFLoad)cff->cffload;
451 
452  /* Get code to SID mapping from `cff_standard_encoding'. */
453  glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
454 
455  for ( n = 0; n < cff->num_glyphs; n++ )
456  {
457  if ( cff->charset.sids[n] == glyph_sid )
458  return (FT_Int)n;
459  }
460 
461  return -1;
462  }
463 
464 
465 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
466 
467  /*************************************************************************/
468  /* */
469  /* <Function> */
470  /* cff_decoder_parse_charstrings */
471  /* */
472  /* <Description> */
473  /* Parses a given Type 2 charstrings program. */
474  /* */
475  /* <InOut> */
476  /* decoder :: The current Type 1 decoder. */
477  /* */
478  /* <Input> */
479  /* charstring_base :: The base of the charstring stream. */
480  /* */
481  /* charstring_len :: The length in bytes of the charstring stream. */
482  /* */
483  /* in_dict :: Set to 1 if function is called from top or */
484  /* private DICT (needed for Multiple Master CFFs). */
485  /* */
486  /* <Return> */
487  /* FreeType error code. 0 means success. */
488  /* */
490  cff_decoder_parse_charstrings( CFF_Decoder* decoder,
491  FT_Byte* charstring_base,
492  FT_ULong charstring_len,
493  FT_Bool in_dict )
494  {
495  FT_Error error;
497  FT_Byte* ip;
498  FT_Byte* limit;
499  CFF_Builder* builder = &decoder->builder;
500  FT_Pos x, y;
501  FT_Fixed* stack;
502  FT_Int charstring_type =
504  FT_UShort num_designs =
505  decoder->cff->top_font.font_dict.num_designs;
506  FT_UShort num_axes =
507  decoder->cff->top_font.font_dict.num_axes;
508 
509  T2_Hints_Funcs hinter;
510 
511 
512  /* set default width */
513  decoder->num_hints = 0;
514  decoder->read_width = 1;
515 
516  /* initialize the decoder */
517  decoder->top = decoder->stack;
518  decoder->zone = decoder->zones;
519  zone = decoder->zones;
520  stack = decoder->top;
521 
522  hinter = (T2_Hints_Funcs)builder->hints_funcs;
523 
524  builder->path_begun = 0;
525 
526  zone->base = charstring_base;
527  limit = zone->limit = charstring_base + charstring_len;
528  ip = zone->cursor = zone->base;
529 
530  error = FT_Err_Ok;
531 
532  x = builder->pos_x;
533  y = builder->pos_y;
534 
535  /* begin hints recording session, if any */
536  if ( hinter )
537  hinter->open( hinter->hints );
538 
539  /* now execute loop */
540  while ( ip < limit )
541  {
542  CFF_Operator op;
543  FT_Byte v;
544 
545 
546  /********************************************************************/
547  /* */
548  /* Decode operator or operand */
549  /* */
550  v = *ip++;
551  if ( v >= 32 || v == 28 )
552  {
553  FT_Int shift = 16;
554  FT_Int32 val;
555 
556 
557  /* this is an operand, push it on the stack */
558 
559  /* if we use shifts, all computations are done with unsigned */
560  /* values; the conversion to a signed value is the last step */
561  if ( v == 28 )
562  {
563  if ( ip + 1 >= limit )
564  goto Syntax_Error;
565  val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
566  ip += 2;
567  }
568  else if ( v < 247 )
569  val = (FT_Int32)v - 139;
570  else if ( v < 251 )
571  {
572  if ( ip >= limit )
573  goto Syntax_Error;
574  val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
575  }
576  else if ( v < 255 )
577  {
578  if ( ip >= limit )
579  goto Syntax_Error;
580  val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
581  }
582  else
583  {
584  if ( ip + 3 >= limit )
585  goto Syntax_Error;
586  val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
587  ( (FT_UInt32)ip[1] << 16 ) |
588  ( (FT_UInt32)ip[2] << 8 ) |
589  (FT_UInt32)ip[3] );
590  ip += 4;
591  if ( charstring_type == 2 )
592  shift = 0;
593  }
594  if ( decoder->top - stack >= CFF_MAX_OPERANDS )
595  goto Stack_Overflow;
596 
597  val = (FT_Int32)( (FT_UInt32)val << shift );
598  *decoder->top++ = val;
599 
600 #ifdef FT_DEBUG_LEVEL_TRACE
601  if ( !( val & 0xFFFFL ) )
602  FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
603  else
604  FT_TRACE4(( " %.5f", val / 65536.0 ));
605 #endif
606 
607  }
608  else
609  {
610  /* The specification says that normally arguments are to be taken */
611  /* from the bottom of the stack. However, this seems not to be */
612  /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
613  /* arguments similar to a PS interpreter. */
614 
615  FT_Fixed* args = decoder->top;
616  FT_Int num_args = (FT_Int)( args - decoder->stack );
617  FT_Int req_args;
618 
619 
620  /* find operator */
621  op = cff_op_unknown;
622 
623  switch ( v )
624  {
625  case 1:
626  op = cff_op_hstem;
627  break;
628  case 3:
629  op = cff_op_vstem;
630  break;
631  case 4:
632  op = cff_op_vmoveto;
633  break;
634  case 5:
635  op = cff_op_rlineto;
636  break;
637  case 6:
638  op = cff_op_hlineto;
639  break;
640  case 7:
641  op = cff_op_vlineto;
642  break;
643  case 8:
644  op = cff_op_rrcurveto;
645  break;
646  case 9:
647  op = cff_op_closepath;
648  break;
649  case 10:
650  op = cff_op_callsubr;
651  break;
652  case 11:
653  op = cff_op_return;
654  break;
655  case 12:
656  if ( ip >= limit )
657  goto Syntax_Error;
658  v = *ip++;
659 
660  switch ( v )
661  {
662  case 0:
663  op = cff_op_dotsection;
664  break;
665  case 1: /* this is actually the Type1 vstem3 operator */
666  op = cff_op_vstem;
667  break;
668  case 2: /* this is actually the Type1 hstem3 operator */
669  op = cff_op_hstem;
670  break;
671  case 3:
672  op = cff_op_and;
673  break;
674  case 4:
675  op = cff_op_or;
676  break;
677  case 5:
678  op = cff_op_not;
679  break;
680  case 6:
681  op = cff_op_seac;
682  break;
683  case 7:
684  op = cff_op_sbw;
685  break;
686  case 8:
687  op = cff_op_store;
688  break;
689  case 9:
690  op = cff_op_abs;
691  break;
692  case 10:
693  op = cff_op_add;
694  break;
695  case 11:
696  op = cff_op_sub;
697  break;
698  case 12:
699  op = cff_op_div;
700  break;
701  case 13:
702  op = cff_op_load;
703  break;
704  case 14:
705  op = cff_op_neg;
706  break;
707  case 15:
708  op = cff_op_eq;
709  break;
710  case 16:
711  op = cff_op_callothersubr;
712  break;
713  case 17:
714  op = cff_op_pop;
715  break;
716  case 18:
717  op = cff_op_drop;
718  break;
719  case 20:
720  op = cff_op_put;
721  break;
722  case 21:
723  op = cff_op_get;
724  break;
725  case 22:
726  op = cff_op_ifelse;
727  break;
728  case 23:
729  op = cff_op_random;
730  break;
731  case 24:
732  op = cff_op_mul;
733  break;
734  case 26:
735  op = cff_op_sqrt;
736  break;
737  case 27:
738  op = cff_op_dup;
739  break;
740  case 28:
741  op = cff_op_exch;
742  break;
743  case 29:
744  op = cff_op_index;
745  break;
746  case 30:
747  op = cff_op_roll;
748  break;
749  case 33:
750  op = cff_op_setcurrentpoint;
751  break;
752  case 34:
753  op = cff_op_hflex;
754  break;
755  case 35:
756  op = cff_op_flex;
757  break;
758  case 36:
759  op = cff_op_hflex1;
760  break;
761  case 37:
762  op = cff_op_flex1;
763  break;
764  default:
765  FT_TRACE4(( " unknown op (12, %d)\n", v ));
766  break;
767  }
768  break;
769  case 13:
770  op = cff_op_hsbw;
771  break;
772  case 14:
773  op = cff_op_endchar;
774  break;
775  case 16:
776  op = cff_op_blend;
777  break;
778  case 18:
779  op = cff_op_hstemhm;
780  break;
781  case 19:
782  op = cff_op_hintmask;
783  break;
784  case 20:
785  op = cff_op_cntrmask;
786  break;
787  case 21:
788  op = cff_op_rmoveto;
789  break;
790  case 22:
791  op = cff_op_hmoveto;
792  break;
793  case 23:
794  op = cff_op_vstemhm;
795  break;
796  case 24:
797  op = cff_op_rcurveline;
798  break;
799  case 25:
800  op = cff_op_rlinecurve;
801  break;
802  case 26:
803  op = cff_op_vvcurveto;
804  break;
805  case 27:
806  op = cff_op_hhcurveto;
807  break;
808  case 29:
809  op = cff_op_callgsubr;
810  break;
811  case 30:
812  op = cff_op_vhcurveto;
813  break;
814  case 31:
815  op = cff_op_hvcurveto;
816  break;
817  default:
818  FT_TRACE4(( " unknown op (%d)\n", v ));
819  break;
820  }
821 
822  if ( op == cff_op_unknown )
823  continue;
824 
825  /* in Multiple Master CFFs, T2 charstrings can appear in */
826  /* dictionaries, but some operators are prohibited */
827  if ( in_dict )
828  {
829  switch ( op )
830  {
831  case cff_op_hstem:
832  case cff_op_vstem:
833  case cff_op_vmoveto:
834  case cff_op_rlineto:
835  case cff_op_hlineto:
836  case cff_op_vlineto:
837  case cff_op_rrcurveto:
838  case cff_op_hstemhm:
839  case cff_op_hintmask:
840  case cff_op_cntrmask:
841  case cff_op_rmoveto:
842  case cff_op_hmoveto:
843  case cff_op_vstemhm:
844  case cff_op_rcurveline:
845  case cff_op_rlinecurve:
846  case cff_op_vvcurveto:
847  case cff_op_hhcurveto:
848  case cff_op_vhcurveto:
849  case cff_op_hvcurveto:
850  case cff_op_hflex:
851  case cff_op_flex:
852  case cff_op_hflex1:
853  case cff_op_flex1:
854  case cff_op_callsubr:
855  case cff_op_callgsubr:
856  goto MM_Error;
857 
858  default:
859  break;
860  }
861  }
862 
863  /* check arguments */
864  req_args = cff_argument_counts[op];
865  if ( req_args & CFF_COUNT_CHECK_WIDTH )
866  {
867  if ( num_args > 0 && decoder->read_width )
868  {
869  /* If `nominal_width' is non-zero, the number is really a */
870  /* difference against `nominal_width'. Else, the number here */
871  /* is truly a width, not a difference against `nominal_width'. */
872  /* If the font does not set `nominal_width', then */
873  /* `nominal_width' defaults to zero, and so we can set */
874  /* `glyph_width' to `nominal_width' plus number on the stack */
875  /* -- for either case. */
876 
877  FT_Int set_width_ok;
878 
879 
880  switch ( op )
881  {
882  case cff_op_hmoveto:
883  case cff_op_vmoveto:
884  set_width_ok = num_args & 2;
885  break;
886 
887  case cff_op_hstem:
888  case cff_op_vstem:
889  case cff_op_hstemhm:
890  case cff_op_vstemhm:
891  case cff_op_rmoveto:
892  case cff_op_hintmask:
893  case cff_op_cntrmask:
894  set_width_ok = num_args & 1;
895  break;
896 
897  case cff_op_endchar:
898  /* If there is a width specified for endchar, we either have */
899  /* 1 argument or 5 arguments. We like to argue. */
900  set_width_ok = in_dict
901  ? 0
902  : ( ( num_args == 5 ) || ( num_args == 1 ) );
903  break;
904 
905  default:
906  set_width_ok = 0;
907  break;
908  }
909 
910  if ( set_width_ok )
911  {
912  decoder->glyph_width = decoder->nominal_width +
913  ( stack[0] >> 16 );
914 
915  if ( decoder->width_only )
916  {
917  /* we only want the advance width; stop here */
918  break;
919  }
920 
921  /* Consumed an argument. */
922  num_args--;
923  }
924  }
925 
926  decoder->read_width = 0;
927  req_args = 0;
928  }
929 
930  req_args &= 0x000F;
931  if ( num_args < req_args )
932  goto Stack_Underflow;
933  args -= req_args;
934  num_args -= req_args;
935 
936  /* At this point, `args' points to the first argument of the */
937  /* operand in case `req_args' isn't zero. Otherwise, we have */
938  /* to adjust `args' manually. */
939 
940  /* Note that we only pop arguments from the stack which we */
941  /* really need and can digest so that we can continue in case */
942  /* of superfluous stack elements. */
943 
944  switch ( op )
945  {
946  case cff_op_hstem:
947  case cff_op_vstem:
948  case cff_op_hstemhm:
949  case cff_op_vstemhm:
950  /* the number of arguments is always even here */
951  FT_TRACE4((
952  op == cff_op_hstem ? " hstem\n" :
953  ( op == cff_op_vstem ? " vstem\n" :
954  ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
955 
956  if ( hinter )
957  hinter->stems( hinter->hints,
958  ( op == cff_op_hstem || op == cff_op_hstemhm ),
959  num_args / 2,
960  args - ( num_args & ~1 ) );
961 
962  decoder->num_hints += num_args / 2;
963  args = stack;
964  break;
965 
966  case cff_op_hintmask:
967  case cff_op_cntrmask:
968  FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
969 
970  /* implement vstem when needed -- */
971  /* the specification doesn't say it, but this also works */
972  /* with the 'cntrmask' operator */
973  /* */
974  if ( num_args > 0 )
975  {
976  if ( hinter )
977  hinter->stems( hinter->hints,
978  0,
979  num_args / 2,
980  args - ( num_args & ~1 ) );
981 
982  decoder->num_hints += num_args / 2;
983  }
984 
985  /* In a valid charstring there must be at least one byte */
986  /* after `hintmask' or `cntrmask' (e.g., for a `return' */
987  /* instruction). Additionally, there must be space for */
988  /* `num_hints' bits. */
989 
990  if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
991  goto Syntax_Error;
992 
993  if ( hinter )
994  {
995  if ( op == cff_op_hintmask )
996  hinter->hintmask( hinter->hints,
997  (FT_UInt)builder->current->n_points,
998  (FT_UInt)decoder->num_hints,
999  ip );
1000  else
1001  hinter->counter( hinter->hints,
1002  (FT_UInt)decoder->num_hints,
1003  ip );
1004  }
1005 
1006 #ifdef FT_DEBUG_LEVEL_TRACE
1007  {
1008  FT_UInt maskbyte;
1009 
1010 
1011  FT_TRACE4(( " (maskbytes:" ));
1012 
1013  for ( maskbyte = 0;
1014  maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1015  maskbyte++, ip++ )
1016  FT_TRACE4(( " 0x%02X", *ip ));
1017 
1018  FT_TRACE4(( ")\n" ));
1019  }
1020 #else
1021  ip += ( decoder->num_hints + 7 ) >> 3;
1022 #endif
1023  args = stack;
1024  break;
1025 
1026  case cff_op_rmoveto:
1027  FT_TRACE4(( " rmoveto\n" ));
1028 
1029  cff_builder_close_contour( builder );
1030  builder->path_begun = 0;
1031  x = ADD_LONG( x, args[-2] );
1032  y = ADD_LONG( y, args[-1] );
1033  args = stack;
1034  break;
1035 
1036  case cff_op_vmoveto:
1037  FT_TRACE4(( " vmoveto\n" ));
1038 
1039  cff_builder_close_contour( builder );
1040  builder->path_begun = 0;
1041  y = ADD_LONG( y, args[-1] );
1042  args = stack;
1043  break;
1044 
1045  case cff_op_hmoveto:
1046  FT_TRACE4(( " hmoveto\n" ));
1047 
1048  cff_builder_close_contour( builder );
1049  builder->path_begun = 0;
1050  x = ADD_LONG( x, args[-1] );
1051  args = stack;
1052  break;
1053 
1054  case cff_op_rlineto:
1055  FT_TRACE4(( " rlineto\n" ));
1056 
1057  if ( cff_builder_start_point( builder, x, y ) ||
1058  cff_check_points( builder, num_args / 2 ) )
1059  goto Fail;
1060 
1061  if ( num_args < 2 )
1062  goto Stack_Underflow;
1063 
1064  args -= num_args & ~1;
1065  while ( args < decoder->top )
1066  {
1067  x = ADD_LONG( x, args[0] );
1068  y = ADD_LONG( y, args[1] );
1069  cff_builder_add_point( builder, x, y, 1 );
1070  args += 2;
1071  }
1072  args = stack;
1073  break;
1074 
1075  case cff_op_hlineto:
1076  case cff_op_vlineto:
1077  {
1078  FT_Int phase = ( op == cff_op_hlineto );
1079 
1080 
1081  FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1082  : " vlineto\n" ));
1083 
1084  if ( num_args < 0 )
1085  goto Stack_Underflow;
1086 
1087  /* there exist subsetted fonts (found in PDFs) */
1088  /* which call `hlineto' without arguments */
1089  if ( num_args == 0 )
1090  break;
1091 
1092  if ( cff_builder_start_point( builder, x, y ) ||
1093  cff_check_points( builder, num_args ) )
1094  goto Fail;
1095 
1096  args = stack;
1097  while ( args < decoder->top )
1098  {
1099  if ( phase )
1100  x = ADD_LONG( x, args[0] );
1101  else
1102  y = ADD_LONG( y, args[0] );
1103 
1104  if ( cff_builder_add_point1( builder, x, y ) )
1105  goto Fail;
1106 
1107  args++;
1108  phase ^= 1;
1109  }
1110  args = stack;
1111  }
1112  break;
1113 
1114  case cff_op_rrcurveto:
1115  {
1116  FT_Int nargs;
1117 
1118 
1119  FT_TRACE4(( " rrcurveto\n" ));
1120 
1121  if ( num_args < 6 )
1122  goto Stack_Underflow;
1123 
1124  nargs = num_args - num_args % 6;
1125 
1126  if ( cff_builder_start_point( builder, x, y ) ||
1127  cff_check_points( builder, nargs / 2 ) )
1128  goto Fail;
1129 
1130  args -= nargs;
1131  while ( args < decoder->top )
1132  {
1133  x = ADD_LONG( x, args[0] );
1134  y = ADD_LONG( y, args[1] );
1135  cff_builder_add_point( builder, x, y, 0 );
1136 
1137  x = ADD_LONG( x, args[2] );
1138  y = ADD_LONG( y, args[3] );
1139  cff_builder_add_point( builder, x, y, 0 );
1140 
1141  x = ADD_LONG( x, args[4] );
1142  y = ADD_LONG( y, args[5] );
1143  cff_builder_add_point( builder, x, y, 1 );
1144 
1145  args += 6;
1146  }
1147  args = stack;
1148  }
1149  break;
1150 
1151  case cff_op_vvcurveto:
1152  {
1153  FT_Int nargs;
1154 
1155 
1156  FT_TRACE4(( " vvcurveto\n" ));
1157 
1158  if ( num_args < 4 )
1159  goto Stack_Underflow;
1160 
1161  /* if num_args isn't of the form 4n or 4n+1, */
1162  /* we enforce it by clearing the second bit */
1163 
1164  nargs = num_args & ~2;
1165 
1166  if ( cff_builder_start_point( builder, x, y ) )
1167  goto Fail;
1168 
1169  args -= nargs;
1170 
1171  if ( nargs & 1 )
1172  {
1173  x = ADD_LONG( x, args[0] );
1174  args++;
1175  nargs--;
1176  }
1177 
1178  if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1179  goto Fail;
1180 
1181  while ( args < decoder->top )
1182  {
1183  y = ADD_LONG( y, args[0] );
1184  cff_builder_add_point( builder, x, y, 0 );
1185 
1186  x = ADD_LONG( x, args[1] );
1187  y = ADD_LONG( y, args[2] );
1188  cff_builder_add_point( builder, x, y, 0 );
1189 
1190  y = ADD_LONG( y, args[3] );
1191  cff_builder_add_point( builder, x, y, 1 );
1192 
1193  args += 4;
1194  }
1195  args = stack;
1196  }
1197  break;
1198 
1199  case cff_op_hhcurveto:
1200  {
1201  FT_Int nargs;
1202 
1203 
1204  FT_TRACE4(( " hhcurveto\n" ));
1205 
1206  if ( num_args < 4 )
1207  goto Stack_Underflow;
1208 
1209  /* if num_args isn't of the form 4n or 4n+1, */
1210  /* we enforce it by clearing the second bit */
1211 
1212  nargs = num_args & ~2;
1213 
1214  if ( cff_builder_start_point( builder, x, y ) )
1215  goto Fail;
1216 
1217  args -= nargs;
1218  if ( nargs & 1 )
1219  {
1220  y = ADD_LONG( y, args[0] );
1221  args++;
1222  nargs--;
1223  }
1224 
1225  if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1226  goto Fail;
1227 
1228  while ( args < decoder->top )
1229  {
1230  x = ADD_LONG( x, args[0] );
1231  cff_builder_add_point( builder, x, y, 0 );
1232 
1233  x = ADD_LONG( x, args[1] );
1234  y = ADD_LONG( y, args[2] );
1235  cff_builder_add_point( builder, x, y, 0 );
1236 
1237  x = ADD_LONG( x, args[3] );
1238  cff_builder_add_point( builder, x, y, 1 );
1239 
1240  args += 4;
1241  }
1242  args = stack;
1243  }
1244  break;
1245 
1246  case cff_op_vhcurveto:
1247  case cff_op_hvcurveto:
1248  {
1249  FT_Int phase;
1250  FT_Int nargs;
1251 
1252 
1253  FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1254  : " hvcurveto\n" ));
1255 
1256  if ( cff_builder_start_point( builder, x, y ) )
1257  goto Fail;
1258 
1259  if ( num_args < 4 )
1260  goto Stack_Underflow;
1261 
1262  /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1263  /* we enforce it by clearing the second bit */
1264 
1265  nargs = num_args & ~2;
1266 
1267  args -= nargs;
1268  if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1269  goto Stack_Underflow;
1270 
1271  phase = ( op == cff_op_hvcurveto );
1272 
1273  while ( nargs >= 4 )
1274  {
1275  nargs -= 4;
1276  if ( phase )
1277  {
1278  x = ADD_LONG( x, args[0] );
1279  cff_builder_add_point( builder, x, y, 0 );
1280 
1281  x = ADD_LONG( x, args[1] );
1282  y = ADD_LONG( y, args[2] );
1283  cff_builder_add_point( builder, x, y, 0 );
1284 
1285  y = ADD_LONG( y, args[3] );
1286  if ( nargs == 1 )
1287  x = ADD_LONG( x, args[4] );
1288  cff_builder_add_point( builder, x, y, 1 );
1289  }
1290  else
1291  {
1292  y = ADD_LONG( y, args[0] );
1293  cff_builder_add_point( builder, x, y, 0 );
1294 
1295  x = ADD_LONG( x, args[1] );
1296  y = ADD_LONG( y, args[2] );
1297  cff_builder_add_point( builder, x, y, 0 );
1298 
1299  x = ADD_LONG( x, args[3] );
1300  if ( nargs == 1 )
1301  y = ADD_LONG( y, args[4] );
1302  cff_builder_add_point( builder, x, y, 1 );
1303  }
1304  args += 4;
1305  phase ^= 1;
1306  }
1307  args = stack;
1308  }
1309  break;
1310 
1311  case cff_op_rlinecurve:
1312  {
1313  FT_Int num_lines;
1314  FT_Int nargs;
1315 
1316 
1317  FT_TRACE4(( " rlinecurve\n" ));
1318 
1319  if ( num_args < 8 )
1320  goto Stack_Underflow;
1321 
1322  nargs = num_args & ~1;
1323  num_lines = ( nargs - 6 ) / 2;
1324 
1325  if ( cff_builder_start_point( builder, x, y ) ||
1326  cff_check_points( builder, num_lines + 3 ) )
1327  goto Fail;
1328 
1329  args -= nargs;
1330 
1331  /* first, add the line segments */
1332  while ( num_lines > 0 )
1333  {
1334  x = ADD_LONG( x, args[0] );
1335  y = ADD_LONG( y, args[1] );
1336  cff_builder_add_point( builder, x, y, 1 );
1337 
1338  args += 2;
1339  num_lines--;
1340  }
1341 
1342  /* then the curve */
1343  x = ADD_LONG( x, args[0] );
1344  y = ADD_LONG( y, args[1] );
1345  cff_builder_add_point( builder, x, y, 0 );
1346 
1347  x = ADD_LONG( x, args[2] );
1348  y = ADD_LONG( y, args[3] );
1349  cff_builder_add_point( builder, x, y, 0 );
1350 
1351  x = ADD_LONG( x, args[4] );
1352  y = ADD_LONG( y, args[5] );
1353  cff_builder_add_point( builder, x, y, 1 );
1354 
1355  args = stack;
1356  }
1357  break;
1358 
1359  case cff_op_rcurveline:
1360  {
1361  FT_Int num_curves;
1362  FT_Int nargs;
1363 
1364 
1365  FT_TRACE4(( " rcurveline\n" ));
1366 
1367  if ( num_args < 8 )
1368  goto Stack_Underflow;
1369 
1370  nargs = num_args - 2;
1371  nargs = nargs - nargs % 6 + 2;
1372  num_curves = ( nargs - 2 ) / 6;
1373 
1374  if ( cff_builder_start_point( builder, x, y ) ||
1375  cff_check_points( builder, num_curves * 3 + 2 ) )
1376  goto Fail;
1377 
1378  args -= nargs;
1379 
1380  /* first, add the curves */
1381  while ( num_curves > 0 )
1382  {
1383  x = ADD_LONG( x, args[0] );
1384  y = ADD_LONG( y, args[1] );
1385  cff_builder_add_point( builder, x, y, 0 );
1386 
1387  x = ADD_LONG( x, args[2] );
1388  y = ADD_LONG( y, args[3] );
1389  cff_builder_add_point( builder, x, y, 0 );
1390 
1391  x = ADD_LONG( x, args[4] );
1392  y = ADD_LONG( y, args[5] );
1393  cff_builder_add_point( builder, x, y, 1 );
1394 
1395  args += 6;
1396  num_curves--;
1397  }
1398 
1399  /* then the final line */
1400  x = ADD_LONG( x, args[0] );
1401  y = ADD_LONG( y, args[1] );
1402  cff_builder_add_point( builder, x, y, 1 );
1403 
1404  args = stack;
1405  }
1406  break;
1407 
1408  case cff_op_hflex1:
1409  {
1410  FT_Pos start_y;
1411 
1412 
1413  FT_TRACE4(( " hflex1\n" ));
1414 
1415  /* adding five more points: 4 control points, 1 on-curve point */
1416  /* -- make sure we have enough space for the start point if it */
1417  /* needs to be added */
1418  if ( cff_builder_start_point( builder, x, y ) ||
1419  cff_check_points( builder, 6 ) )
1420  goto Fail;
1421 
1422  /* record the starting point's y position for later use */
1423  start_y = y;
1424 
1425  /* first control point */
1426  x = ADD_LONG( x, args[0] );
1427  y = ADD_LONG( y, args[1] );
1428  cff_builder_add_point( builder, x, y, 0 );
1429 
1430  /* second control point */
1431  x = ADD_LONG( x, args[2] );
1432  y = ADD_LONG( y, args[3] );
1433  cff_builder_add_point( builder, x, y, 0 );
1434 
1435  /* join point; on curve, with y-value the same as the last */
1436  /* control point's y-value */
1437  x = ADD_LONG( x, args[4] );
1438  cff_builder_add_point( builder, x, y, 1 );
1439 
1440  /* third control point, with y-value the same as the join */
1441  /* point's y-value */
1442  x = ADD_LONG( x, args[5] );
1443  cff_builder_add_point( builder, x, y, 0 );
1444 
1445  /* fourth control point */
1446  x = ADD_LONG( x, args[6] );
1447  y = ADD_LONG( y, args[7] );
1448  cff_builder_add_point( builder, x, y, 0 );
1449 
1450  /* ending point, with y-value the same as the start */
1451  x = ADD_LONG( x, args[8] );
1452  y = start_y;
1453  cff_builder_add_point( builder, x, y, 1 );
1454 
1455  args = stack;
1456  break;
1457  }
1458 
1459  case cff_op_hflex:
1460  {
1461  FT_Pos start_y;
1462 
1463 
1464  FT_TRACE4(( " hflex\n" ));
1465 
1466  /* adding six more points; 4 control points, 2 on-curve points */
1467  if ( cff_builder_start_point( builder, x, y ) ||
1468  cff_check_points( builder, 6 ) )
1469  goto Fail;
1470 
1471  /* record the starting point's y-position for later use */
1472  start_y = y;
1473 
1474  /* first control point */
1475  x = ADD_LONG( x, args[0] );
1476  cff_builder_add_point( builder, x, y, 0 );
1477 
1478  /* second control point */
1479  x = ADD_LONG( x, args[1] );
1480  y = ADD_LONG( y, args[2] );
1481  cff_builder_add_point( builder, x, y, 0 );
1482 
1483  /* join point; on curve, with y-value the same as the last */
1484  /* control point's y-value */
1485  x = ADD_LONG( x, args[3] );
1486  cff_builder_add_point( builder, x, y, 1 );
1487 
1488  /* third control point, with y-value the same as the join */
1489  /* point's y-value */
1490  x = ADD_LONG( x, args[4] );
1491  cff_builder_add_point( builder, x, y, 0 );
1492 
1493  /* fourth control point */
1494  x = ADD_LONG( x, args[5] );
1495  y = start_y;
1496  cff_builder_add_point( builder, x, y, 0 );
1497 
1498  /* ending point, with y-value the same as the start point's */
1499  /* y-value -- we don't add this point, though */
1500  x = ADD_LONG( x, args[6] );
1501  cff_builder_add_point( builder, x, y, 1 );
1502 
1503  args = stack;
1504  break;
1505  }
1506 
1507  case cff_op_flex1:
1508  {
1509  FT_Pos start_x, start_y; /* record start x, y values for */
1510  /* alter use */
1511  FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
1512  /* algorithm below */
1513  FT_Int horizontal, count;
1514  FT_Fixed* temp;
1515 
1516 
1517  FT_TRACE4(( " flex1\n" ));
1518 
1519  /* adding six more points; 4 control points, 2 on-curve points */
1520  if ( cff_builder_start_point( builder, x, y ) ||
1521  cff_check_points( builder, 6 ) )
1522  goto Fail;
1523 
1524  /* record the starting point's x, y position for later use */
1525  start_x = x;
1526  start_y = y;
1527 
1528  /* XXX: figure out whether this is supposed to be a horizontal */
1529  /* or vertical flex; the Type 2 specification is vague... */
1530 
1531  temp = args;
1532 
1533  /* grab up to the last argument */
1534  for ( count = 5; count > 0; count-- )
1535  {
1536  dx = ADD_LONG( dx, temp[0] );
1537  dy = ADD_LONG( dy, temp[1] );
1538  temp += 2;
1539  }
1540 
1541  if ( dx < 0 )
1542  dx = -dx;
1543  if ( dy < 0 )
1544  dy = -dy;
1545 
1546  /* strange test, but here it is... */
1547  horizontal = ( dx > dy );
1548 
1549  for ( count = 5; count > 0; count-- )
1550  {
1551  x = ADD_LONG( x, args[0] );
1552  y = ADD_LONG( y, args[1] );
1553  cff_builder_add_point( builder, x, y,
1554  (FT_Bool)( count == 3 ) );
1555  args += 2;
1556  }
1557 
1558  /* is last operand an x- or y-delta? */
1559  if ( horizontal )
1560  {
1561  x = ADD_LONG( x, args[0] );
1562  y = start_y;
1563  }
1564  else
1565  {
1566  x = start_x;
1567  y = ADD_LONG( y, args[0] );
1568  }
1569 
1570  cff_builder_add_point( builder, x, y, 1 );
1571 
1572  args = stack;
1573  break;
1574  }
1575 
1576  case cff_op_flex:
1577  {
1578  FT_UInt count;
1579 
1580 
1581  FT_TRACE4(( " flex\n" ));
1582 
1583  if ( cff_builder_start_point( builder, x, y ) ||
1584  cff_check_points( builder, 6 ) )
1585  goto Fail;
1586 
1587  for ( count = 6; count > 0; count-- )
1588  {
1589  x = ADD_LONG( x, args[0] );
1590  y = ADD_LONG( y, args[1] );
1591  cff_builder_add_point( builder, x, y,
1592  (FT_Bool)( count == 4 || count == 1 ) );
1593  args += 2;
1594  }
1595 
1596  args = stack;
1597  }
1598  break;
1599 
1600  case cff_op_seac:
1601  FT_TRACE4(( " seac\n" ));
1602 
1603  error = cff_operator_seac( decoder,
1604  args[0], args[1], args[2],
1605  (FT_Int)( args[3] >> 16 ),
1606  (FT_Int)( args[4] >> 16 ) );
1607 
1608  /* add current outline to the glyph slot */
1609  FT_GlyphLoader_Add( builder->loader );
1610 
1611  /* return now! */
1612  FT_TRACE4(( "\n" ));
1613  return error;
1614 
1615  case cff_op_endchar:
1616  /* in dictionaries, `endchar' simply indicates end of data */
1617  if ( in_dict )
1618  return error;
1619 
1620  FT_TRACE4(( " endchar\n" ));
1621 
1622  /* We are going to emulate the seac operator. */
1623  if ( num_args >= 4 )
1624  {
1625  /* Save glyph width so that the subglyphs don't overwrite it. */
1626  FT_Pos glyph_width = decoder->glyph_width;
1627 
1628 
1629  error = cff_operator_seac( decoder,
1630  0L, args[-4], args[-3],
1631  (FT_Int)( args[-2] >> 16 ),
1632  (FT_Int)( args[-1] >> 16 ) );
1633 
1634  decoder->glyph_width = glyph_width;
1635  }
1636  else
1637  {
1638  cff_builder_close_contour( builder );
1639 
1640  /* close hints recording session */
1641  if ( hinter )
1642  {
1643  if ( hinter->close( hinter->hints,
1644  (FT_UInt)builder->current->n_points ) )
1645  goto Syntax_Error;
1646 
1647  /* apply hints to the loaded glyph outline now */
1648  error = hinter->apply( hinter->hints,
1649  builder->current,
1650  (PSH_Globals)builder->hints_globals,
1651  decoder->hint_mode );
1652  if ( error )
1653  goto Fail;
1654  }
1655 
1656  /* add current outline to the glyph slot */
1657  FT_GlyphLoader_Add( builder->loader );
1658  }
1659 
1660  /* return now! */
1661  FT_TRACE4(( "\n" ));
1662  return error;
1663 
1664  case cff_op_abs:
1665  FT_TRACE4(( " abs\n" ));
1666 
1667  if ( args[0] < 0 )
1668  {
1669  if ( args[0] == FT_LONG_MIN )
1670  args[0] = FT_LONG_MAX;
1671  else
1672  args[0] = -args[0];
1673  }
1674  args++;
1675  break;
1676 
1677  case cff_op_add:
1678  FT_TRACE4(( " add\n" ));
1679 
1680  args[0] = ADD_LONG( args[0], args[1] );
1681  args++;
1682  break;
1683 
1684  case cff_op_sub:
1685  FT_TRACE4(( " sub\n" ));
1686 
1687  args[0] = SUB_LONG( args[0], args[1] );
1688  args++;
1689  break;
1690 
1691  case cff_op_div:
1692  FT_TRACE4(( " div\n" ));
1693 
1694  args[0] = FT_DivFix( args[0], args[1] );
1695  args++;
1696  break;
1697 
1698  case cff_op_neg:
1699  FT_TRACE4(( " neg\n" ));
1700 
1701  if ( args[0] == FT_LONG_MIN )
1702  args[0] = FT_LONG_MAX;
1703  args[0] = -args[0];
1704  args++;
1705  break;
1706 
1707  case cff_op_random:
1708  FT_TRACE4(( " random\n" ));
1709 
1710  /* only use the lower 16 bits of `random' */
1711  /* to generate a number in the range (0;1] */
1712  args[0] = (FT_Fixed)
1713  ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
1714  args++;
1715 
1716  decoder->current_subfont->random =
1717  cff_random( decoder->current_subfont->random );
1718  break;
1719 
1720  case cff_op_mul:
1721  FT_TRACE4(( " mul\n" ));
1722 
1723  args[0] = FT_MulFix( args[0], args[1] );
1724  args++;
1725  break;
1726 
1727  case cff_op_sqrt:
1728  FT_TRACE4(( " sqrt\n" ));
1729 
1730  if ( args[0] > 0 )
1731  {
1732  FT_Fixed root = args[0];
1733  FT_Fixed new_root;
1734 
1735 
1736  for (;;)
1737  {
1738  new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1739  if ( new_root == root )
1740  break;
1741  root = new_root;
1742  }
1743  args[0] = new_root;
1744  }
1745  else
1746  args[0] = 0;
1747  args++;
1748  break;
1749 
1750  case cff_op_drop:
1751  /* nothing */
1752  FT_TRACE4(( " drop\n" ));
1753 
1754  break;
1755 
1756  case cff_op_exch:
1757  {
1758  FT_Fixed tmp;
1759 
1760 
1761  FT_TRACE4(( " exch\n" ));
1762 
1763  tmp = args[0];
1764  args[0] = args[1];
1765  args[1] = tmp;
1766  args += 2;
1767  }
1768  break;
1769 
1770  case cff_op_index:
1771  {
1772  FT_Int idx = (FT_Int)( args[0] >> 16 );
1773 
1774 
1775  FT_TRACE4(( " index\n" ));
1776 
1777  if ( idx < 0 )
1778  idx = 0;
1779  else if ( idx > num_args - 2 )
1780  idx = num_args - 2;
1781  args[0] = args[-( idx + 1 )];
1782  args++;
1783  }
1784  break;
1785 
1786  case cff_op_roll:
1787  {
1788  FT_Int count = (FT_Int)( args[0] >> 16 );
1789  FT_Int idx = (FT_Int)( args[1] >> 16 );
1790 
1791 
1792  FT_TRACE4(( " roll\n" ));
1793 
1794  if ( count <= 0 )
1795  count = 1;
1796 
1797  args -= count;
1798  if ( args < stack )
1799  goto Stack_Underflow;
1800 
1801  if ( idx >= 0 )
1802  {
1803  while ( idx > 0 )
1804  {
1805  FT_Fixed tmp = args[count - 1];
1806  FT_Int i;
1807 
1808 
1809  for ( i = count - 2; i >= 0; i-- )
1810  args[i + 1] = args[i];
1811  args[0] = tmp;
1812  idx--;
1813  }
1814  }
1815  else
1816  {
1817  while ( idx < 0 )
1818  {
1819  FT_Fixed tmp = args[0];
1820  FT_Int i;
1821 
1822 
1823  for ( i = 0; i < count - 1; i++ )
1824  args[i] = args[i + 1];
1825  args[count - 1] = tmp;
1826  idx++;
1827  }
1828  }
1829  args += count;
1830  }
1831  break;
1832 
1833  case cff_op_dup:
1834  FT_TRACE4(( " dup\n" ));
1835 
1836  args[1] = args[0];
1837  args += 2;
1838  break;
1839 
1840  case cff_op_put:
1841  {
1842  FT_Fixed val = args[0];
1843  FT_Int idx = (FT_Int)( args[1] >> 16 );
1844 
1845 
1846  FT_TRACE4(( " put\n" ));
1847 
1848  /* the Type2 specification before version 16-March-2000 */
1849  /* didn't give a hard-coded size limit of the temporary */
1850  /* storage array; instead, an argument of the */
1851  /* `MultipleMaster' operator set the size */
1852  if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1853  decoder->buildchar[idx] = val;
1854  }
1855  break;
1856 
1857  case cff_op_get:
1858  {
1859  FT_Int idx = (FT_Int)( args[0] >> 16 );
1860  FT_Fixed val = 0;
1861 
1862 
1863  FT_TRACE4(( " get\n" ));
1864 
1865  if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1866  val = decoder->buildchar[idx];
1867 
1868  args[0] = val;
1869  args++;
1870  }
1871  break;
1872 
1873  case cff_op_store:
1874  /* this operator was removed from the Type2 specification */
1875  /* in version 16-March-2000 */
1876 
1877  /* since we currently don't handle interpolation of multiple */
1878  /* master fonts, this is a no-op */
1879  FT_TRACE4(( " store\n" ));
1880  break;
1881 
1882  case cff_op_load:
1883  /* this operator was removed from the Type2 specification */
1884  /* in version 16-March-2000 */
1885  {
1886  FT_Int reg_idx = (FT_Int)args[0];
1887  FT_Int idx = (FT_Int)args[1];
1888  FT_Int count = (FT_Int)args[2];
1889 
1890 
1891  FT_TRACE4(( " load\n" ));
1892 
1893  /* since we currently don't handle interpolation of multiple */
1894  /* master fonts, we store a vector [1 0 0 ...] in the */
1895  /* temporary storage array regardless of the Registry index */
1896  if ( reg_idx >= 0 && reg_idx <= 2 &&
1897  idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1898  count >= 0 && count <= num_axes )
1899  {
1900  FT_Int end, i;
1901 
1902 
1904 
1905  if ( idx < end )
1906  decoder->buildchar[idx] = 1 << 16;
1907 
1908  for ( i = idx + 1; i < end; i++ )
1909  decoder->buildchar[i] = 0;
1910  }
1911  }
1912  break;
1913 
1914  case cff_op_blend:
1915  /* this operator was removed from the Type2 specification */
1916  /* in version 16-March-2000 */
1917  {
1918  FT_Int num_results = (FT_Int)( args[0] >> 16 );
1919 
1920 
1921  FT_TRACE4(( " blend\n" ));
1922 
1923  if ( num_results < 0 )
1924  goto Syntax_Error;
1925 
1926  if ( num_results * (FT_Int)num_designs > num_args )
1927  goto Stack_Underflow;
1928 
1929  /* since we currently don't handle interpolation of multiple */
1930  /* master fonts, return the `num_results' values of the */
1931  /* first master */
1932  args -= num_results * ( num_designs - 1 );
1933  num_args -= num_results * ( num_designs - 1 );
1934  }
1935  break;
1936 
1937  case cff_op_dotsection:
1938  /* this operator is deprecated and ignored by the parser */
1939  FT_TRACE4(( " dotsection\n" ));
1940  break;
1941 
1942  case cff_op_closepath:
1943  /* this is an invalid Type 2 operator; however, there */
1944  /* exist fonts which are incorrectly converted from probably */
1945  /* Type 1 to CFF, and some parsers seem to accept it */
1946 
1947  FT_TRACE4(( " closepath (invalid op)\n" ));
1948 
1949  args = stack;
1950  break;
1951 
1952  case cff_op_hsbw:
1953  /* this is an invalid Type 2 operator; however, there */
1954  /* exist fonts which are incorrectly converted from probably */
1955  /* Type 1 to CFF, and some parsers seem to accept it */
1956 
1957  FT_TRACE4(( " hsbw (invalid op)\n" ));
1958 
1959  decoder->glyph_width =
1960  ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
1961 
1962  decoder->builder.left_bearing.x = args[0];
1963  decoder->builder.left_bearing.y = 0;
1964 
1965  x = ADD_LONG( decoder->builder.pos_x, args[0] );
1966  y = decoder->builder.pos_y;
1967  args = stack;
1968  break;
1969 
1970  case cff_op_sbw:
1971  /* this is an invalid Type 2 operator; however, there */
1972  /* exist fonts which are incorrectly converted from probably */
1973  /* Type 1 to CFF, and some parsers seem to accept it */
1974 
1975  FT_TRACE4(( " sbw (invalid op)\n" ));
1976 
1977  decoder->glyph_width =
1978  ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
1979 
1980  decoder->builder.left_bearing.x = args[0];
1981  decoder->builder.left_bearing.y = args[1];
1982 
1983  x = ADD_LONG( decoder->builder.pos_x, args[0] );
1984  y = ADD_LONG( decoder->builder.pos_y, args[1] );
1985  args = stack;
1986  break;
1987 
1988  case cff_op_setcurrentpoint:
1989  /* this is an invalid Type 2 operator; however, there */
1990  /* exist fonts which are incorrectly converted from probably */
1991  /* Type 1 to CFF, and some parsers seem to accept it */
1992 
1993  FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
1994 
1995  x = ADD_LONG( decoder->builder.pos_x, args[0] );
1996  y = ADD_LONG( decoder->builder.pos_y, args[1] );
1997  args = stack;
1998  break;
1999 
2000  case cff_op_callothersubr:
2001  /* this is an invalid Type 2 operator; however, there */
2002  /* exist fonts which are incorrectly converted from probably */
2003  /* Type 1 to CFF, and some parsers seem to accept it */
2004 
2005  FT_TRACE4(( " callothersubr (invalid op)\n" ));
2006 
2007  /* subsequent `pop' operands should add the arguments, */
2008  /* this is the implementation described for `unknown' other */
2009  /* subroutines in the Type1 spec. */
2010  /* */
2011  /* XXX Fix return arguments (see discussion below). */
2012  args -= 2 + ( args[-2] >> 16 );
2013  if ( args < stack )
2014  goto Stack_Underflow;
2015  break;
2016 
2017  case cff_op_pop:
2018  /* this is an invalid Type 2 operator; however, there */
2019  /* exist fonts which are incorrectly converted from probably */
2020  /* Type 1 to CFF, and some parsers seem to accept it */
2021 
2022  FT_TRACE4(( " pop (invalid op)\n" ));
2023 
2024  /* XXX Increasing `args' is wrong: After a certain number of */
2025  /* `pop's we get a stack overflow. Reason for doing it is */
2026  /* code like this (actually found in a CFF font): */
2027  /* */
2028  /* 17 1 3 callothersubr */
2029  /* pop */
2030  /* callsubr */
2031  /* */
2032  /* Since we handle `callothersubr' as a no-op, and */
2033  /* `callsubr' needs at least one argument, `pop' can't be a */
2034  /* no-op too as it basically should be. */
2035  /* */
2036  /* The right solution would be to provide real support for */
2037  /* `callothersubr' as done in `t1decode.c', however, given */
2038  /* the fact that CFF fonts with `pop' are invalid, it is */
2039  /* questionable whether it is worth the time. */
2040  args++;
2041  break;
2042 
2043  case cff_op_and:
2044  {
2045  FT_Fixed cond = ( args[0] && args[1] );
2046 
2047 
2048  FT_TRACE4(( " and\n" ));
2049 
2050  args[0] = cond ? 0x10000L : 0;
2051  args++;
2052  }
2053  break;
2054 
2055  case cff_op_or:
2056  {
2057  FT_Fixed cond = ( args[0] || args[1] );
2058 
2059 
2060  FT_TRACE4(( " or\n" ));
2061 
2062  args[0] = cond ? 0x10000L : 0;
2063  args++;
2064  }
2065  break;
2066 
2067  case cff_op_not:
2068  {
2069  FT_Fixed cond = !args[0];
2070 
2071 
2072  FT_TRACE4(( " not\n" ));
2073 
2074  args[0] = cond ? 0x10000L : 0;
2075  args++;
2076  }
2077  break;
2078 
2079  case cff_op_eq:
2080  {
2081  FT_Fixed cond = ( args[0] == args[1] );
2082 
2083 
2084  FT_TRACE4(( " eq\n" ));
2085 
2086  args[0] = cond ? 0x10000L : 0;
2087  args++;
2088  }
2089  break;
2090 
2091  case cff_op_ifelse:
2092  {
2093  FT_Fixed cond = ( args[2] <= args[3] );
2094 
2095 
2096  FT_TRACE4(( " ifelse\n" ));
2097 
2098  if ( !cond )
2099  args[0] = args[1];
2100  args++;
2101  }
2102  break;
2103 
2104  case cff_op_callsubr:
2105  {
2106  FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2107  decoder->locals_bias );
2108 
2109 
2110  FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
2111  idx,
2112  zone - decoder->zones + 1 ));
2113 
2114  if ( idx >= decoder->num_locals )
2115  {
2116  FT_ERROR(( "cff_decoder_parse_charstrings:"
2117  " invalid local subr index\n" ));
2118  goto Syntax_Error;
2119  }
2120 
2121  if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2122  {
2123  FT_ERROR(( "cff_decoder_parse_charstrings:"
2124  " too many nested subrs\n" ));
2125  goto Syntax_Error;
2126  }
2127 
2128  zone->cursor = ip; /* save current instruction pointer */
2129 
2130  zone++;
2131  zone->base = decoder->locals[idx];
2132  zone->limit = decoder->locals[idx + 1];
2133  zone->cursor = zone->base;
2134 
2135  if ( !zone->base || zone->limit == zone->base )
2136  {
2137  FT_ERROR(( "cff_decoder_parse_charstrings:"
2138  " invoking empty subrs\n" ));
2139  goto Syntax_Error;
2140  }
2141 
2142  decoder->zone = zone;
2143  ip = zone->base;
2144  limit = zone->limit;
2145  }
2146  break;
2147 
2148  case cff_op_callgsubr:
2149  {
2150  FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2151  decoder->globals_bias );
2152 
2153 
2154  FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
2155  idx,
2156  zone - decoder->zones + 1 ));
2157 
2158  if ( idx >= decoder->num_globals )
2159  {
2160  FT_ERROR(( "cff_decoder_parse_charstrings:"
2161  " invalid global subr index\n" ));
2162  goto Syntax_Error;
2163  }
2164 
2165  if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2166  {
2167  FT_ERROR(( "cff_decoder_parse_charstrings:"
2168  " too many nested subrs\n" ));
2169  goto Syntax_Error;
2170  }
2171 
2172  zone->cursor = ip; /* save current instruction pointer */
2173 
2174  zone++;
2175  zone->base = decoder->globals[idx];
2176  zone->limit = decoder->globals[idx + 1];
2177  zone->cursor = zone->base;
2178 
2179  if ( !zone->base || zone->limit == zone->base )
2180  {
2181  FT_ERROR(( "cff_decoder_parse_charstrings:"
2182  " invoking empty subrs\n" ));
2183  goto Syntax_Error;
2184  }
2185 
2186  decoder->zone = zone;
2187  ip = zone->base;
2188  limit = zone->limit;
2189  }
2190  break;
2191 
2192  case cff_op_return:
2193  FT_TRACE4(( " return (leaving level %d)\n",
2194  decoder->zone - decoder->zones ));
2195 
2196  if ( decoder->zone <= decoder->zones )
2197  {
2198  FT_ERROR(( "cff_decoder_parse_charstrings:"
2199  " unexpected return\n" ));
2200  goto Syntax_Error;
2201  }
2202 
2203  decoder->zone--;
2204  zone = decoder->zone;
2205  ip = zone->cursor;
2206  limit = zone->limit;
2207  break;
2208 
2209  default:
2210  FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2211 
2212  if ( ip[-1] == 12 )
2213  FT_ERROR(( " %d", ip[0] ));
2214  FT_ERROR(( "\n" ));
2215 
2216  return FT_THROW( Unimplemented_Feature );
2217  }
2218 
2219  decoder->top = args;
2220 
2221  if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2222  goto Stack_Overflow;
2223 
2224  } /* general operator processing */
2225 
2226  } /* while ip < limit */
2227 
2228  FT_TRACE4(( "..end..\n\n" ));
2229 
2230  Fail:
2231  return error;
2232 
2233  MM_Error:
2234  FT_TRACE4(( "cff_decoder_parse_charstrings:"
2235  " invalid opcode found in top DICT charstring\n"));
2236  return FT_THROW( Invalid_File_Format );
2237 
2238  Syntax_Error:
2239  FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2240  return FT_THROW( Invalid_File_Format );
2241 
2242  Stack_Underflow:
2243  FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2244  return FT_THROW( Too_Few_Arguments );
2245 
2246  Stack_Overflow:
2247  FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2248  return FT_THROW( Stack_Overflow );
2249  }
2250 
2251 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2252 
2253 
2254  /*************************************************************************/
2255  /* */
2256  /* <Function> */
2257  /* cff_decoder_init */
2258  /* */
2259  /* <Description> */
2260  /* Initializes a given glyph decoder. */
2261  /* */
2262  /* <InOut> */
2263  /* decoder :: A pointer to the glyph builder to initialize. */
2264  /* */
2265  /* <Input> */
2266  /* face :: The current face object. */
2267  /* */
2268  /* size :: The current size object. */
2269  /* */
2270  /* slot :: The current glyph object. */
2271  /* */
2272  /* hinting :: Whether hinting is active. */
2273  /* */
2274  /* hint_mode :: The hinting mode. */
2275  /* */
2276  FT_LOCAL_DEF( void )
2278  TT_Face face,
2279  CFF_Size size,
2281  FT_Bool hinting,
2282  FT_Render_Mode hint_mode,
2284  CFF_Decoder_Free_Glyph_Callback free_callback )
2285  {
2286  CFF_Font cff = (CFF_Font)face->extra.data;
2287 
2288 
2289  /* clear everything */
2290  FT_ZERO( decoder );
2291 
2292  /* initialize builder */
2293  cff_builder_init( &decoder->builder, face, size, slot, hinting );
2294 
2295  /* initialize Type2 decoder */
2296  decoder->cff = cff;
2297  decoder->num_globals = cff->global_subrs_index.count;
2298  decoder->globals = cff->global_subrs;
2299  decoder->globals_bias = cff_compute_bias(
2301  decoder->num_globals );
2302 
2303  decoder->hint_mode = hint_mode;
2304 
2305  decoder->get_glyph_callback = get_callback;
2306  decoder->free_glyph_callback = free_callback;
2307  }
2308 
2309 
2310  /* this function is used to select the subfont */
2311  /* and the locals subrs array */
2314  CFF_Size size,
2315  FT_UInt glyph_index )
2316  {
2317  CFF_Builder *builder = &decoder->builder;
2318  CFF_Font cff = (CFF_Font)builder->face->extra.data;
2319  CFF_SubFont sub = &cff->top_font;
2321 
2322  FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload;
2323 
2324 
2325  /* manage CID fonts */
2326  if ( cff->num_subfonts )
2327  {
2328  FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select,
2329  glyph_index );
2330 
2331 
2332  if ( fd_index >= cff->num_subfonts )
2333  {
2334  FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
2335  error = FT_THROW( Invalid_File_Format );
2336  goto Exit;
2337  }
2338 
2339  FT_TRACE3(( " in subfont %d:\n", fd_index ));
2340 
2341  sub = cff->subfonts[fd_index];
2342 
2343  if ( builder->hints_funcs && size )
2344  {
2345  FT_Size ftsize = FT_SIZE( size );
2346  CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
2347 
2348 
2349  /* for CFFs without subfonts, this value has already been set */
2350  builder->hints_globals = (void *)internal->subfonts[fd_index];
2351  }
2352  }
2353 
2354  decoder->num_locals = sub->local_subrs_index.count;
2355  decoder->locals = sub->local_subrs;
2356  decoder->locals_bias = cff_compute_bias(
2357  decoder->cff->top_font.font_dict.charstring_type,
2358  decoder->num_locals );
2359 
2360  decoder->glyph_width = sub->private_dict.default_width;
2361  decoder->nominal_width = sub->private_dict.nominal_width;
2362 
2363  decoder->current_subfont = sub;
2364 
2365  Exit:
2366  return error;
2367  }
2368 
2369 
2370 /* END */
int FT_Error
Definition: fttypes.h:300
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_Pos y
Definition: ftimage.h:77
static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
Definition: binding.c:1411
#define TRUE
Definition: types.h:120
#define shift
Definition: input.c:1668
unsigned long FT_ULong
Definition: fttypes.h:253
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
FT_UInt num_globals
Definition: psaux.h:1126
FT_Byte ** globals
Definition: psaux.h:1132
FT_Fixed * top
Definition: psaux.h:1108
static int start_x
Definition: maze.c:118
FT_Int charstring_type
Definition: cfftypes.h:193
FT_Size_Internal internal
Definition: freetype.h:1678
#define error(str)
Definition: mkdosfs.c:1605
#define CFF_MAX_SUBRS_CALLS
Definition: psaux.h:1083
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3923
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:300
CFF_Decoder_Zone * zone
Definition: psaux.h:1111
FT_Render_Mode hint_mode
Definition: psaux.h:1137
T2_Hints_ApplyFunc apply
Definition: pshints.h:664
cff_builder_init(CFF_Builder *builder, TT_Face face, CFF_Size size, CFF_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1793
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3928
const struct T2_Hints_FuncsRec_ * T2_Hints_Funcs
Definition: pshints.h:404
T2_Hints_OpenFunc open
Definition: pshints.h:659
FT_Pos x
Definition: ftimage.h:76
static FT_Int cff_compute_bias(FT_Int in_charstring_type, FT_UInt num_subrs)
Definition: cffdecode.c:399
T2_Hints_StemsFunc stems
Definition: pshints.h:661
signed int FT_Int
Definition: fttypes.h:220
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
FT_Bool path_begun
Definition: psaux.h:1060
FT_Vector left_bearing
Definition: psaux.h:1055
enum FT_Render_Mode_ FT_Render_Mode
#define U(x)
Definition: wordpad.c:44
FT_Pos glyph_width
Definition: psaux.h:1117
FT_UShort num_axes
Definition: cfftypes.h:227
void * module_data
Definition: ftobjs.h:497
GLdouble n
Definition: glext.h:7729
FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]
Definition: psaux.h:1123
CFF_Decoder_Free_Glyph_Callback free_glyph_callback
Definition: psaux.h:1144
CFF_SubFont current_subfont
Definition: psaux.h:1141
FT_UInt num_subfonts
Definition: cfftypes.h:374
#define FT_MIN(a, b)
Definition: ftobjs.h:71
cff_check_points(CFF_Builder *builder, FT_Int count)
Definition: psobjs.c:1870
cff_lookup_glyph_by_stdcharcode(CFF_Font cff, FT_Int charcode)
Definition: cffdecode.c:419
JSAMPARRAY JDIMENSION num_lines
Definition: jpeglib.h:1013
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
FT_UShort num_designs
Definition: cfftypes.h:226
static stack_node_t * stack
Definition: rpn_ieee.c:37
FT_Vector advance
Definition: psaux.h:1056
GLuint GLuint end
Definition: gl.h:1545
CFF_IndexRec global_subrs_index
Definition: cfftypes.h:352
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:125
FT_Byte ** global_subrs
Definition: cfftypes.h:365
return FT_Err_Ok
Definition: ftbbox.c:511
Definition: match.c:390
CFF_Builder builder
Definition: psaux.h:1104
GLint limit
Definition: glext.h:10326
cff_random(FT_UInt32 r)
Definition: psobjs.c:2522
FT_Bool seac
Definition: psaux.h:1139
T2_Hints_CounterFunc counter
Definition: pshints.h:663
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
#define FT_LONG_MAX
Definition: ftstdlib.h:67
cff_decoder_prepare(CFF_Decoder *decoder, CFF_Size size, FT_UInt glyph_index)
Definition: cffdecode.c:2313
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FT_UInt num_locals
Definition: psaux.h:1125
FT_Bool width_only
Definition: psaux.h:1121
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define ADD_LONG(a, b)
Definition: ftcalc.h:420
unsigned char FT_Byte
Definition: fttypes.h:154
FT_GlyphLoader loader
Definition: ftobjs.h:467
FT_Int globals_bias
Definition: psaux.h:1129
#define FT_THROW(e)
Definition: ftdebug.h:213
const void * cffload
Definition: cfftypes.h:386
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
int ip[4]
Definition: rtl.c:1176
unsigned int idx
Definition: utils.c:41
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
#define CFF_MAX_TRANS_ELEMENTS
Definition: psaux.h:1089
FT_Error(* CFF_Decoder_Get_Glyph_Callback)(TT_Face face, FT_UInt glyph_index, FT_Byte **pointer, FT_ULong *length)
Definition: psaux.h:588
cff_decoder_init(CFF_Decoder *decoder, TT_Face face, CFF_Size size, CFF_GlyphSlot slot, FT_Bool hinting, FT_Render_Mode hint_mode, CFF_Decoder_Get_Glyph_Callback get_callback, CFF_Decoder_Free_Glyph_Callback free_callback)
Definition: cffdecode.c:2277
CFF_Font cff
Definition: cffdrivr.c:695
CFF_FDSelectRec fd_select
Definition: cfftypes.h:377
FT_Pos pos_x
Definition: psaux.h:1052
cff_builder_add_point1(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1917
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
FT_GlyphLoader loader
Definition: psaux.h:1048
FT_UInt32 random
Definition: cfftypes.h:325
GLuint GLfloat * val
Definition: glext.h:7180
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
Definition: _stack.h:47
T2_Hints hints
Definition: pshints.h:658
GLsizeiptr size
Definition: glext.h:5919
#define FT_ZERO(p)
Definition: ftmemory.h:237
FT_Bool read_width
Definition: psaux.h:1120
Definition: dhcpd.h:61
void * hints_globals
Definition: psaux.h:1067
if(!(yy_init))
Definition: macro.lex.yy.c:714
FT_Outline * current
Definition: psaux.h:1050
FT_Pos pos_y
Definition: psaux.h:1053
static void Exit(void)
Definition: sock.c:1331
FT_Byte ** locals
Definition: psaux.h:1131
void * data
Definition: fttypes.h:461
FT_UInt num_subglyphs
Definition: freetype.h:1929
CFF_Decoder_Get_Glyph_Callback get_glyph_callback
Definition: psaux.h:1143
FT_Bool no_recurse
Definition: psaux.h:1062
FT_Pos nominal_width
Definition: psaux.h:1118
TT_Face face
Definition: psaux.h:1046
static const WCHAR L[]
Definition: oid.c:1250
signed short FT_Short
Definition: fttypes.h:198
cff_builder_close_contour(CFF_Builder *builder)
Definition: psobjs.c:1984
FT_Generic extra
Definition: tttypes.h:1498
T2_Hints_MaskFunc hintmask
Definition: pshints.h:662
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
FT_UShort * sids
Definition: cfftypes.h:98
FT_Int num_hints
Definition: psaux.h:1122
#define CFF_MAX_OPERANDS
Definition: psaux.h:1082
#define FT_SIZE(x)
Definition: ftobjs.h:631
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
Definition: vfat.h:184
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
struct CFF_FontRec_ * CFF_Font
Definition: cfftypes.h:152
Definition: hiveinit.c:368
FT_Int locals_bias
Definition: psaux.h:1128
DWORD zone
Definition: sec_mgr.c:1760
FT_UInt num_glyphs
Definition: cfftypes.h:340
FT_Glyph_Format format
Definition: freetype.h:1921
CFF_Font cff
Definition: psaux.h:1105
signed long FT_Fixed
Definition: fttypes.h:288
short n_points
Definition: ftimage.h:337
void * hints_funcs
Definition: psaux.h:1066
const GLdouble * v
Definition: gl.h:2040
static calc_node_t temp
Definition: rpn_ieee.c:38
unsigned int FT_UInt
Definition: fttypes.h:231
void(* CFF_Decoder_Free_Glyph_Callback)(TT_Face face, FT_Byte **pointer, FT_ULong length)
Definition: psaux.h:594
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:554
CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS+1]
Definition: psaux.h:1110
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
CFF_SubFont subfonts[CFF_MAX_CID_FONTS]
Definition: cfftypes.h:375
FT_Fixed stack[CFF_MAX_OPERANDS+1]
Definition: psaux.h:1107
cff_builder_start_point(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1962
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:312
struct CFF_InternalRec_ * CFF_Internal
FT_Slot_Internal internal
Definition: freetype.h:1940
static int start_y
Definition: maze.c:118
CFF_GlyphSlot glyph
Definition: psaux.h:1047
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
UINT op
Definition: effect.c:223
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
unsigned short FT_UShort
Definition: fttypes.h:209
T2_Hints_CloseFunc close
Definition: pshints.h:660
cff_builder_add_point(CFF_Builder *builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1879
GLuint64EXT * result
Definition: glext.h:11304
#define args
Definition: format.c:66
FT_SubGlyph subglyphs
Definition: freetype.h:1930
CFF_CharsetRec charset
Definition: cfftypes.h:355
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:41
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
#define FT_LONG_MIN
Definition: ftstdlib.h:66
CFF_SubFontRec top_font
Definition: cfftypes.h:373