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 {
46 op_none = 0,
47 op_endchar,
48 op_hsbw,
49 op_seac,
50 op_sbw,
51 op_closepath,
52 op_hlineto,
53 op_hmoveto,
54 op_hvcurveto,
55 op_rlineto,
56 op_rmoveto,
57 op_rrcurveto,
58 op_vhcurveto,
59 op_vlineto,
60 op_vmoveto,
61 op_dotsection,
62 op_hstem,
63 op_hstem3,
64 op_vstem,
65 op_vstem3,
66 op_div,
67 op_callothersubr,
68 op_callsubr,
69 op_pop,
70 op_return,
71 op_setcurrentpoint,
72 op_unknown15,
73
74 op_max /* never remove this one */
75
76 } T1_Operator;
77
78
79 static
80 const FT_Int t1_args_count[op_max] =
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 */
132 FT_LOCAL_DEF( FT_Int )
133 t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder,
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 */
217 FT_LOCAL_DEF( FT_Error )
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 {
263 FT_Error error;
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 */
336 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
337 if ( error )
338 goto Exit;
339
340 subg = loader->current.subglyphs;
341
342 /* subglyph 0 = base character */
343 subg->index = bchar_index;
344 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
345 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
346 subg->arg1 = 0;
347 subg->arg2 = 0;
348 subg++;
349
350 /* subglyph 1 = accent character */
351 subg->index = achar_index;
352 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
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 */
434 FT_LOCAL_DEF( FT_Error )
435 t1_decoder_parse_charstrings( T1_Decoder decoder,
436 FT_Byte* charstring_base,
437 FT_UInt charstring_len )
438 {
439 FT_Error error;
440 T1_Decoder_Zone zone;
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
487 error = FT_Err_Ok;
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;
502 T1_Operator op = op_none;
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:
546 op = op_rrcurveto;
547 break;
548 case 9:
549 op = op_closepath;
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 */
566 op = op_unknown15;
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:
577 op = op_vhcurveto;
578 break;
579 case 31:
580 op = op_hvcurveto;
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:
594 op = op_dotsection;
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:
612 op = op_callothersubr;
613 break;
614 case 17:
615 op = op_pop;
616 break;
617 case 33:
618 op = op_setcurrentpoint;
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;
750 FT_Int arg_cnt;
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;
896 FT_Long* values;
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
1221 builder->parse_state = T1_Parse_Have_Width;
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
1256 builder->parse_state = T1_Parse_Have_Width;
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
1288 builder->parse_state = T1_Parse_Have_Width;
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;
1309 builder->parse_state = T1_Parse_Have_Moveto;
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;
1355 builder->parse_state = T1_Parse_Have_Moveto;
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;
1415 builder->parse_state = T1_Parse_Have_Moveto;
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 */
1684 FT_LOCAL_DEF( FT_Error )
1685 t1_decoder_parse_metrics( T1_Decoder decoder,
1686 FT_Byte* charstring_base,
1687 FT_UInt charstring_len )
1688 {
1689 T1_Decoder_Zone zone;
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;
1714 T1_Operator op = op_none;
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
1887 builder->parse_state = T1_Parse_Have_Width;
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
1904 builder->parse_state = T1_Parse_Have_Width;
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 */
1947 FT_LOCAL_DEF( FT_Error )
1948 t1_decoder_init( T1_Decoder decoder,
1949 FT_Face face,
1950 FT_Size size,
1951 FT_GlyphSlot slot,
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 )
1996 t1_decoder_done( T1_Decoder decoder )
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 */
2012