Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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