ReactOS  0.4.13-dev-544-gede3fdd
t1decode.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* t1decode.c */
4 /* */
5 /* PostScript Type 1 decoding routines (body). */
6 /* */
7 /* Copyright 2000-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_INTERNAL_CALC_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
23 #include FT_INTERNAL_HASH_H
24 #include FT_OUTLINE_H
25 
26 #include "t1decode.h"
27 #include "psobjs.h"
28 
29 #include "psauxerr.h"
30 
31 /* ensure proper sign extension */
32 #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) )
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_t1decode
42 
43 
44  typedef enum T1_Operator_
45  {
46  op_none = 0,
73 
74  op_max /* never remove this one */
75 
76  } T1_Operator;
77 
78 
79  static
81  {
82  0, /* none */
83  0, /* endchar */
84  2, /* hsbw */
85  5, /* seac */
86  4, /* sbw */
87  0, /* closepath */
88  1, /* hlineto */
89  1, /* hmoveto */
90  4, /* hvcurveto */
91  2, /* rlineto */
92  2, /* rmoveto */
93  6, /* rrcurveto */
94  4, /* vhcurveto */
95  1, /* vlineto */
96  1, /* vmoveto */
97  0, /* dotsection */
98  2, /* hstem */
99  6, /* hstem3 */
100  2, /* vstem */
101  6, /* vstem3 */
102  2, /* div */
103  -1, /* callothersubr */
104  1, /* callsubr */
105  0, /* pop */
106  0, /* return */
107  2, /* setcurrentpoint */
108  2 /* opcode 15 (undocumented and obsolete) */
109  };
110 
111 
112  /*************************************************************************/
113  /* */
114  /* <Function> */
115  /* t1_lookup_glyph_by_stdcharcode_ps */
116  /* */
117  /* <Description> */
118  /* Looks up a given glyph by its StandardEncoding charcode. Used to */
119  /* implement the SEAC Type 1 operator in the Adobe engine */
120  /* */
121  /* <Input> */
122  /* face :: The current face object. */
123  /* */
124  /* charcode :: The character code to look for. */
125  /* */
126  /* <Return> */
127  /* A glyph index in the font face. Returns -1 if the corresponding */
128  /* glyph wasn't found. */
129  /* */
132  FT_Int charcode )
133  {
134  FT_UInt n;
135  const FT_String* glyph_name;
136  FT_Service_PsCMaps psnames = decoder->psnames;
137 
138 
139  /* check range of standard char code */
140  if ( charcode < 0 || charcode > 255 )
141  return -1;
142 
143  glyph_name = psnames->adobe_std_strings(
144  psnames->adobe_std_encoding[charcode]);
145 
146  for ( n = 0; n < decoder->num_glyphs; n++ )
147  {
148  FT_String* name = (FT_String*)decoder->glyph_names[n];
149 
150 
151  if ( name &&
152  name[0] == glyph_name[0] &&
153  ft_strcmp( name, glyph_name ) == 0 )
154  return (FT_Int)n;
155  }
156 
157  return -1;
158  }
159 
160 
161 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
162  /*************************************************************************/
163  /* */
164  /* <Function> */
165  /* t1_lookup_glyph_by_stdcharcode */
166  /* */
167  /* <Description> */
168  /* Looks up a given glyph by its StandardEncoding charcode. Used to */
169  /* implement the SEAC Type 1 operator. */
170  /* */
171  /* <Input> */
172  /* face :: The current face object. */
173  /* */
174  /* charcode :: The character code to look for. */
175  /* */
176  /* <Return> */
177  /* A glyph index in the font face. Returns -1 if the corresponding */
178  /* glyph wasn't found. */
179  /* */
180  static FT_Int
181  t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder,
182  FT_Int charcode )
183  {
184  FT_UInt n;
185  const FT_String* glyph_name;
186  FT_Service_PsCMaps psnames = decoder->psnames;
187 
188 
189  /* check range of standard char code */
190  if ( charcode < 0 || charcode > 255 )
191  return -1;
192 
193  glyph_name = psnames->adobe_std_strings(
194  psnames->adobe_std_encoding[charcode]);
195 
196  for ( n = 0; n < decoder->num_glyphs; n++ )
197  {
198  FT_String* name = (FT_String*)decoder->glyph_names[n];
199 
200 
201  if ( name &&
202  name[0] == glyph_name[0] &&
203  ft_strcmp( name, glyph_name ) == 0 )
204  return (FT_Int)n;
205  }
206 
207  return -1;
208  }
209 
210 
211  /* parse a single Type 1 glyph */
213  t1_decoder_parse_glyph( T1_Decoder decoder,
214  FT_UInt glyph )
215  {
216  return decoder->parse_callback( decoder, glyph );
217  }
218 
219 
220  /*************************************************************************/
221  /* */
222  /* <Function> */
223  /* t1operator_seac */
224  /* */
225  /* <Description> */
226  /* Implements the `seac' Type 1 operator for a Type 1 decoder. */
227  /* */
228  /* <Input> */
229  /* decoder :: The current CID decoder. */
230  /* */
231  /* asb :: The accent's side bearing. */
232  /* */
233  /* adx :: The horizontal offset of the accent. */
234  /* */
235  /* ady :: The vertical offset of the accent. */
236  /* */
237  /* bchar :: The base character's StandardEncoding charcode. */
238  /* */
239  /* achar :: The accent character's StandardEncoding charcode. */
240  /* */
241  /* <Return> */
242  /* FreeType error code. 0 means success. */
243  /* */
244  static FT_Error
245  t1operator_seac( T1_Decoder decoder,
246  FT_Pos asb,
247  FT_Pos adx,
248  FT_Pos ady,
249  FT_Int bchar,
250  FT_Int achar )
251  {
252  FT_Error error;
253  FT_Int bchar_index, achar_index;
254 #if 0
255  FT_Int n_base_points;
256  FT_Outline* base = decoder->builder.base;
257 #endif
258  FT_Vector left_bearing, advance;
259 
260 #ifdef FT_CONFIG_OPTION_INCREMENTAL
261  T1_Face face = (T1_Face)decoder->builder.face;
262 #endif
263 
264 
265  if ( decoder->seac )
266  {
267  FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
268  return FT_THROW( Syntax_Error );
269  }
270 
271  if ( decoder->builder.metrics_only )
272  {
273  FT_ERROR(( "t1operator_seac: unexpected seac\n" ));
274  return FT_THROW( Syntax_Error );
275  }
276 
277  /* seac weirdness */
278  adx += decoder->builder.left_bearing.x;
279 
280  /* `glyph_names' is set to 0 for CID fonts which do not */
281  /* include an encoding. How can we deal with these? */
282 #ifdef FT_CONFIG_OPTION_INCREMENTAL
283  if ( decoder->glyph_names == 0 &&
284  !face->root.internal->incremental_interface )
285 #else
286  if ( decoder->glyph_names == 0 )
287 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
288  {
289  FT_ERROR(( "t1operator_seac:"
290  " glyph names table not available in this font\n" ));
291  return FT_THROW( Syntax_Error );
292  }
293 
294 #ifdef FT_CONFIG_OPTION_INCREMENTAL
295  if ( face->root.internal->incremental_interface )
296  {
297  /* the caller must handle the font encoding also */
298  bchar_index = bchar;
299  achar_index = achar;
300  }
301  else
302 #endif
303  {
304  bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
305  achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
306  }
307 
308  if ( bchar_index < 0 || achar_index < 0 )
309  {
310  FT_ERROR(( "t1operator_seac:"
311  " invalid seac character code arguments\n" ));
312  return FT_THROW( Syntax_Error );
313  }
314 
315  /* if we are trying to load a composite glyph, do not load the */
316  /* accent character and return the array of subglyphs. */
317  if ( decoder->builder.no_recurse )
318  {
319  FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
320  FT_GlyphLoader loader = glyph->internal->loader;
321  FT_SubGlyph subg;
322 
323 
324  /* reallocate subglyph array if necessary */
325  error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
326  if ( error )
327  goto Exit;
328 
329  subg = loader->current.subglyphs;
330 
331  /* subglyph 0 = base character */
332  subg->index = bchar_index;
335  subg->arg1 = 0;
336  subg->arg2 = 0;
337  subg++;
338 
339  /* subglyph 1 = accent character */
340  subg->index = achar_index;
342  subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
343  subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
344 
345  /* set up remaining glyph fields */
346  glyph->num_subglyphs = 2;
347  glyph->subglyphs = loader->base.subglyphs;
348  glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
349 
350  loader->current.num_subglyphs = 2;
351  goto Exit;
352  }
353 
354  /* First load `bchar' in builder */
355  /* now load the unscaled outline */
356 
357  FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
358 
359  /* the seac operator must not be nested */
360  decoder->seac = TRUE;
361  error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
362  decoder->seac = FALSE;
363  if ( error )
364  goto Exit;
365 
366  /* save the left bearing and width of the base character */
367  /* as they will be erased by the next load. */
368 
369  left_bearing = decoder->builder.left_bearing;
370  advance = decoder->builder.advance;
371 
372  decoder->builder.left_bearing.x = 0;
373  decoder->builder.left_bearing.y = 0;
374 
375  decoder->builder.pos_x = adx - asb;
376  decoder->builder.pos_y = ady;
377 
378  /* Now load `achar' on top of */
379  /* the base outline */
380 
381  /* the seac operator must not be nested */
382  decoder->seac = TRUE;
383  error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
384  decoder->seac = FALSE;
385  if ( error )
386  goto Exit;
387 
388  /* restore the left side bearing and */
389  /* advance width of the base character */
390 
391  decoder->builder.left_bearing = left_bearing;
392  decoder->builder.advance = advance;
393 
394  decoder->builder.pos_x = 0;
395  decoder->builder.pos_y = 0;
396 
397  Exit:
398  return error;
399  }
400 
401 
402  /*************************************************************************/
403  /* */
404  /* <Function> */
405  /* t1_decoder_parse_charstrings */
406  /* */
407  /* <Description> */
408  /* Parses a given Type 1 charstrings program. */
409  /* */
410  /* <Input> */
411  /* decoder :: The current Type 1 decoder. */
412  /* */
413  /* charstring_base :: The base address of the charstring stream. */
414  /* */
415  /* charstring_len :: The length in bytes of the charstring stream. */
416  /* */
417  /* <Return> */
418  /* FreeType error code. 0 means success. */
419  /* */
421  t1_decoder_parse_charstrings( T1_Decoder decoder,
422  FT_Byte* charstring_base,
423  FT_UInt charstring_len )
424  {
425  FT_Error error;
427  FT_Byte* ip;
428  FT_Byte* limit;
429  T1_Builder builder = &decoder->builder;
430  FT_Pos x, y, orig_x, orig_y;
431  FT_Int known_othersubr_result_cnt = 0;
432  FT_Int unknown_othersubr_result_cnt = 0;
433  FT_Bool large_int;
434  FT_Fixed seed;
435 
436  T1_Hints_Funcs hinter;
437 
438 #ifdef FT_DEBUG_LEVEL_TRACE
439  FT_Bool bol = TRUE;
440 #endif
441 
442 
443  /* compute random seed from stack address of parameter */
444  seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^
445  (FT_Offset)(char*)&decoder ^
446  (FT_Offset)(char*)&charstring_base ) &
447  FT_ULONG_MAX );
448  seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
449  if ( seed == 0 )
450  seed = 0x7384;
451 
452  /* First of all, initialize the decoder */
453  decoder->top = decoder->stack;
454  decoder->zone = decoder->zones;
455  zone = decoder->zones;
456 
457  builder->parse_state = T1_Parse_Start;
458 
459  hinter = (T1_Hints_Funcs)builder->hints_funcs;
460 
461  /* a font that reads BuildCharArray without setting */
462  /* its values first is buggy, but ... */
463  FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
464  ( decoder->buildchar == NULL ) );
465 
466  if ( decoder->buildchar && decoder->len_buildchar > 0 )
467  FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
468 
469  FT_TRACE4(( "\n"
470  "Start charstring\n" ));
471 
472  zone->base = charstring_base;
473  limit = zone->limit = charstring_base + charstring_len;
474  ip = zone->cursor = zone->base;
475 
476  error = FT_Err_Ok;
477 
478  x = orig_x = builder->pos_x;
479  y = orig_y = builder->pos_y;
480 
481  /* begin hints recording session, if any */
482  if ( hinter )
483  hinter->open( hinter->hints );
484 
485  large_int = FALSE;
486 
487  /* now, execute loop */
488  while ( ip < limit )
489  {
490  FT_Long* top = decoder->top;
492  FT_Int32 value = 0;
493 
494 
495  FT_ASSERT( known_othersubr_result_cnt == 0 ||
496  unknown_othersubr_result_cnt == 0 );
497 
498 #ifdef FT_DEBUG_LEVEL_TRACE
499  if ( bol )
500  {
501  FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
502  bol = FALSE;
503  }
504 #endif
505 
506  /*********************************************************************/
507  /* */
508  /* Decode operator or operand */
509  /* */
510  /* */
511 
512  /* first of all, decompress operator or value */
513  switch ( *ip++ )
514  {
515  case 1:
516  op = op_hstem;
517  break;
518 
519  case 3:
520  op = op_vstem;
521  break;
522  case 4:
523  op = op_vmoveto;
524  break;
525  case 5:
526  op = op_rlineto;
527  break;
528  case 6:
529  op = op_hlineto;
530  break;
531  case 7:
532  op = op_vlineto;
533  break;
534  case 8:
535  op = op_rrcurveto;
536  break;
537  case 9:
538  op = op_closepath;
539  break;
540  case 10:
541  op = op_callsubr;
542  break;
543  case 11:
544  op = op_return;
545  break;
546 
547  case 13:
548  op = op_hsbw;
549  break;
550  case 14:
551  op = op_endchar;
552  break;
553 
554  case 15: /* undocumented, obsolete operator */
555  op = op_unknown15;
556  break;
557 
558  case 21:
559  op = op_rmoveto;
560  break;
561  case 22:
562  op = op_hmoveto;
563  break;
564 
565  case 30:
566  op = op_vhcurveto;
567  break;
568  case 31:
569  op = op_hvcurveto;
570  break;
571 
572  case 12:
573  if ( ip >= limit )
574  {
575  FT_ERROR(( "t1_decoder_parse_charstrings:"
576  " invalid escape (12+EOF)\n" ));
577  goto Syntax_Error;
578  }
579 
580  switch ( *ip++ )
581  {
582  case 0:
583  op = op_dotsection;
584  break;
585  case 1:
586  op = op_vstem3;
587  break;
588  case 2:
589  op = op_hstem3;
590  break;
591  case 6:
592  op = op_seac;
593  break;
594  case 7:
595  op = op_sbw;
596  break;
597  case 12:
598  op = op_div;
599  break;
600  case 16:
602  break;
603  case 17:
604  op = op_pop;
605  break;
606  case 33:
608  break;
609 
610  default:
611  FT_ERROR(( "t1_decoder_parse_charstrings:"
612  " invalid escape (12+%d)\n",
613  ip[-1] ));
614  goto Syntax_Error;
615  }
616  break;
617 
618  case 255: /* four bytes integer */
619  if ( ip + 4 > limit )
620  {
621  FT_ERROR(( "t1_decoder_parse_charstrings:"
622  " unexpected EOF in integer\n" ));
623  goto Syntax_Error;
624  }
625 
626  value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
627  ( (FT_UInt32)ip[1] << 16 ) |
628  ( (FT_UInt32)ip[2] << 8 ) |
629  (FT_UInt32)ip[3] );
630  ip += 4;
631 
632  /* According to the specification, values > 32000 or < -32000 must */
633  /* be followed by a `div' operator to make the result be in the */
634  /* range [-32000;32000]. We expect that the second argument of */
635  /* `div' is not a large number. Additionally, we don't handle */
636  /* stuff like `<large1> <large2> <num> div <num> div' or */
637  /* <large1> <large2> <num> div div'. This is probably not allowed */
638  /* anyway. */
639  if ( value > 32000 || value < -32000 )
640  {
641  if ( large_int )
642  {
643  FT_ERROR(( "t1_decoder_parse_charstrings:"
644  " no `div' after large integer\n" ));
645  }
646  else
647  large_int = TRUE;
648  }
649  else
650  {
651  if ( !large_int )
652  value = (FT_Int32)( (FT_UInt32)value << 16 );
653  }
654 
655  break;
656 
657  default:
658  if ( ip[-1] >= 32 )
659  {
660  if ( ip[-1] < 247 )
661  value = (FT_Int32)ip[-1] - 139;
662  else
663  {
664  if ( ++ip > limit )
665  {
666  FT_ERROR(( "t1_decoder_parse_charstrings:"
667  " unexpected EOF in integer\n" ));
668  goto Syntax_Error;
669  }
670 
671  if ( ip[-2] < 251 )
672  value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
673  else
674  value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
675  }
676 
677  if ( !large_int )
678  value = (FT_Int32)( (FT_UInt32)value << 16 );
679  }
680  else
681  {
682  FT_ERROR(( "t1_decoder_parse_charstrings:"
683  " invalid byte (%d)\n", ip[-1] ));
684  goto Syntax_Error;
685  }
686  }
687 
688  if ( unknown_othersubr_result_cnt > 0 )
689  {
690  switch ( op )
691  {
692  case op_callsubr:
693  case op_return:
694  case op_none:
695  case op_pop:
696  break;
697 
698  default:
699  /* all operands have been transferred by previous pops */
700  unknown_othersubr_result_cnt = 0;
701  break;
702  }
703  }
704 
705  if ( large_int && !( op == op_none || op == op_div ) )
706  {
707  FT_ERROR(( "t1_decoder_parse_charstrings:"
708  " no `div' after large integer\n" ));
709 
710  large_int = FALSE;
711  }
712 
713  /*********************************************************************/
714  /* */
715  /* Push value on stack, or process operator */
716  /* */
717  /* */
718  if ( op == op_none )
719  {
720  if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
721  {
722  FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
723  goto Syntax_Error;
724  }
725 
726 #ifdef FT_DEBUG_LEVEL_TRACE
727  if ( large_int )
728  FT_TRACE4(( " %d", value ));
729  else
730  FT_TRACE4(( " %d", value / 65536 ));
731 #endif
732 
733  *top++ = value;
734  decoder->top = top;
735  }
736  else if ( op == op_callothersubr ) /* callothersubr */
737  {
738  FT_Int subr_no;
739  FT_Int arg_cnt;
740 
741 
742 #ifdef FT_DEBUG_LEVEL_TRACE
743  FT_TRACE4(( " callothersubr\n" ));
744  bol = TRUE;
745 #endif
746 
747  if ( top - decoder->stack < 2 )
748  goto Stack_Underflow;
749 
750  top -= 2;
751 
752  subr_no = Fix2Int( top[1] );
753  arg_cnt = Fix2Int( top[0] );
754 
755  /***********************************************************/
756  /* */
757  /* remove all operands to callothersubr from the stack */
758  /* */
759  /* for handled othersubrs, where we know the number of */
760  /* arguments, we increase the stack by the value of */
761  /* known_othersubr_result_cnt */
762  /* */
763  /* for unhandled othersubrs the following pops adjust the */
764  /* stack pointer as necessary */
765 
766  if ( arg_cnt > top - decoder->stack )
767  goto Stack_Underflow;
768 
769  top -= arg_cnt;
770 
771  known_othersubr_result_cnt = 0;
772  unknown_othersubr_result_cnt = 0;
773 
774  /* XXX TODO: The checks to `arg_count == <whatever>' */
775  /* might not be correct; an othersubr expects a certain */
776  /* number of operands on the PostScript stack (as opposed */
777  /* to the T1 stack) but it doesn't have to put them there */
778  /* by itself; previous othersubrs might have left the */
779  /* operands there if they were not followed by an */
780  /* appropriate number of pops */
781  /* */
782  /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
783  /* accept a font that contains charstrings like */
784  /* */
785  /* 100 200 2 20 callothersubr */
786  /* 300 1 20 callothersubr pop */
787  /* */
788  /* Perhaps this is the reason why BuildCharArray exists. */
789 
790  switch ( subr_no )
791  {
792  case 0: /* end flex feature */
793  if ( arg_cnt != 3 )
794  goto Unexpected_OtherSubr;
795 
796  if ( !decoder->flex_state ||
797  decoder->num_flex_vectors != 7 )
798  {
799  FT_ERROR(( "t1_decoder_parse_charstrings:"
800  " unexpected flex end\n" ));
801  goto Syntax_Error;
802  }
803 
804  /* the two `results' are popped by the following setcurrentpoint */
805  top[0] = x;
806  top[1] = y;
807  known_othersubr_result_cnt = 2;
808  break;
809 
810  case 1: /* start flex feature */
811  if ( arg_cnt != 0 )
812  goto Unexpected_OtherSubr;
813 
814  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
815  FT_SET_ERROR( t1_builder_check_points( builder, 6 ) ) )
816  goto Fail;
817 
818  decoder->flex_state = 1;
819  decoder->num_flex_vectors = 0;
820  break;
821 
822  case 2: /* add flex vectors */
823  {
824  FT_Int idx;
825 
826 
827  if ( arg_cnt != 0 )
828  goto Unexpected_OtherSubr;
829 
830  if ( !decoder->flex_state )
831  {
832  FT_ERROR(( "t1_decoder_parse_charstrings:"
833  " missing flex start\n" ));
834  goto Syntax_Error;
835  }
836 
837  /* note that we should not add a point for index 0; */
838  /* this will move our current position to the flex */
839  /* point without adding any point to the outline */
840  idx = decoder->num_flex_vectors++;
841  if ( idx > 0 && idx < 7 )
842  {
843  /* in malformed fonts it is possible to have other */
844  /* opcodes in the middle of a flex (which don't */
845  /* increase `num_flex_vectors'); we thus have to */
846  /* check whether we can add a point */
847  if ( FT_SET_ERROR( t1_builder_check_points( builder, 1 ) ) )
848  goto Syntax_Error;
849 
850  t1_builder_add_point( builder,
851  x,
852  y,
853  (FT_Byte)( idx == 3 || idx == 6 ) );
854  }
855  }
856  break;
857 
858  case 3: /* change hints */
859  if ( arg_cnt != 1 )
860  goto Unexpected_OtherSubr;
861 
862  known_othersubr_result_cnt = 1;
863 
864  if ( hinter )
865  hinter->reset( hinter->hints,
866  (FT_UInt)builder->current->n_points );
867  break;
868 
869  case 12:
870  case 13:
871  /* counter control hints, clear stack */
872  top = decoder->stack;
873  break;
874 
875  case 14:
876  case 15:
877  case 16:
878  case 17:
879  case 18: /* multiple masters */
880  {
881  PS_Blend blend = decoder->blend;
882  FT_UInt num_points, nn, mm;
883  FT_Long* delta;
884  FT_Long* values;
885 
886 
887  if ( !blend )
888  {
889  FT_ERROR(( "t1_decoder_parse_charstrings:"
890  " unexpected multiple masters operator\n" ));
891  goto Syntax_Error;
892  }
893 
894  num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
895  if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
896  {
897  FT_ERROR(( "t1_decoder_parse_charstrings:"
898  " incorrect number of multiple masters arguments\n" ));
899  goto Syntax_Error;
900  }
901 
902  /* We want to compute */
903  /* */
904  /* a0*w0 + a1*w1 + ... + ak*wk */
905  /* */
906  /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */
907  /* */
908  /* However, given that w0 + w1 + ... + wk == 1, we can */
909  /* rewrite it easily as */
910  /* */
911  /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */
912  /* */
913  /* where k == num_designs-1. */
914  /* */
915  /* I guess that's why it's written in this `compact' */
916  /* form. */
917  /* */
918  delta = top + num_points;
919  values = top;
920  for ( nn = 0; nn < num_points; nn++ )
921  {
922  FT_Long tmp = values[0];
923 
924 
925  for ( mm = 1; mm < blend->num_designs; mm++ )
926  tmp = ADD_LONG( tmp,
927  FT_MulFix( *delta++,
928  blend->weight_vector[mm] ) );
929 
930  *values++ = tmp;
931  }
932 
933  known_othersubr_result_cnt = (FT_Int)num_points;
934  break;
935  }
936 
937  case 19:
938  /* <idx> 1 19 callothersubr */
939  /* => replace elements starting from index cvi( <idx> ) */
940  /* of BuildCharArray with WeightVector */
941  {
942  FT_Int idx;
943  PS_Blend blend = decoder->blend;
944 
945 
946  if ( arg_cnt != 1 || !blend )
947  goto Unexpected_OtherSubr;
948 
949  idx = Fix2Int( top[0] );
950 
951  if ( idx < 0 ||
952  (FT_UInt)idx + blend->num_designs > decoder->len_buildchar )
953  goto Unexpected_OtherSubr;
954 
955  ft_memcpy( &decoder->buildchar[idx],
956  blend->weight_vector,
957  blend->num_designs *
958  sizeof ( blend->weight_vector[0] ) );
959  }
960  break;
961 
962  case 20:
963  /* <arg1> <arg2> 2 20 callothersubr pop */
964  /* ==> push <arg1> + <arg2> onto T1 stack */
965  if ( arg_cnt != 2 )
966  goto Unexpected_OtherSubr;
967 
968  top[0] = ADD_LONG( top[0], top[1] );
969 
970  known_othersubr_result_cnt = 1;
971  break;
972 
973  case 21:
974  /* <arg1> <arg2> 2 21 callothersubr pop */
975  /* ==> push <arg1> - <arg2> onto T1 stack */
976  if ( arg_cnt != 2 )
977  goto Unexpected_OtherSubr;
978 
979  top[0] = SUB_LONG( top[0], top[1] );
980 
981  known_othersubr_result_cnt = 1;
982  break;
983 
984  case 22:
985  /* <arg1> <arg2> 2 22 callothersubr pop */
986  /* ==> push <arg1> * <arg2> onto T1 stack */
987  if ( arg_cnt != 2 )
988  goto Unexpected_OtherSubr;
989 
990  top[0] = FT_MulFix( top[0], top[1] );
991 
992  known_othersubr_result_cnt = 1;
993  break;
994 
995  case 23:
996  /* <arg1> <arg2> 2 23 callothersubr pop */
997  /* ==> push <arg1> / <arg2> onto T1 stack */
998  if ( arg_cnt != 2 || top[1] == 0 )
999  goto Unexpected_OtherSubr;
1000 
1001  top[0] = FT_DivFix( top[0], top[1] );
1002 
1003  known_othersubr_result_cnt = 1;
1004  break;
1005 
1006  case 24:
1007  /* <val> <idx> 2 24 callothersubr */
1008  /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
1009  {
1010  FT_Int idx;
1011  PS_Blend blend = decoder->blend;
1012 
1013 
1014  if ( arg_cnt != 2 || !blend )
1015  goto Unexpected_OtherSubr;
1016 
1017  idx = Fix2Int( top[1] );
1018 
1019  if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1020  goto Unexpected_OtherSubr;
1021 
1022  decoder->buildchar[idx] = top[0];
1023  }
1024  break;
1025 
1026  case 25:
1027  /* <idx> 1 25 callothersubr pop */
1028  /* ==> push BuildCharArray[cvi( idx )] */
1029  /* onto T1 stack */
1030  {
1031  FT_Int idx;
1032  PS_Blend blend = decoder->blend;
1033 
1034 
1035  if ( arg_cnt != 1 || !blend )
1036  goto Unexpected_OtherSubr;
1037 
1038  idx = Fix2Int( top[0] );
1039 
1040  if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
1041  goto Unexpected_OtherSubr;
1042 
1043  top[0] = decoder->buildchar[idx];
1044  }
1045 
1046  known_othersubr_result_cnt = 1;
1047  break;
1048 
1049 #if 0
1050  case 26:
1051  /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
1052  /* leave mark on T1 stack */
1053  /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
1054  XXX which routine has left its mark on the (PostScript) stack?;
1055  break;
1056 #endif
1057 
1058  case 27:
1059  /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
1060  /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
1061  /* otherwise push <res2> */
1062  if ( arg_cnt != 4 )
1063  goto Unexpected_OtherSubr;
1064 
1065  if ( top[2] > top[3] )
1066  top[0] = top[1];
1067 
1068  known_othersubr_result_cnt = 1;
1069  break;
1070 
1071  case 28:
1072  /* 0 28 callothersubr pop */
1073  /* => push random value from interval [0, 1) onto stack */
1074  if ( arg_cnt != 0 )
1075  goto Unexpected_OtherSubr;
1076 
1077  {
1078  FT_Fixed Rand;
1079 
1080 
1081  Rand = seed;
1082  if ( Rand >= 0x8000L )
1083  Rand++;
1084 
1085  top[0] = Rand;
1086 
1087  seed = FT_MulFix( seed, 0x10000L - seed );
1088  if ( seed == 0 )
1089  seed += 0x2873;
1090  }
1091 
1092  known_othersubr_result_cnt = 1;
1093  break;
1094 
1095  default:
1096  if ( arg_cnt >= 0 && subr_no >= 0 )
1097  {
1098  FT_ERROR(( "t1_decoder_parse_charstrings:"
1099  " unknown othersubr [%d %d], wish me luck\n",
1100  arg_cnt, subr_no ));
1101  unknown_othersubr_result_cnt = arg_cnt;
1102  break;
1103  }
1104  /* fall through */
1105 
1106  Unexpected_OtherSubr:
1107  FT_ERROR(( "t1_decoder_parse_charstrings:"
1108  " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
1109  goto Syntax_Error;
1110  }
1111 
1112  top += known_othersubr_result_cnt;
1113 
1114  decoder->top = top;
1115  }
1116  else /* general operator */
1117  {
1118  FT_Int num_args = t1_args_count[op];
1119 
1120 
1121  FT_ASSERT( num_args >= 0 );
1122 
1123  if ( top - decoder->stack < num_args )
1124  goto Stack_Underflow;
1125 
1126  /* XXX Operators usually take their operands from the */
1127  /* bottom of the stack, i.e., the operands are */
1128  /* decoder->stack[0], ..., decoder->stack[num_args - 1]; */
1129  /* only div, callsubr, and callothersubr are different. */
1130  /* In practice it doesn't matter (?). */
1131 
1132 #ifdef FT_DEBUG_LEVEL_TRACE
1133 
1134  switch ( op )
1135  {
1136  case op_callsubr:
1137  case op_div:
1138  case op_callothersubr:
1139  case op_pop:
1140  case op_return:
1141  break;
1142 
1143  default:
1144  if ( top - decoder->stack != num_args )
1145  FT_TRACE0(( "t1_decoder_parse_charstrings:"
1146  " too much operands on the stack"
1147  " (seen %d, expected %d)\n",
1148  top - decoder->stack, num_args ));
1149  break;
1150  }
1151 
1152 #endif /* FT_DEBUG_LEVEL_TRACE */
1153 
1154  top -= num_args;
1155 
1156  switch ( op )
1157  {
1158  case op_endchar:
1159  FT_TRACE4(( " endchar\n" ));
1160 
1161  t1_builder_close_contour( builder );
1162 
1163  /* close hints recording session */
1164  if ( hinter )
1165  {
1166  if ( hinter->close( hinter->hints,
1167  (FT_UInt)builder->current->n_points ) )
1168  goto Syntax_Error;
1169 
1170  /* apply hints to the loaded glyph outline now */
1171  error = hinter->apply( hinter->hints,
1172  builder->current,
1173  (PSH_Globals)builder->hints_globals,
1174  decoder->hint_mode );
1175  if ( error )
1176  goto Fail;
1177  }
1178 
1179  /* add current outline to the glyph slot */
1180  FT_GlyphLoader_Add( builder->loader );
1181 
1182  /* the compiler should optimize away this empty loop but ... */
1183 
1184 #ifdef FT_DEBUG_LEVEL_TRACE
1185 
1186  if ( decoder->len_buildchar > 0 )
1187  {
1188  FT_UInt i;
1189 
1190 
1191  FT_TRACE4(( "BuildCharArray = [ " ));
1192 
1193  for ( i = 0; i < decoder->len_buildchar; i++ )
1194  FT_TRACE4(( "%d ", decoder->buildchar[i] ));
1195 
1196  FT_TRACE4(( "]\n" ));
1197  }
1198 
1199 #endif /* FT_DEBUG_LEVEL_TRACE */
1200 
1201  FT_TRACE4(( "\n" ));
1202 
1203  /* return now! */
1204  return FT_Err_Ok;
1205 
1206  case op_hsbw:
1207  FT_TRACE4(( " hsbw" ));
1208 
1209  builder->parse_state = T1_Parse_Have_Width;
1210 
1211  builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1212  top[0] );
1213 
1214  builder->advance.x = top[1];
1215  builder->advance.y = 0;
1216 
1217  orig_x = x = ADD_LONG( builder->pos_x, top[0] );
1218  orig_y = y = builder->pos_y;
1219 
1220  FT_UNUSED( orig_y );
1221 
1222  /* the `metrics_only' indicates that we only want to compute */
1223  /* the glyph's metrics (lsb + advance width), not load the */
1224  /* rest of it; so exit immediately */
1225  if ( builder->metrics_only )
1226  return FT_Err_Ok;
1227 
1228  break;
1229 
1230  case op_seac:
1231  return t1operator_seac( decoder,
1232  top[0],
1233  top[1],
1234  top[2],
1235  Fix2Int( top[3] ),
1236  Fix2Int( top[4] ) );
1237 
1238  case op_sbw:
1239  FT_TRACE4(( " sbw" ));
1240 
1241  builder->parse_state = T1_Parse_Have_Width;
1242 
1243  builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1244  top[0] );
1245  builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1246  top[1] );
1247 
1248  builder->advance.x = top[2];
1249  builder->advance.y = top[3];
1250 
1251  x = ADD_LONG( builder->pos_x, top[0] );
1252  y = ADD_LONG( builder->pos_y, top[1] );
1253 
1254  /* the `metrics_only' indicates that we only want to compute */
1255  /* the glyph's metrics (lsb + advance width), not load the */
1256  /* rest of it; so exit immediately */
1257  if ( builder->metrics_only )
1258  return FT_Err_Ok;
1259 
1260  break;
1261 
1262  case op_closepath:
1263  FT_TRACE4(( " closepath" ));
1264 
1265  /* if there is no path, `closepath' is a no-op */
1266  if ( builder->parse_state == T1_Parse_Have_Path ||
1267  builder->parse_state == T1_Parse_Have_Moveto )
1268  t1_builder_close_contour( builder );
1269 
1270  builder->parse_state = T1_Parse_Have_Width;
1271  break;
1272 
1273  case op_hlineto:
1274  FT_TRACE4(( " hlineto" ));
1275 
1276  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1277  goto Fail;
1278 
1279  x = ADD_LONG( x, top[0] );
1280  goto Add_Line;
1281 
1282  case op_hmoveto:
1283  FT_TRACE4(( " hmoveto" ));
1284 
1285  x = ADD_LONG( x, top[0] );
1286 
1287  if ( !decoder->flex_state )
1288  {
1289  if ( builder->parse_state == T1_Parse_Start )
1290  goto Syntax_Error;
1291  builder->parse_state = T1_Parse_Have_Moveto;
1292  }
1293  break;
1294 
1295  case op_hvcurveto:
1296  FT_TRACE4(( " hvcurveto" ));
1297 
1298  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1299  FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
1300  goto Fail;
1301 
1302  x = ADD_LONG( x, top[0] );
1303  t1_builder_add_point( builder, x, y, 0 );
1304 
1305  x = ADD_LONG( x, top[1] );
1306  y = ADD_LONG( y, top[2] );
1307  t1_builder_add_point( builder, x, y, 0 );
1308 
1309  y = ADD_LONG( y, top[3] );
1310  t1_builder_add_point( builder, x, y, 1 );
1311  break;
1312 
1313  case op_rlineto:
1314  FT_TRACE4(( " rlineto" ));
1315 
1316  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1317  goto Fail;
1318 
1319  x = ADD_LONG( x, top[0] );
1320  y = ADD_LONG( y, top[1] );
1321 
1322  Add_Line:
1323  if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
1324  goto Fail;
1325  break;
1326 
1327  case op_rmoveto:
1328  FT_TRACE4(( " rmoveto" ));
1329 
1330  x = ADD_LONG( x, top[0] );
1331  y = ADD_LONG( y, top[1] );
1332 
1333  if ( !decoder->flex_state )
1334  {
1335  if ( builder->parse_state == T1_Parse_Start )
1336  goto Syntax_Error;
1337  builder->parse_state = T1_Parse_Have_Moveto;
1338  }
1339  break;
1340 
1341  case op_rrcurveto:
1342  FT_TRACE4(( " rrcurveto" ));
1343 
1344  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1345  FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
1346  goto Fail;
1347 
1348  x = ADD_LONG( x, top[0] );
1349  y = ADD_LONG( y, top[1] );
1350  t1_builder_add_point( builder, x, y, 0 );
1351 
1352  x = ADD_LONG( x, top[2] );
1353  y = ADD_LONG( y, top[3] );
1354  t1_builder_add_point( builder, x, y, 0 );
1355 
1356  x = ADD_LONG( x, top[4] );
1357  y = ADD_LONG( y, top[5] );
1358  t1_builder_add_point( builder, x, y, 1 );
1359  break;
1360 
1361  case op_vhcurveto:
1362  FT_TRACE4(( " vhcurveto" ));
1363 
1364  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
1365  FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) )
1366  goto Fail;
1367 
1368  y = ADD_LONG( y, top[0] );
1369  t1_builder_add_point( builder, x, y, 0 );
1370 
1371  x = ADD_LONG( x, top[1] );
1372  y = ADD_LONG( y, top[2] );
1373  t1_builder_add_point( builder, x, y, 0 );
1374 
1375  x = ADD_LONG( x, top[3] );
1376  t1_builder_add_point( builder, x, y, 1 );
1377  break;
1378 
1379  case op_vlineto:
1380  FT_TRACE4(( " vlineto" ));
1381 
1382  if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1383  goto Fail;
1384 
1385  y = ADD_LONG( y, top[0] );
1386  goto Add_Line;
1387 
1388  case op_vmoveto:
1389  FT_TRACE4(( " vmoveto" ));
1390 
1391  y = ADD_LONG( y, top[0] );
1392 
1393  if ( !decoder->flex_state )
1394  {
1395  if ( builder->parse_state == T1_Parse_Start )
1396  goto Syntax_Error;
1397  builder->parse_state = T1_Parse_Have_Moveto;
1398  }
1399  break;
1400 
1401  case op_div:
1402  FT_TRACE4(( " div" ));
1403 
1404  /* if `large_int' is set, we divide unscaled numbers; */
1405  /* otherwise, we divide numbers in 16.16 format -- */
1406  /* in both cases, it is the same operation */
1407  *top = FT_DivFix( top[0], top[1] );
1408  top++;
1409 
1410  large_int = FALSE;
1411  break;
1412 
1413  case op_callsubr:
1414  {
1415  FT_Int idx;
1416 
1417 
1418  FT_TRACE4(( " callsubr" ));
1419 
1420  idx = Fix2Int( top[0] );
1421 
1422  if ( decoder->subrs_hash )
1423  {
1424  size_t* val = ft_hash_num_lookup( idx,
1425  decoder->subrs_hash );
1426 
1427 
1428  if ( val )
1429  idx = *val;
1430  else
1431  idx = -1;
1432  }
1433 
1434  if ( idx < 0 || idx >= decoder->num_subrs )
1435  {
1436  FT_ERROR(( "t1_decoder_parse_charstrings:"
1437  " invalid subrs index\n" ));
1438  goto Syntax_Error;
1439  }
1440 
1441  if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
1442  {
1443  FT_ERROR(( "t1_decoder_parse_charstrings:"
1444  " too many nested subrs\n" ));
1445  goto Syntax_Error;
1446  }
1447 
1448  zone->cursor = ip; /* save current instruction pointer */
1449 
1450  zone++;
1451 
1452  /* The Type 1 driver stores subroutines without the seed bytes. */
1453  /* The CID driver stores subroutines with seed bytes. This */
1454  /* case is taken care of when decoder->subrs_len == 0. */
1455  zone->base = decoder->subrs[idx];
1456 
1457  if ( decoder->subrs_len )
1458  zone->limit = zone->base + decoder->subrs_len[idx];
1459  else
1460  {
1461  /* We are using subroutines from a CID font. We must adjust */
1462  /* for the seed bytes. */
1463  zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
1464  zone->limit = decoder->subrs[idx + 1];
1465  }
1466 
1467  zone->cursor = zone->base;
1468 
1469  if ( !zone->base )
1470  {
1471  FT_ERROR(( "t1_decoder_parse_charstrings:"
1472  " invoking empty subrs\n" ));
1473  goto Syntax_Error;
1474  }
1475 
1476  decoder->zone = zone;
1477  ip = zone->base;
1478  limit = zone->limit;
1479  break;
1480  }
1481 
1482  case op_pop:
1483  FT_TRACE4(( " pop" ));
1484 
1485  if ( known_othersubr_result_cnt > 0 )
1486  {
1487  known_othersubr_result_cnt--;
1488  /* ignore, we pushed the operands ourselves */
1489  break;
1490  }
1491 
1492  if ( unknown_othersubr_result_cnt == 0 )
1493  {
1494  FT_ERROR(( "t1_decoder_parse_charstrings:"
1495  " no more operands for othersubr\n" ));
1496  goto Syntax_Error;
1497  }
1498 
1499  unknown_othersubr_result_cnt--;
1500  top++; /* `push' the operand to callothersubr onto the stack */
1501  break;
1502 
1503  case op_return:
1504  FT_TRACE4(( " return" ));
1505 
1506  if ( zone <= decoder->zones )
1507  {
1508  FT_ERROR(( "t1_decoder_parse_charstrings:"
1509  " unexpected return\n" ));
1510  goto Syntax_Error;
1511  }
1512 
1513  zone--;
1514  ip = zone->cursor;
1515  limit = zone->limit;
1516  decoder->zone = zone;
1517  break;
1518 
1519  case op_dotsection:
1520  FT_TRACE4(( " dotsection" ));
1521 
1522  break;
1523 
1524  case op_hstem:
1525  FT_TRACE4(( " hstem" ));
1526 
1527  /* record horizontal hint */
1528  if ( hinter )
1529  {
1530  /* top[0] += builder->left_bearing.y; */
1531  hinter->stem( hinter->hints, 1, top );
1532  }
1533  break;
1534 
1535  case op_hstem3:
1536  FT_TRACE4(( " hstem3" ));
1537 
1538  /* record horizontal counter-controlled hints */
1539  if ( hinter )
1540  hinter->stem3( hinter->hints, 1, top );
1541  break;
1542 
1543  case op_vstem:
1544  FT_TRACE4(( " vstem" ));
1545 
1546  /* record vertical hint */
1547  if ( hinter )
1548  {
1549  top[0] = ADD_LONG( top[0], orig_x );
1550  hinter->stem( hinter->hints, 0, top );
1551  }
1552  break;
1553 
1554  case op_vstem3:
1555  FT_TRACE4(( " vstem3" ));
1556 
1557  /* record vertical counter-controlled hints */
1558  if ( hinter )
1559  {
1560  FT_Pos dx = orig_x;
1561 
1562 
1563  top[0] = ADD_LONG( top[0], dx );
1564  top[2] = ADD_LONG( top[2], dx );
1565  top[4] = ADD_LONG( top[4], dx );
1566  hinter->stem3( hinter->hints, 0, top );
1567  }
1568  break;
1569 
1570  case op_setcurrentpoint:
1571  FT_TRACE4(( " setcurrentpoint" ));
1572 
1573  /* From the T1 specification, section 6.4: */
1574  /* */
1575  /* The setcurrentpoint command is used only in */
1576  /* conjunction with results from OtherSubrs procedures. */
1577 
1578  /* known_othersubr_result_cnt != 0 is already handled */
1579  /* above. */
1580 
1581  /* Note, however, that both Ghostscript and Adobe */
1582  /* Distiller handle this situation by silently ignoring */
1583  /* the inappropriate `setcurrentpoint' instruction. So */
1584  /* we do the same. */
1585 #if 0
1586 
1587  if ( decoder->flex_state != 1 )
1588  {
1589  FT_ERROR(( "t1_decoder_parse_charstrings:"
1590  " unexpected `setcurrentpoint'\n" ));
1591  goto Syntax_Error;
1592  }
1593  else
1594  ...
1595 #endif
1596 
1597  x = top[0];
1598  y = top[1];
1599  decoder->flex_state = 0;
1600  break;
1601 
1602  case op_unknown15:
1603  FT_TRACE4(( " opcode_15" ));
1604  /* nothing to do except to pop the two arguments */
1605  break;
1606 
1607  default:
1608  FT_ERROR(( "t1_decoder_parse_charstrings:"
1609  " unhandled opcode %d\n", op ));
1610  goto Syntax_Error;
1611  }
1612 
1613  /* XXX Operators usually clear the operand stack; */
1614  /* only div, callsubr, callothersubr, pop, and */
1615  /* return are different. */
1616  /* In practice it doesn't matter (?). */
1617 
1618  decoder->top = top;
1619 
1620 #ifdef FT_DEBUG_LEVEL_TRACE
1621  FT_TRACE4(( "\n" ));
1622  bol = TRUE;
1623 #endif
1624 
1625  } /* general operator processing */
1626 
1627  } /* while ip < limit */
1628 
1629  FT_TRACE4(( "..end..\n\n" ));
1630 
1631  Fail:
1632  return error;
1633 
1634  Syntax_Error:
1635  return FT_THROW( Syntax_Error );
1636 
1637  Stack_Underflow:
1638  return FT_THROW( Stack_Underflow );
1639  }
1640 
1641 #else /* T1_CONFIG_OPTION_OLD_ENGINE */
1642 
1643  /*************************************************************************/
1644  /* */
1645  /* <Function> */
1646  /* t1_decoder_parse_metrics */
1647  /* */
1648  /* <Description> */
1649  /* Parses a given Type 1 charstrings program to extract width */
1650  /* */
1651  /* <Input> */
1652  /* decoder :: The current Type 1 decoder. */
1653  /* */
1654  /* charstring_base :: The base address of the charstring stream. */
1655  /* */
1656  /* charstring_len :: The length in bytes of the charstring stream. */
1657  /* */
1658  /* <Return> */
1659  /* FreeType error code. 0 means success. */
1660  /* */
1663  FT_Byte* charstring_base,
1664  FT_UInt charstring_len )
1665  {
1667  FT_Byte* ip;
1668  FT_Byte* limit;
1669  T1_Builder builder = &decoder->builder;
1670 
1671 #ifdef FT_DEBUG_LEVEL_TRACE
1672  FT_Bool bol = TRUE;
1673 #endif
1674 
1675 
1676  /* First of all, initialize the decoder */
1677  decoder->top = decoder->stack;
1678  decoder->zone = decoder->zones;
1679  zone = decoder->zones;
1680 
1681  builder->parse_state = T1_Parse_Start;
1682 
1683  FT_TRACE4(( "\n"
1684  "Start charstring: get width\n" ));
1685 
1686  zone->base = charstring_base;
1687  limit = zone->limit = charstring_base + charstring_len;
1688  ip = zone->cursor = zone->base;
1689 
1690  /* now, execute loop */
1691  while ( ip < limit )
1692  {
1693  FT_Long* top = decoder->top;
1695  FT_Int32 value = 0;
1696 
1697 
1698 #ifdef FT_DEBUG_LEVEL_TRACE
1699  if ( bol )
1700  {
1701  FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
1702  bol = FALSE;
1703  }
1704 #endif
1705 
1706  /*********************************************************************/
1707  /* */
1708  /* Decode operator or operand */
1709  /* */
1710  /* */
1711 
1712  /* first of all, decompress operator or value */
1713  switch ( *ip++ )
1714  {
1715  case 1:
1716  case 3:
1717  case 4:
1718  case 5:
1719  case 6:
1720  case 7:
1721  case 8:
1722  case 9:
1723  case 10:
1724  case 11:
1725  case 14:
1726  case 15:
1727  case 21:
1728  case 22:
1729  case 30:
1730  case 31:
1731  goto No_Width;
1732 
1733  case 13:
1734  op = op_hsbw;
1735  break;
1736 
1737  case 12:
1738  if ( ip >= limit )
1739  {
1740  FT_ERROR(( "t1_decoder_parse_metrics:"
1741  " invalid escape (12+EOF)\n" ));
1742  goto Syntax_Error;
1743  }
1744 
1745  switch ( *ip++ )
1746  {
1747  case 7:
1748  op = op_sbw;
1749  break;
1750 
1751  default:
1752  goto No_Width;
1753  }
1754  break;
1755 
1756  case 255: /* four bytes integer */
1757  if ( ip + 4 > limit )
1758  {
1759  FT_ERROR(( "t1_decoder_parse_metrics:"
1760  " unexpected EOF in integer\n" ));
1761  goto Syntax_Error;
1762  }
1763 
1764  value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
1765  ( (FT_UInt32)ip[1] << 16 ) |
1766  ( (FT_UInt32)ip[2] << 8 ) |
1767  (FT_UInt32)ip[3] );
1768  ip += 4;
1769 
1770  /* According to the specification, values > 32000 or < -32000 must */
1771  /* be followed by a `div' operator to make the result be in the */
1772  /* range [-32000;32000]. We expect that the second argument of */
1773  /* `div' is not a large number. Additionally, we don't handle */
1774  /* stuff like `<large1> <large2> <num> div <num> div' or */
1775  /* <large1> <large2> <num> div div'. This is probably not allowed */
1776  /* anyway. */
1777  if ( value > 32000 || value < -32000 )
1778  {
1779  FT_ERROR(( "t1_decoder_parse_metrics:"
1780  " large integer found for width\n" ));
1781  goto Syntax_Error;
1782  }
1783  else
1784  {
1785  value = (FT_Int32)( (FT_UInt32)value << 16 );
1786  }
1787 
1788  break;
1789 
1790  default:
1791  if ( ip[-1] >= 32 )
1792  {
1793  if ( ip[-1] < 247 )
1794  value = (FT_Int32)ip[-1] - 139;
1795  else
1796  {
1797  if ( ++ip > limit )
1798  {
1799  FT_ERROR(( "t1_decoder_parse_metrics:"
1800  " unexpected EOF in integer\n" ));
1801  goto Syntax_Error;
1802  }
1803 
1804  if ( ip[-2] < 251 )
1805  value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
1806  else
1807  value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
1808  }
1809 
1810  value = (FT_Int32)( (FT_UInt32)value << 16 );
1811  }
1812  else
1813  {
1814  FT_ERROR(( "t1_decoder_parse_metrics:"
1815  " invalid byte (%d)\n", ip[-1] ));
1816  goto Syntax_Error;
1817  }
1818  }
1819 
1820  /*********************************************************************/
1821  /* */
1822  /* Push value on stack, or process operator */
1823  /* */
1824  /* */
1825  if ( op == op_none )
1826  {
1827  if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
1828  {
1829  FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
1830  goto Syntax_Error;
1831  }
1832 
1833 #ifdef FT_DEBUG_LEVEL_TRACE
1834  FT_TRACE4(( " %d", value / 65536 ));
1835 #endif
1836 
1837  *top++ = value;
1838  decoder->top = top;
1839  }
1840  else /* general operator */
1841  {
1842  FT_Int num_args = t1_args_count[op];
1843 
1844 
1845  FT_ASSERT( num_args >= 0 );
1846 
1847  if ( top - decoder->stack < num_args )
1848  goto Stack_Underflow;
1849 
1850 #ifdef FT_DEBUG_LEVEL_TRACE
1851 
1852  if ( top - decoder->stack != num_args )
1853  FT_TRACE0(( "t1_decoder_parse_metrics:"
1854  " too much operands on the stack"
1855  " (seen %d, expected %d)\n",
1856  top - decoder->stack, num_args ));
1857 
1858 #endif /* FT_DEBUG_LEVEL_TRACE */
1859 
1860  top -= num_args;
1861 
1862  switch ( op )
1863  {
1864  case op_hsbw:
1865  FT_TRACE4(( " hsbw" ));
1866 
1867  builder->parse_state = T1_Parse_Have_Width;
1868 
1869  builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1870  top[0] );
1871 
1872  builder->advance.x = top[1];
1873  builder->advance.y = 0;
1874 
1875  /* we only want to compute the glyph's metrics */
1876  /* (lsb + advance width), not load the rest of */
1877  /* it; so exit immediately */
1878  return FT_Err_Ok;
1879 
1880  case op_sbw:
1881  FT_TRACE4(( " sbw" ));
1882 
1883  builder->parse_state = T1_Parse_Have_Width;
1884 
1885  builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1886  top[0] );
1887  builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1888  top[1] );
1889 
1890  builder->advance.x = top[2];
1891  builder->advance.y = top[3];
1892 
1893  /* we only want to compute the glyph's metrics */
1894  /* (lsb + advance width), not load the rest of */
1895  /* it; so exit immediately */
1896  return FT_Err_Ok;
1897 
1898  default:
1899  FT_ERROR(( "t1_decoder_parse_metrics:"
1900  " unhandled opcode %d\n", op ));
1901  goto Syntax_Error;
1902  }
1903 
1904  } /* general operator processing */
1905 
1906  } /* while ip < limit */
1907 
1908  FT_TRACE4(( "..end..\n\n" ));
1909 
1910  No_Width:
1911  FT_ERROR(( "t1_decoder_parse_metrics:"
1912  " no width, found op %d instead\n",
1913  ip[-1] ));
1914  Syntax_Error:
1915  return FT_THROW( Syntax_Error );
1916 
1917  Stack_Underflow:
1918  return FT_THROW( Stack_Underflow );
1919  }
1920 #endif /* T1_CONFIG_OPTION_OLD_ENGINE */
1921 
1922 
1923  /* initialize T1 decoder */
1926  FT_Face face,
1927  FT_Size size,
1929  FT_Byte** glyph_names,
1930  PS_Blend blend,
1931  FT_Bool hinting,
1932  FT_Render_Mode hint_mode,
1933  T1_Decoder_Callback parse_callback )
1934  {
1935  FT_ZERO( decoder );
1936 
1937  /* retrieve PSNames interface from list of current modules */
1938  {
1939  FT_Service_PsCMaps psnames;
1940 
1941 
1942  FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1943  if ( !psnames )
1944  {
1945  FT_ERROR(( "t1_decoder_init:"
1946  " the `psnames' module is not available\n" ));
1947  return FT_THROW( Unimplemented_Feature );
1948  }
1949 
1950  decoder->psnames = psnames;
1951  }
1952 
1953  t1_builder_init( &decoder->builder, face, size, slot, hinting );
1954 
1955  /* decoder->buildchar and decoder->len_buildchar have to be */
1956  /* initialized by the caller since we cannot know the length */
1957  /* of the BuildCharArray */
1958 
1959  decoder->num_glyphs = (FT_UInt)face->num_glyphs;
1960  decoder->glyph_names = glyph_names;
1961  decoder->hint_mode = hint_mode;
1962  decoder->blend = blend;
1963  decoder->parse_callback = parse_callback;
1964 
1965  decoder->funcs = t1_decoder_funcs;
1966 
1967  return FT_Err_Ok;
1968  }
1969 
1970 
1971  /* finalize T1 decoder */
1972  FT_LOCAL_DEF( void )
1974  {
1975  FT_Memory memory = decoder->builder.memory;
1976 
1977 
1978  t1_builder_done( &decoder->builder );
1979 
1980  if ( decoder->cf2_instance.finalizer )
1981  {
1982  decoder->cf2_instance.finalizer( decoder->cf2_instance.data );
1983  FT_FREE( decoder->cf2_instance.data );
1984  }
1985  }
1986 
1987 
1988 /* END */
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid glyph index unsupported glyph image format invalid outline too many hints invalid object handle invalid module handle invalid size handle invalid charmap handle invalid stream handle too many extensions unlisted object invalid stream seek invalid stream read invalid frame operation invalid frame read raster corrupted negative height while rastering invalid opcode stack overflow bad argument invalid reference found ENDF opcode in execution stream invalid code range too many function definitions SFNT font table missing name table missing horizontal PostScript(post) table missing" ) FT_ERRORDEF_( Invalid_Horiz_Metrics
#define FIXED_TO_INT(x)
Definition: ftcalc.h:406
t1_decoder_parse_metrics(T1_Decoder decoder, FT_Byte *charstring_base, FT_UInt charstring_len)
Definition: t1decode.c:1662
FT_UInt num_designs
Definition: t1tables.h:300
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
signed long FT_Long
Definition: fttypes.h:242
#define TRUE
Definition: types.h:120
FT_Vector advance
Definition: psaux.h:793
struct T1_FaceRec_ * T1_Face
Definition: t1types.h:196
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
FT_Byte ** glyph_names
Definition: psaux.h:905
FT_Int lenIV
Definition: psaux.h:907
t1_builder_done(T1_Builder builder)
Definition: psobjs.c:1589
t1_builder_add_point1(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1634
FT_UInt * subrs_len
Definition: psaux.h:910
#define error(str)
Definition: mkdosfs.c:1605
FT_Fixed * weight_vector
Definition: t1tables.h:307
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3923
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3928
FT_Outline * base
Definition: psaux.h:786
FT_Pos x
Definition: ftimage.h:76
#define FT_ARRAY_ZERO(dest, count)
Definition: ftmemory.h:240
signed int FT_Int
Definition: fttypes.h:220
t1_lookup_glyph_by_stdcharcode_ps(PS_Decoder *decoder, FT_Int charcode)
Definition: t1decode.c:131
static GLenum which
Definition: wgl_font.c:159
FT_GlyphSlot glyph
Definition: psaux.h:784
#define FT_ULONG_MAX
Definition: ftstdlib.h:68
enum FT_Render_Mode_ FT_Render_Mode
FT_Long * top
Definition: psaux.h:898
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
T1_Hints_OpenFunc open
Definition: pshints.h:345
t1_builder_start_point(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1686
FT_Bool metrics_only
Definition: psaux.h:800
GLdouble n
Definition: glext.h:7729
FT_Service_PsCMaps psnames
Definition: psaux.h:903
FT_Error(* T1_Decoder_Callback)(T1_Decoder decoder, FT_UInt glyph_index)
Definition: psaux.h:852
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
PS_Blend blend
Definition: psaux.h:920
size_t * ft_hash_num_lookup(FT_Int num, FT_Hash hash)
Definition: fthash.c:327
T1_Hints_ResetFunc reset
Definition: pshints.h:349
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:125
FT_Int num_flex_vectors
Definition: psaux.h:917
return FT_Err_Ok
Definition: ftbbox.c:511
static char memory[1024 *256]
Definition: process.c:116
#define Fix2Int(f)
Definition: t1decode.c:32
enum T1_Operator_ T1_Operator
GLint limit
Definition: glext.h:10326
T1_Decoder_Callback parse_callback
Definition: psaux.h:924
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
FT_Bool no_recurse
Definition: psaux.h:798
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
t1_decoder_init(T1_Decoder decoder, FT_Face face, FT_Size size, FT_GlyphSlot slot, FT_Byte **glyph_names, PS_Blend blend, FT_Bool hinting, FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback)
Definition: t1decode.c:1925
#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
T1_Decoder_Zone zone
Definition: psaux.h:901
FT_GlyphLoader loader
Definition: ftobjs.h:467
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
static const FT_Int t1_args_count[op_max]
Definition: t1decode.c:80
int ip[4]
Definition: rtl.c:1176
unsigned int idx
Definition: utils.c:41
#define T1_MAX_SUBRS_CALLS
Definition: ftoption.h:715
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]
Definition: psaux.h:897
FT_Int flex_state
Definition: psaux.h:916
smooth NULL
Definition: ftsmooth.c:416
const struct T1_Hints_FuncsRec_ * T1_Hints_Funcs
Definition: pshints.h:117
#define T1_MAX_CHARSTRINGS_OPERANDS
Definition: ftoption.h:725
#define FT_FREE(ptr)
Definition: ftmemory.h:329
T1_ParseState parse_state
Definition: psaux.h:796
FT_CALLBACK_TABLE_DEF const T1_Decoder_FuncsRec t1_decoder_funcs
Definition: psauxmod.c:88
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
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
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
FT_Long * buildchar
Definition: psaux.h:927
char FT_String
Definition: fttypes.h:187
GLsizeiptr size
Definition: glext.h:5919
#define FT_ZERO(p)
Definition: ftmemory.h:237
Definition: dhcpd.h:61
if(!(yy_init))
Definition: macro.lex.yy.c:714
FT_Face face
Definition: psaux.h:783
static void Exit(void)
Definition: sock.c:1331
T1_Operator_
Definition: t1decode.c:44
T1_BuilderRec builder
Definition: psaux.h:895
GLint left
Definition: glext.h:7726
T1_Hints_CloseFunc close
Definition: pshints.h:346
FT_Pos pos_x
Definition: psaux.h:789
FT_UInt num_subglyphs
Definition: freetype.h:1929
FT_Byte ** subrs
Definition: psaux.h:909
FT_Vector left_bearing
Definition: psaux.h:792
FT_Outline * current
Definition: psaux.h:787
t1_builder_close_contour(T1_Builder builder)
Definition: psobjs.c:1711
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
int jpeg_marker_parser_method routine
Definition: jpeglib.h:1089
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
T1_Hints_SetStem3Func stem3
Definition: pshints.h:348
GLsizei const GLfloat * value
Definition: glext.h:6069
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
Definition: vfat.h:184
T1_Hints_ApplyFunc apply
Definition: pshints.h:350
Definition: hiveinit.c:368
void * hints_funcs
Definition: psaux.h:802
DWORD zone
Definition: sec_mgr.c:1760
FT_Glyph_Format format
Definition: freetype.h:1921
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
signed long FT_Fixed
Definition: fttypes.h:288
short n_points
Definition: ftimage.h:337
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
FT_GlyphLoader loader
Definition: psaux.h:785
unsigned int FT_UInt
Definition: fttypes.h:231
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:554
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
FT_UInt len_buildchar
Definition: psaux.h:928
FT_Bool seac
Definition: psaux.h:930
T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS+1]
Definition: psaux.h:900
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
t1_builder_add_point(T1_Builder builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1610
FT_Int num_subrs
Definition: psaux.h:908
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:312
Definition: name.c:36
void * hints_globals
Definition: psaux.h:803
FT_Slot_Internal internal
Definition: freetype.h:1940
t1_builder_init(T1_Builder builder, FT_Face face, FT_Size size, FT_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1533
FT_Render_Mode hint_mode
Definition: psaux.h:922
FT_Hash subrs_hash
Definition: psaux.h:911
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
UINT op
Definition: effect.c:223
T1_Hints hints
Definition: pshints.h:344
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
T1_Hints_SetStemFunc stem
Definition: pshints.h:347
FT_Pos pos_y
Definition: psaux.h:790
t1_decoder_done(T1_Decoder decoder)
Definition: t1decode.c:1973
#define ft_memcpy
Definition: ftstdlib.h:82
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
FT_SubGlyph subglyphs
Definition: freetype.h:1930
FT_UInt num_glyphs
Definition: psaux.h:904
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:41
t1_builder_check_points(T1_Builder builder, FT_Int count)
Definition: psobjs.c:1601
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
size_t FT_Offset
Definition: fttypes.h:324
#define ft_strcmp
Definition: ftstdlib.h:86