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