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