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