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