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