zenilib: zenilib/jni/external/freetype2/src/psaux/t1decode.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
t1decode.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* t1decode.c */
4 /* */
5 /* PostScript Type 1 decoding routines (body). */
6 /* */
7 /* Copyright 2000-2011 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_OUTLINE_H
24
25 #include "t1decode.h"
26 #include "psobjs.h"
27
28 #include "psauxerr.h"
29
30 /* ensure proper sign extension */
31 #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) )
32
33 /*************************************************************************/
34 /* */
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */
38 /* */
39 #undef FT_COMPONENT
40 #define FT_COMPONENT trace_t1decode
41
42
43 typedef enum T1_Operator_
44 {
45 op_none = 0,
46 op_endchar,
47 op_hsbw,
48 op_seac,
49 op_sbw,
50 op_closepath,
51 op_hlineto,
52 op_hmoveto,
53 op_hvcurveto,
54 op_rlineto,
55 op_rmoveto,
56 op_rrcurveto,
57 op_vhcurveto,
58 op_vlineto,
59 op_vmoveto,
60 op_dotsection,
61 op_hstem,
62 op_hstem3,
63 op_vstem,
64 op_vstem3,
65 op_div,
66 op_callothersubr,
67 op_callsubr,
68 op_pop,
69 op_return,
70 op_setcurrentpoint,
71 op_unknown15,
72
73 op_max /* never remove this one */
74
75 } T1_Operator;
76
77
78 static
79 const FT_Int t1_args_count[op_max] =
80 {
81 0, /* none */
82 0, /* endchar */
83 2, /* hsbw */
84 5, /* seac */
85 4, /* sbw */
86 0, /* closepath */
87 1, /* hlineto */
88 1, /* hmoveto */
89 4, /* hvcurveto */
90 2, /* rlineto */
91 2, /* rmoveto */
92 6, /* rrcurveto */
93 4, /* vhcurveto */
94 1, /* vlineto */
95 1, /* vmoveto */
96 0, /* dotsection */
97 2, /* hstem */
98 6, /* hstem3 */
99 2, /* vstem */
100 6, /* vstem3 */
101 2, /* div */
102 -1, /* callothersubr */
103 1, /* callsubr */
104 0, /* pop */
105 0, /* return */
106 2, /* setcurrentpoint */
107 2 /* opcode 15 (undocumented and obsolete) */
108 };
109
110
111 /*************************************************************************/
112 /* */
113 /* <Function> */
114 /* t1_lookup_glyph_by_stdcharcode */
115 /* */
116 /* <Description> */
117 /* Looks up a given glyph by its StandardEncoding charcode. Used to */
118 /* implement the SEAC Type 1 operator. */
119 /* */
120 /* <Input> */
121 /* face :: The current face object. */
122 /* */
123 /* charcode :: The character code to look for. */
124 /* */
125 /* <Return> */
126 /* A glyph index in the font face. Returns -1 if the corresponding */
127 /* glyph wasn't found. */
128 /* */
129 static FT_Int
130 t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder,
131 FT_Int charcode )
132 {
133 FT_UInt n;
134 const FT_String* glyph_name;
135 FT_Service_PsCMaps psnames = decoder->psnames;
136
137
138 /* check range of standard char code */
139 if ( charcode < 0 || charcode > 255 )
140 return -1;
141
142 glyph_name = psnames->adobe_std_strings(
143 psnames->adobe_std_encoding[charcode]);
144
145 for ( n = 0; n < decoder->num_glyphs; n++ )
146 {
147 FT_String* name = (FT_String*)decoder->glyph_names[n];
148
149
150 if ( name &&
151 name[0] == glyph_name[0] &&
152 ft_strcmp( name, glyph_name ) == 0 )
153 return n;
154 }
155
156 return -1;
157 }
158
159
160 /*************************************************************************/
161 /* */
162 /* <Function> */
163 /* t1operator_seac */
164 /* */
165 /* <Description> */
166 /* Implements the `seac' Type 1 operator for a Type 1 decoder. */
167 /* */
168 /* <Input> */
169 /* decoder :: The current CID decoder. */
170 /* */
171 /* asb :: The accent's side bearing. */
172 /* */
173 /* adx :: The horizontal offset of the accent. */
174 /* */
175 /* ady :: The vertical offset of the accent. */
176 /* */
177 /* bchar :: The base character's StandardEncoding charcode. */
178 /* */
179 /* achar :: The accent character's StandardEncoding charcode. */
180 /* */
181 /* <Return> */
182 /* FreeType error code. 0 means success. */
183 /* */
184 static FT_Error
185 t1operator_seac( T1_Decoder decoder,
186 FT_Pos asb,
187 FT_Pos adx,
188 FT_Pos ady,
189 FT_Int bchar,
190 FT_Int achar )
191 {
192 FT_Error error;
193 FT_Int bchar_index, achar_index;
194 #if 0
195 FT_Int n_base_points;
196 FT_Outline* base = decoder->builder.base;
197 #endif
198 FT_Vector left_bearing, advance;
199
200 #ifdef FT_CONFIG_OPTION_INCREMENTAL
201 T1_Face face = (T1_Face)decoder->builder.face;
202 #endif
203
204
205 if ( decoder->seac )
206 {
207 FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
208 return PSaux_Err_Syntax_Error;
209 }
210
211 /* seac weirdness */
212 adx += decoder->builder.left_bearing.x;
213
214 /* `glyph_names' is set to 0 for CID fonts which do not */
215 /* include an encoding. How can we deal with these? */
216 #ifdef FT_CONFIG_OPTION_INCREMENTAL
217 if ( decoder->glyph_names == 0 &&
218 !face->root.internal->incremental_interface )
219 #else
220 if ( decoder->glyph_names == 0 )
221 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
222 {
223 FT_ERROR(( "t1operator_seac:"
224 " glyph names table not available in this font\n" ));
225 return PSaux_Err_Syntax_Error;
226 }
227
228 #ifdef FT_CONFIG_OPTION_INCREMENTAL
229 if ( face->root.internal->incremental_interface )
230 {
231 /* the caller must handle the font encoding also */
232 bchar_index = bchar;
233 achar_index = achar;
234 }
235 else
236 #endif
237 {
238 bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
239 achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
240 }
241
242 if ( bchar_index < 0 || achar_index < 0 )
243 {
244 FT_ERROR(( "t1operator_seac:"
245 " invalid seac character code arguments\n" ));
246 return PSaux_Err_Syntax_Error;
247 }
248
249 /* if we are trying to load a composite glyph, do not load the */
250 /* accent character and return the array of subglyphs. */
251 if ( decoder->builder.no_recurse )
252 {
253 FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
254 FT_GlyphLoader loader = glyph->internal->loader;
255 FT_SubGlyph subg;
256
257
258 /* reallocate subglyph array if necessary */
259 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
260 if ( error )
261 goto Exit;
262
263 subg = loader->current.subglyphs;
264
265 /* subglyph 0 = base character */
266 subg->index = bchar_index;
267 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
268 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
269 subg->arg1 = 0;
270 subg->arg2 = 0;
271 subg++;
272
273 /* subglyph 1 = accent character */
274 subg->index = achar_index;
275 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
276 subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
277 subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
278
279 /* set up remaining glyph fields */
280 glyph->num_subglyphs = 2;
281 glyph->subglyphs = loader->base.subglyphs;
282 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
283
284 loader->current.num_subglyphs = 2;
285 goto Exit;
286 }
287
288 /* First load `bchar' in builder */
289 /* now load the unscaled outline */
290
291 FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
292
293 /* the seac operator must not be nested */
294 decoder->seac = TRUE;
295 error = t1_decoder_parse_glyph( decoder, bchar_index );
296 decoder->seac = FALSE;
297 if ( error )
298 goto Exit;
299
300 /* save the left bearing and width of the base character */
301 /* as they will be erased by the next load. */
302
303 left_bearing = decoder->builder.left_bearing;
304 advance = decoder->builder.advance;
305
306 decoder->builder.left_bearing.x = 0;
307 decoder->builder.left_bearing.y = 0;
308
309 decoder->builder.pos_x = adx - asb;
310 decoder->builder.pos_y = ady;
311
312 /* Now load `achar' on top of */
313 /* the base outline */
314
315 /* the seac operator must not be nested */
316 decoder->seac = TRUE;
317 error = t1_decoder_parse_glyph( decoder, achar_index );
318 decoder->seac = FALSE;
319 if ( error )
320 goto Exit;
321
322 /* restore the left side bearing and */
323 /* advance width of the base character */
324
325 decoder->builder.left_bearing = left_bearing;
326 decoder->builder.advance = advance;
327
328 decoder->builder.pos_x = 0;
329 decoder->builder.pos_y = 0;
330
331 Exit:
332 return error;
333 }
334
335
336 /*************************************************************************/
337 /* */
338 /* <Function> */
339 /* t1_decoder_parse_charstrings */
340 /* */
341 /* <Description> */
342 /* Parses a given Type 1 charstrings program. */
343 /* */
344 /* <Input> */
345 /* decoder :: The current Type 1 decoder. */
346 /* */
347 /* charstring_base :: The base address of the charstring stream. */
348 /* */
349 /* charstring_len :: The length in bytes of the charstring stream. */
350 /* */
351 /* <Return> */
352 /* FreeType error code. 0 means success. */
353 /* */
354 FT_LOCAL_DEF( FT_Error )
355 t1_decoder_parse_charstrings( T1_Decoder decoder,
356 FT_Byte* charstring_base,
357 FT_UInt charstring_len )
358 {
359 FT_Error error;
360 T1_Decoder_Zone zone;
361 FT_Byte* ip;
362 FT_Byte* limit;
363 T1_Builder builder = &decoder->builder;
364 FT_Pos x, y, orig_x, orig_y;
365 FT_Int known_othersubr_result_cnt = 0;
366 FT_Int unknown_othersubr_result_cnt = 0;
367 FT_Bool large_int;
368 FT_Fixed seed;
369
370 T1_Hints_Funcs hinter;
371
372 #ifdef FT_DEBUG_LEVEL_TRACE
373 FT_Bool bol = TRUE;
374 #endif
375
376
377 /* compute random seed from stack address of parameter */
378 seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
379 (FT_PtrDist)(char*)&decoder ^
380 (FT_PtrDist)(char*)&charstring_base ) &
381 FT_ULONG_MAX ) ;
382 seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
383 if ( seed == 0 )
384 seed = 0x7384;
385
386 /* First of all, initialize the decoder */
387 decoder->top = decoder->stack;
388 decoder->zone = decoder->zones;
389 zone = decoder->zones;
390
391 builder->parse_state = T1_Parse_Start;
392
393 hinter = (T1_Hints_Funcs)builder->hints_funcs;
394
395 /* a font that reads BuildCharArray without setting */
396 /* its values first is buggy, but ... */
397 FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
398 ( decoder->buildchar == NULL ) );
399
400 if ( decoder->buildchar && decoder->len_buildchar > 0 )
401 ft_memset( &decoder->buildchar[0],
402 0,
403 sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar );
404
405 FT_TRACE4(( "\n"
406 "Start charstring\n" ));
407
408 zone->base = charstring_base;
409 limit = zone->limit = charstring_base + charstring_len;
410 ip = zone->cursor = zone->base;
411
412 error = PSaux_Err_Ok;
413
414 x = orig_x = builder->pos_x;
415 y = orig_y = builder->pos_y;
416
417 /* begin hints recording session, if any */
418 if ( hinter )
419 hinter->open( hinter->hints );
420
421 large_int = FALSE;
422
423 /* now, execute loop */
424 while ( ip < limit )
425 {
426 FT_Long* top = decoder->top;
427 T1_Operator op = op_none;
428 FT_Int32 value = 0;
429
430
431 FT_ASSERT( known_othersubr_result_cnt == 0 ||
432 unknown_othersubr_result_cnt == 0 );
433
434 #ifdef FT_DEBUG_LEVEL_TRACE
435 if ( bol )
436 {
437 FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
438 bol = FALSE;
439 }
440 #endif
441
442 /*********************************************************************/
443 /* */
444 /* Decode operator or operand */
445 /* */
446 /* */
447
448 /* first of all, decompress operator or value */
449 switch ( *ip++ )
450 {
451 case 1:
452 op = op_hstem;
453 break;
454
455 case 3:
456 op = op_vstem;
457 break;
458 case 4:
459 op = op_vmoveto;
460 break;
461 case 5:
462 op = op_rlineto;
463 break;
464 case 6:
465 op = op_hlineto;
466 break;
467 case 7:
468 op = op_vlineto;
469 break;
470 case 8:
471 op = op_rrcurveto;
472 break;
473 case 9:
474 op = op_closepath;
475 break;
476 case 10:
477 op = op_callsubr;
478 break;
479 case 11:
480 op = op_return;
481 break;
482
483 case 13:
484 op = op_hsbw;
485 break;
486 case 14:
487 op = op_endchar;
488 break;
489
490 case 15: /* undocumented, obsolete operator */
491 op = op_unknown15;
492 break;
493
494 case 21:
495 op = op_rmoveto;
496 break;
497 case 22:
498 op = op_hmoveto;
499 break;
500
501 case 30:
502 op = op_vhcurveto;
503 break;
504 case 31:
505 op = op_hvcurveto;
506 break;
507
508 case 12:
509 if ( ip > limit )
510 {
511 FT_ERROR(( "t1_decoder_parse_charstrings:"
512 " invalid escape (12+EOF)\n" ));
513 goto Syntax_Error;
514 }
515
516 switch ( *ip++ )
517 {
518 case 0:
519 op = op_dotsection;
520 break;
521 case 1:
522 op = op_vstem3;
523 break;
524 case 2:
525 op = op_hstem3;
526 break;
527 case 6:
528 op = op_seac;
529 break;
530 case 7:
531 op = op_sbw;
532 break;
533 case 12:
534 op = op_div;
535 break;
536 case 16:
537 op = op_callothersubr;
538 break;
539 case 17:
540 op = op_pop;
541 break;
542 case 33:
543 op = op_setcurrentpoint;
544 break;
545
546 default:
547 FT_ERROR(( "t1_decoder_parse_charstrings:"
548 " invalid escape (12+%d)\n",
549 ip[-1] ));
550 goto Syntax_Error;
551 }
552 break;
553
554 case 255: /* four bytes integer */
555 if ( ip + 4 > limit )
556 {
557 FT_ERROR(( "t1_decoder_parse_charstrings:"
558 " unexpected EOF in integer\n" ));
559 goto Syntax_Error;
560 }
561
562 value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
563 ( (FT_Long)ip[1] << 16 ) |
564 ( (FT_Long)ip[2] << 8 ) |
565 ip[3] );
566 ip += 4;
567
568 /* According to the specification, values > 32000 or < -32000 must */
569 /* be followed by a `div' operator to make the result be in the */
570 /* range [-32000;32000]. We expect that the second argument of */
571 /* `div' is not a large number. Additionally, we don't handle */
572 /* stuff like `<large1> <large2> <num> div <num> div' or */
573 /* <large1> <large2> <num> div div'. This is probably not allowed */
574 /* anyway. */
575 if ( value > 32000 || value < -32000 )
576 {
577 if ( large_int )
578 {
579 FT_ERROR(( "t1_decoder_parse_charstrings:"
580 " no `div' after large integer\n" ));
581 }
582 else
583 large_int = TRUE;
584 }
585 else
586 {
587 if ( !large_int )
588 value <<= 16;
589 }
590
591 break;
592
593 default:
594 if ( ip[-1] >= 32 )
595 {
596 if ( ip[-1] < 247 )
597 value = (FT_Int32)ip[-1] - 139;
598 else
599 {
600 if ( ++ip > limit )
601 {
602 FT_ERROR(( "t1_decoder_parse_charstrings:"
603 " unexpected EOF in integer\n" ));
604 goto Syntax_Error;
605 }
606
607 if ( ip[-2] < 251 )
608 value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
609 else
610 value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
611 }
612
613 if ( !large_int )
614 value <<= 16;
615 }
616 else
617 {
618 FT_ERROR(( "t1_decoder_parse_charstrings:"
619 " invalid byte (%d)\n", ip[-1] ));
620 goto Syntax_Error;
621 }
622 }
623
624 if ( unknown_othersubr_result_cnt > 0 )
625 {
626 switch ( op )
627 {
628 case op_callsubr:
629 case op_return:
630 case op_none:
631 case op_pop:
632 break;
633
634 default:
635 /* all operands have been transferred by previous pops */
636 unknown_othersubr_result_cnt = 0;
637 break;
638 }
639 }
640
641 if ( large_int && !( op == op_none || op == op_div ) )
642 {
643 FT_ERROR(( "t1_decoder_parse_charstrings:"
644 " no `div' after large integer\n" ));
645
646 large_int = FALSE;
647 }
648
649 /*********************************************************************/
650 /* */
651 /* Push value on stack, or process operator */
652 /* */
653 /* */
654 if ( op == op_none )
655 {
656 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
657 {
658 FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
659 goto Syntax_Error;
660 }
661
662 #ifdef FT_DEBUG_LEVEL_TRACE
663 if ( large_int )
664 FT_TRACE4(( " %ld", value ));
665 else
666 FT_TRACE4(( " %ld", Fix2Int( value ) ));
667 #endif
668
669 *top++ = value;
670 decoder->top = top;
671 }
672 else if ( op == op_callothersubr ) /* callothersubr */
673 {
674 FT_Int subr_no;
675 FT_Int arg_cnt;
676
677
678 #ifdef FT_DEBUG_LEVEL_TRACE
679 FT_TRACE4(( " callothersubr\n" ));
680 bol = TRUE;
681 #endif
682
683 if ( top - decoder->stack < 2 )
684 goto Stack_Underflow;
685
686 top -= 2;
687
688 subr_no = Fix2Int( top[1] );
689 arg_cnt = Fix2Int( top[0] );
690
691 /***********************************************************/
692 /* */
693 /* remove all operands to callothersubr from the stack */
694 /* */
695 /* for handled othersubrs, where we know the number of */
696 /* arguments, we increase the stack by the value of */
697 /* known_othersubr_result_cnt */
698 /* */
699 /* for unhandled othersubrs the following pops adjust the */
700 /* stack pointer as necessary */
701
702 if ( arg_cnt > top - decoder->stack )
703 goto Stack_Underflow;
704
705 top -= arg_cnt;
706
707 known_othersubr_result_cnt = 0;
708 unknown_othersubr_result_cnt = 0;
709
710 /* XXX TODO: The checks to `arg_count == <whatever>' */
711 /* might not be correct; an othersubr expects a certain */
712 /* number of operands on the PostScript stack (as opposed */
713 /* to the T1 stack) but it doesn't have to put them there */
714 /* by itself; previous othersubrs might have left the */
715 /* operands there if they were not followed by an */
716 /* appropriate number of pops */
717 /* */
718 /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
719 /* accept a font that contains charstrings like */
720 /* */
721 /* 100 200 2 20 callothersubr */
722 /* 300 1 20 callothersubr pop */
723 /* */
724 /* Perhaps this is the reason why BuildCharArray exists. */
725
726 switch ( subr_no )
727 {
728 case 0: /* end flex feature */
729 if ( arg_cnt != 3 )
730 goto Unexpected_OtherSubr;
731
732 if ( decoder->flex_state == 0 ||
733 decoder->num_flex_vectors != 7 )
734 {
735 FT_ERROR(( "t1_decoder_parse_charstrings:"
736 " unexpected flex end\n" ));
737 goto Syntax_Error;
738 }
739
740 /* the two `results' are popped by the following setcurrentpoint */
741 top[0] = x;
742 top[1] = y;
743 known_othersubr_result_cnt = 2;
744 break;
745
746 case 1: /* start flex feature */
747 if ( arg_cnt != 0 )
748 goto Unexpected_OtherSubr;
749
750 decoder->flex_state = 1;
751 decoder->num_flex_vectors = 0;
752 if ( ( error = t1_builder_start_point( builder, x, y ) )
753 != PSaux_Err_Ok ||
754 ( error = t1_builder_check_points( builder, 6 ) )
755 != PSaux_Err_Ok )
756 goto Fail;
757 break;
758
759 case 2: /* add flex vectors */
760 {
761 FT_Int idx;
762
763
764 if ( arg_cnt != 0 )
765 goto Unexpected_OtherSubr;
766
767 if ( decoder->flex_state == 0 )
768 {
769 FT_ERROR(( "t1_decoder_parse_charstrings:"
770 " missing flex start\n" ));
771 goto Syntax_Error;
772 }
773
774 /* note that we should not add a point for index 0; */
775 /* this will move our current position to the flex */
776 /* point without adding any point to the outline */
777 idx = decoder->num_flex_vectors++;
778 if ( idx > 0 && idx < 7 )
779 t1_builder_add_point( builder,
780 x,
781 y,
782 (FT_Byte)( idx == 3 || idx == 6 ) );
783 }
784 break;
785
786 case 3: /* change hints */
787 if ( arg_cnt != 1 )
788 goto Unexpected_OtherSubr;
789
790 known_othersubr_result_cnt = 1;
791
792 if ( hinter )
793 hinter->reset( hinter->hints, builder->current->n_points );
794 break;
795
796 case 12:
797 case 13:
798 /* counter control hints, clear stack */
799 top = decoder->stack;
800 break;
801
802 case 14:
803 case 15:
804 case 16:
805 case 17:
806 case 18: /* multiple masters */
807 {
808 PS_Blend blend = decoder->blend;
809 FT_UInt num_points, nn, mm;
810 FT_Long* delta;
811 FT_Long* values;
812
813
814 if ( !blend )
815 {
816 FT_ERROR(( "t1_decoder_parse_charstrings:"
817 " unexpected multiple masters operator\n" ));
818 goto Syntax_Error;
819 }
820
821 num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
822 if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
823 {
824 FT_ERROR(( "t1_decoder_parse_charstrings:"
825 " incorrect number of multiple masters arguments\n" ));
826 goto Syntax_Error;
827 }
828
829 /* We want to compute */
830 /* */
831 /* a0*w0 + a1*w1 + ... + ak*wk */
832 /* */
833 /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */
834 /* */
835 /* However, given that w0 + w1 + ... + wk == 1, we can */
836 /* rewrite it easily as */
837 /* */
838 /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */
839 /* */
840 /* where k == num_designs-1. */
841 /* */
842 /* I guess that's why it's written in this `compact' */
843 /* form. */
844 /* */
845 delta = top + num_points;
846 values = top;
847 for ( nn = 0; nn < num_points; nn++ )
848 {
849 FT_Long tmp = values[0];
850
851
852 for ( mm = 1; mm < blend->num_designs; mm++ )
853 tmp += FT_MulFix( *delta++, blend->weight_vector[mm] );
854
855 *values++ = tmp;
856 }
857
858 known_othersubr_result_cnt = num_points;
859 break;
860 }
861
862 case 19:
863 /* <idx> 1 19 callothersubr */
864 /* => replace elements starting from index cvi( <idx> ) */
865 /* of BuildCharArray with WeightVector */
866 {
867 FT_Int idx;
868 PS_Blend blend = decoder->blend;
869
870
871 if ( arg_cnt != 1 || blend == NULL )
872 goto Unexpected_OtherSubr;
873
874 idx = Fix2Int( top[0] );
875
876 if ( idx < 0 ||
877 idx + blend->num_designs > decoder->len_buildchar )
878 goto Unexpected_OtherSubr;
879
880 ft_memcpy( &decoder->buildchar[idx],
881 blend->weight_vector,
882 blend->num_designs *
883 sizeof ( blend->weight_vector[0] ) );
884 }
885 break;
886
887 case 20:
888 /* <arg1> <arg2> 2 20 callothersubr pop */
889 /* ==> push <arg1> + <arg2> onto T1 stack */
890 if ( arg_cnt != 2 )
891 goto Unexpected_OtherSubr;
892
893 top[0] += top[1]; /* XXX (over|under)flow */
894
895 known_othersubr_result_cnt = 1;
896 break;
897
898 case 21:
899 /* <arg1> <arg2> 2 21 callothersubr pop */
900 /* ==> push <arg1> - <arg2> onto T1 stack */
901 if ( arg_cnt != 2 )
902 goto Unexpected_OtherSubr;
903
904 top[0] -= top[1]; /* XXX (over|under)flow */
905
906 known_othersubr_result_cnt = 1;
907 break;
908
909 case 22:
910 /* <arg1> <arg2> 2 22 callothersubr pop */
911 /* ==> push <arg1> * <arg2> onto T1 stack */
912 if ( arg_cnt != 2 )
913 goto Unexpected_OtherSubr;
914
915 top[0] = FT_MulFix( top[0], top[1] );
916
917 known_othersubr_result_cnt = 1;
918 break;
919
920 case 23:
921 /* <arg1> <arg2> 2 23 callothersubr pop */
922 /* ==> push <arg1> / <arg2> onto T1 stack */
923 if ( arg_cnt != 2 || top[1] == 0 )
924 goto Unexpected_OtherSubr;
925
926 top[0] = FT_DivFix( top[0], top[1] );
927
928 known_othersubr_result_cnt = 1;
929 break;
930
931 case 24:
932 /* <val> <idx> 2 24 callothersubr */
933 /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
934 {
935 FT_Int idx;
936 PS_Blend blend = decoder->blend;
937
938
939 if ( arg_cnt != 2 || blend == NULL )
940 goto Unexpected_OtherSubr;
941
942 idx = Fix2Int( top[1] );
943
944 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
945 goto Unexpected_OtherSubr;
946
947 decoder->buildchar[idx] = top[0];
948 }
949 break;
950
951 case 25:
952 /* <idx> 1 25 callothersubr pop */
953 /* ==> push BuildCharArray[cvi( idx )] */
954 /* onto T1 stack */
955 {
956 FT_Int idx;
957 PS_Blend blend = decoder->blend;
958
959
960 if ( arg_cnt != 1 || blend == NULL )
961 goto Unexpected_OtherSubr;
962
963 idx = Fix2Int( top[0] );
964
965 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
966 goto Unexpected_OtherSubr;
967
968 top[0] = decoder->buildchar[idx];
969 }
970
971 known_othersubr_result_cnt = 1;
972 break;
973
974 #if 0
975 case 26:
976 /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
977 /* leave mark on T1 stack */
978 /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
979 XXX which routine has left its mark on the (PostScript) stack?;
980 break;
981 #endif
982
983 case 27:
984 /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
985 /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
986 /* otherwise push <res2> */
987 if ( arg_cnt != 4 )
988 goto Unexpected_OtherSubr;
989
990 if ( top[2] > top[3] )
991 top[0] = top[1];
992
993 known_othersubr_result_cnt = 1;
994 break;
995
996 case 28:
997 /* 0 28 callothersubr pop */
998 /* => push random value from interval [0, 1) onto stack */
999 if ( arg_cnt != 0 )
1000 goto Unexpected_OtherSubr;
1001
1002 {
1003 FT_Fixed Rand;
1004
1005
1006 Rand = seed;
1007 if ( Rand >= 0x8000L )
1008 Rand++;
1009
1010 top[0] = Rand;
1011
1012 seed = FT_MulFix( seed, 0x10000L - seed );
1013 if ( seed == 0 )
1014 seed += 0x2873;
1015 }
1016
1017 known_othersubr_result_cnt = 1;
1018 break;
1019
1020 default:
1021 if ( arg_cnt >= 0 && subr_no >= 0 )
1022 {
1023 FT_ERROR(( "t1_decoder_parse_charstrings:"
1024 " unknown othersubr [%d %d], wish me luck\n",
1025 arg_cnt, subr_no ));
1026 unknown_othersubr_result_cnt = arg_cnt;
1027 break;
1028 }
1029 /* fall through */
1030
1031 Unexpected_OtherSubr:
1032 FT_ERROR(( "t1_decoder_parse_charstrings:"
1033 " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
1034 goto Syntax_Error;
1035 }
1036
1037 top += known_othersubr_result_cnt;
1038
1039 decoder->top = top;
1040 }
1041 else /* general operator */
1042 {
1043 FT_Int num_args = t1_args_count[op];
1044
1045
1046 FT_ASSERT( num_args >= 0 );
1047
1048 if ( top - decoder->stack < num_args )
1049 goto Stack_Underflow;
1050
1051 /* XXX Operators usually take their operands from the */
1052 /* bottom of the stack, i.e., the operands are */
1053 /* decoder->stack[0], ..., decoder->stack[num_args - 1]; */
1054 /* only div, callsubr, and callothersubr are different. */
1055 /* In practice it doesn't matter (?). */
1056
1057 #ifdef FT_DEBUG_LEVEL_TRACE
1058
1059 switch ( op )
1060 {
1061 case op_callsubr:
1062 case op_div:
1063 case op_callothersubr:
1064 case op_pop:
1065 case op_return:
1066 break;
1067
1068 default:
1069 if ( top - decoder->stack != num_args )
1070 FT_TRACE0(( "t1_decoder_parse_charstrings:"
1071 " too much operands on the stack"
1072 " (seen %d, expected %d)\n",
1073 top - decoder->stack, num_args ));
1074 break;
1075 }
1076
1077 #endif /* FT_DEBUG_LEVEL_TRACE */
1078
1079 top -= num_args;
1080
1081 switch ( op )
1082 {
1083 case op_endchar:
1084 FT_TRACE4(( " endchar\n" ));
1085
1086 t1_builder_close_contour( builder );
1087
1088 /* close hints recording session */
1089 if ( hinter )
1090 {
1091 if ( hinter->close( hinter->hints, builder->current->n_points ) )
1092 goto Syntax_Error;
1093
1094 /* apply hints to the loaded glyph outline now */
1095 hinter->apply( hinter->hints,
1096 builder->current,
1097 (PSH_Globals)builder->hints_globals,
1098 decoder->hint_mode );
1099 }
1100
1101 /* add current outline to the glyph slot */
1102 FT_GlyphLoader_Add( builder->loader );
1103
1104 /* the compiler should optimize away this empty loop but ... */
1105
1106 #ifdef FT_DEBUG_LEVEL_TRACE
1107
1108 if ( decoder->len_buildchar > 0 )
1109 {
1110 FT_UInt i;
1111
1112
1113 FT_TRACE4(( "BuildCharArray = [ " ));
1114
1115 for ( i = 0; i < decoder->len_buildchar; ++i )
1116 FT_TRACE4(( "%d ", decoder->buildchar[i] ));
1117
1118 FT_TRACE4(( "]\n" ));
1119 }
1120
1121 #endif /* FT_DEBUG_LEVEL_TRACE */
1122
1123 FT_TRACE4(( "\n" ));
1124
1125 /* return now! */
1126 return PSaux_Err_Ok;
1127
1128 case op_hsbw:
1129 FT_TRACE4(( " hsbw" ));
1130
1131 builder->parse_state = T1_Parse_Have_Width;
1132
1133 builder->left_bearing.x += top[0];
1134 builder->advance.x = top[1];
1135 builder->advance.y = 0;
1136
1137 orig_x = x = builder->pos_x + top[0];
1138 orig_y = y = builder->pos_y;
1139
1140 FT_UNUSED( orig_y );
1141
1142 /* the `metrics_only' indicates that we only want to compute */
1143 /* the glyph's metrics (lsb + advance width), not load the */
1144 /* rest of it; so exit immediately */
1145 if ( builder->metrics_only )
1146 return PSaux_Err_Ok;
1147
1148 break;
1149
1150 case op_seac:
1151 return t1operator_seac( decoder,
1152 top[0],
1153 top[1],
1154 top[2],
1155 Fix2Int( top[3] ),
1156 Fix2Int( top[4] ) );
1157
1158 case op_sbw:
1159 FT_TRACE4(( " sbw" ));
1160
1161 builder->parse_state = T1_Parse_Have_Width;
1162
1163 builder->left_bearing.x += top[0];
1164 builder->left_bearing.y += top[1];
1165 builder->advance.x = top[2];
1166 builder->advance.y = top[3];
1167
1168 x = builder->pos_x + top[0];
1169 y = builder->pos_y + top[1];
1170
1171 /* the `metrics_only' indicates that we only want to compute */
1172 /* the glyph's metrics (lsb + advance width), not load the */
1173 /* rest of it; so exit immediately */
1174 if ( builder->metrics_only )
1175 return PSaux_Err_Ok;
1176
1177 break;
1178
1179 case op_closepath:
1180 FT_TRACE4(( " closepath" ));
1181
1182 /* if there is no path, `closepath' is a no-op */
1183 if ( builder->parse_state == T1_Parse_Have_Path ||
1184 builder->parse_state == T1_Parse_Have_Moveto )
1185 t1_builder_close_contour( builder );
1186
1187 builder->parse_state = T1_Parse_Have_Width;
1188 break;
1189
1190 case op_hlineto:
1191 FT_TRACE4(( " hlineto" ));
1192
1193 if ( ( error = t1_builder_start_point( builder, x, y ) )
1194 != PSaux_Err_Ok )
1195 goto Fail;
1196
1197 x += top[0];
1198 goto Add_Line;
1199
1200 case op_hmoveto:
1201 FT_TRACE4(( " hmoveto" ));
1202
1203 x += top[0];
1204 if ( !decoder->flex_state )
1205 {
1206 if ( builder->parse_state == T1_Parse_Start )
1207 goto Syntax_Error;
1208 builder->parse_state = T1_Parse_Have_Moveto;
1209 }
1210 break;
1211
1212 case op_hvcurveto:
1213 FT_TRACE4(( " hvcurveto" ));
1214
1215 if ( ( error = t1_builder_start_point( builder, x, y ) )
1216 != PSaux_Err_Ok ||
1217 ( error = t1_builder_check_points( builder, 3 ) )
1218 != PSaux_Err_Ok )
1219 goto Fail;
1220
1221 x += top[0];
1222 t1_builder_add_point( builder, x, y, 0 );
1223 x += top[1];
1224 y += top[2];
1225 t1_builder_add_point( builder, x, y, 0 );
1226 y += top[3];
1227 t1_builder_add_point( builder, x, y, 1 );
1228 break;
1229
1230 case op_rlineto:
1231 FT_TRACE4(( " rlineto" ));
1232
1233 if ( ( error = t1_builder_start_point( builder, x, y ) )
1234 != PSaux_Err_Ok )
1235 goto Fail;
1236
1237 x += top[0];
1238 y += top[1];
1239
1240 Add_Line:
1241 if ( ( error = t1_builder_add_point1( builder, x, y ) )
1242 != PSaux_Err_Ok )
1243 goto Fail;
1244 break;
1245
1246 case op_rmoveto:
1247 FT_TRACE4(( " rmoveto" ));
1248
1249 x += top[0];
1250 y += top[1];
1251 if ( !decoder->flex_state )
1252 {
1253 if ( builder->parse_state == T1_Parse_Start )
1254 goto Syntax_Error;
1255 builder->parse_state = T1_Parse_Have_Moveto;
1256 }
1257 break;
1258
1259 case op_rrcurveto:
1260 FT_TRACE4(( " rrcurveto" ));
1261
1262 if ( ( error = t1_builder_start_point( builder, x, y ) )
1263 != PSaux_Err_Ok ||
1264 ( error = t1_builder_check_points( builder, 3 ) )
1265 != PSaux_Err_Ok )
1266 goto Fail;
1267
1268 x += top[0];
1269 y += top[1];
1270 t1_builder_add_point( builder, x, y, 0 );
1271
1272 x += top[2];
1273 y += top[3];
1274 t1_builder_add_point( builder, x, y, 0 );
1275
1276 x += top[4];
1277 y += top[5];
1278 t1_builder_add_point( builder, x, y, 1 );
1279 break;
1280
1281 case op_vhcurveto:
1282 FT_TRACE4(( " vhcurveto" ));
1283
1284 if ( ( error = t1_builder_start_point( builder, x, y ) )
1285 != PSaux_Err_Ok ||
1286 ( error = t1_builder_check_points( builder, 3 ) )
1287 != PSaux_Err_Ok )
1288 goto Fail;
1289
1290 y += top[0];
1291 t1_builder_add_point( builder, x, y, 0 );
1292 x += top[1];
1293 y += top[2];
1294 t1_builder_add_point( builder, x, y, 0 );
1295 x += top[3];
1296 t1_builder_add_point( builder, x, y, 1 );
1297 break;
1298
1299 case op_vlineto:
1300 FT_TRACE4(( " vlineto" ));
1301
1302 if ( ( error = t1_builder_start_point( builder, x, y ) )
1303 != PSaux_Err_Ok )
1304 goto Fail;
1305
1306 y += top[0];
1307 goto Add_Line;
1308
1309 case op_vmoveto:
1310 FT_TRACE4(( " vmoveto" ));
1311
1312 y += top[0];
1313 if ( !decoder->flex_state )
1314 {
1315 if ( builder->parse_state == T1_Parse_Start )
1316 goto Syntax_Error;
1317 builder->parse_state = T1_Parse_Have_Moveto;
1318 }
1319 break;
1320
1321 case op_div:
1322 FT_TRACE4(( " div" ));
1323
1324 /* if `large_int' is set, we divide unscaled numbers; */
1325 /* otherwise, we divide numbers in 16.16 format -- */
1326 /* in both cases, it is the same operation */
1327 *top = FT_DivFix( top[0], top[1] );
1328 ++top;
1329
1330 large_int = FALSE;
1331 break;
1332
1333 case op_callsubr:
1334 {
1335 FT_Int idx;
1336
1337
1338 FT_TRACE4(( " callsubr" ));
1339
1340 idx = Fix2Int( top[0] );
1341 if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
1342 {
1343 FT_ERROR(( "t1_decoder_parse_charstrings:"
1344 " invalid subrs index\n" ));
1345 goto Syntax_Error;
1346 }
1347
1348 if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
1349 {
1350 FT_ERROR(( "t1_decoder_parse_charstrings:"
1351 " too many nested subrs\n" ));
1352 goto Syntax_Error;
1353 }
1354
1355 zone->cursor = ip; /* save current instruction pointer */
1356
1357 zone++;
1358
1359 /* The Type 1 driver stores subroutines without the seed bytes. */
1360 /* The CID driver stores subroutines with seed bytes. This */
1361 /* case is taken care of when decoder->subrs_len == 0. */
1362 zone->base = decoder->subrs[idx];
1363
1364 if ( decoder->subrs_len )
1365 zone->limit = zone->base + decoder->subrs_len[idx];
1366 else
1367 {
1368 /* We are using subroutines from a CID font. We must adjust */
1369 /* for the seed bytes. */
1370 zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
1371 zone->limit = decoder->subrs[idx + 1];
1372 }
1373
1374 zone->cursor = zone->base;
1375
1376 if ( !zone->base )
1377 {
1378 FT_ERROR(( "t1_decoder_parse_charstrings:"
1379 " invoking empty subrs\n" ));
1380 goto Syntax_Error;
1381 }
1382
1383 decoder->zone = zone;
1384 ip = zone->base;
1385 limit = zone->limit;
1386 break;
1387 }
1388
1389 case op_pop:
1390 FT_TRACE4(( " pop" ));
1391
1392 if ( known_othersubr_result_cnt > 0 )
1393 {
1394 known_othersubr_result_cnt--;
1395 /* ignore, we pushed the operands ourselves */
1396 break;
1397 }
1398
1399 if ( unknown_othersubr_result_cnt == 0 )
1400 {
1401 FT_ERROR(( "t1_decoder_parse_charstrings:"
1402 " no more operands for othersubr\n" ));
1403 goto Syntax_Error;
1404 }
1405
1406 unknown_othersubr_result_cnt--;
1407 top++; /* `push' the operand to callothersubr onto the stack */
1408 break;
1409
1410 case op_return:
1411 FT_TRACE4(( " return" ));
1412
1413 if ( zone <= decoder->zones )
1414 {
1415 FT_ERROR(( "t1_decoder_parse_charstrings:"
1416 " unexpected return\n" ));
1417 goto Syntax_Error;
1418 }
1419
1420 zone--;
1421 ip = zone->cursor;
1422 limit = zone->limit;
1423 decoder->zone = zone;
1424 break;
1425
1426 case op_dotsection:
1427 FT_TRACE4(( " dotsection" ));
1428
1429 break;
1430
1431 case op_hstem:
1432 FT_TRACE4(( " hstem" ));
1433
1434 /* record horizontal hint */
1435 if ( hinter )
1436 {
1437 /* top[0] += builder->left_bearing.y; */
1438 hinter->stem( hinter->hints, 1, top );
1439 }
1440 break;
1441
1442 case op_hstem3:
1443 FT_TRACE4(( " hstem3" ));
1444
1445 /* record horizontal counter-controlled hints */
1446 if ( hinter )
1447 hinter->stem3( hinter->hints, 1, top );
1448 break;
1449
1450 case op_vstem:
1451 FT_TRACE4(( " vstem" ));
1452
1453 /* record vertical hint */
1454 if ( hinter )
1455 {
1456 top[0] += orig_x;
1457 hinter->stem( hinter->hints, 0, top );
1458 }
1459 break;
1460
1461 case op_vstem3:
1462 FT_TRACE4(( " vstem3" ));
1463
1464 /* record vertical counter-controlled hints */
1465 if ( hinter )
1466 {
1467 FT_Pos dx = orig_x;
1468
1469
1470 top[0] += dx;
1471 top[2] += dx;
1472 top[4] += dx;
1473 hinter->stem3( hinter->hints, 0, top );
1474 }
1475 break;
1476
1477 case op_setcurrentpoint:
1478 FT_TRACE4(( " setcurrentpoint" ));
1479
1480 /* From the T1 specification, section 6.4: */
1481 /* */
1482 /* The setcurrentpoint command is used only in */
1483 /* conjunction with results from OtherSubrs procedures. */
1484
1485 /* known_othersubr_result_cnt != 0 is already handled */
1486 /* above. */
1487
1488 /* Note, however, that both Ghostscript and Adobe */
1489 /* Distiller handle this situation by silently ignoring */
1490 /* the inappropriate `setcurrentpoint' instruction. So */
1491 /* we do the same. */
1492 #if 0
1493
1494 if ( decoder->flex_state != 1 )
1495 {
1496 FT_ERROR(( "t1_decoder_parse_charstrings:"
1497 " unexpected `setcurrentpoint'\n" ));
1498 goto Syntax_Error;
1499 }
1500 else
1501 ...
1502 #endif
1503
1504 x = top[0];
1505 y = top[1];
1506 decoder->flex_state = 0;
1507 break;
1508
1509 case op_unknown15:
1510 FT_TRACE4(( " opcode_15" ));
1511 /* nothing to do except to pop the two arguments */
1512 break;
1513
1514 default:
1515 FT_ERROR(( "t1_decoder_parse_charstrings:"
1516 " unhandled opcode %d\n", op ));
1517 goto Syntax_Error;
1518 }
1519
1520 /* XXX Operators usually clear the operand stack; */
1521 /* only div, callsubr, callothersubr, pop, and */
1522 /* return are different. */
1523 /* In practice it doesn't matter (?). */
1524
1525 decoder->top = top;
1526
1527 #ifdef FT_DEBUG_LEVEL_TRACE
1528 FT_TRACE4(( "\n" ));
1529 bol = TRUE;
1530 #endif
1531
1532 } /* general operator processing */
1533
1534 } /* while ip < limit */
1535
1536 FT_TRACE4(( "..end..\n\n" ));
1537
1538 Fail:
1539 return error;
1540
1541 Syntax_Error:
1542 return PSaux_Err_Syntax_Error;
1543
1544 Stack_Underflow:
1545 return PSaux_Err_Stack_Underflow;
1546 }
1547
1548
1549 /* parse a single Type 1 glyph */
1550 FT_LOCAL_DEF( FT_Error )
1551 t1_decoder_parse_glyph( T1_Decoder decoder,
1552 FT_UInt glyph )
1553 {
1554 return decoder->parse_callback( decoder, glyph );
1555 }
1556
1557
1558 /* initialize T1 decoder */
1559 FT_LOCAL_DEF( FT_Error )
1560 t1_decoder_init( T1_Decoder decoder,
1561 FT_Face face,
1562 FT_Size size,
1563 FT_GlyphSlot slot,
1564 FT_Byte** glyph_names,
1565 PS_Blend blend,
1566 FT_Bool hinting,
1567 FT_Render_Mode hint_mode,
1568 T1_Decoder_Callback parse_callback )
1569 {
1570 FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
1571
1572 /* retrieve PSNames interface from list of current modules */
1573 {
1574 FT_Service_PsCMaps psnames = 0;
1575
1576
1577 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1578 if ( !psnames )
1579 {
1580 FT_ERROR(( "t1_decoder_init:"
1581 " the `psnames' module is not available\n" ));
1582 return PSaux_Err_Unimplemented_Feature;
1583 }
1584
1585 decoder->psnames = psnames;
1586 }
1587
1588 t1_builder_init( &decoder->builder, face, size, slot, hinting );
1589
1590 /* decoder->buildchar and decoder->len_buildchar have to be */
1591 /* initialized by the caller since we cannot know the length */
1592 /* of the BuildCharArray */
1593
1594 decoder->num_glyphs = (FT_UInt)face->num_glyphs;
1595 decoder->glyph_names = glyph_names;
1596 decoder->hint_mode = hint_mode;
1597 decoder->blend = blend;
1598 decoder->parse_callback = parse_callback;
1599
1600 decoder->funcs = t1_decoder_funcs;
1601
1602 return PSaux_Err_Ok;
1603 }
1604
1605
1606 /* finalize T1 decoder */
1607 FT_LOCAL_DEF( void )
1608 t1_decoder_done( T1_Decoder decoder )
1609 {
1610 t1_builder_done( &decoder->builder );
1611 }
1612
1613
1614 /* END */
T1_Decoder_ZoneRec_
Definition: psaux.h:617
FIXED_TO_INT
#define FIXED_TO_INT(x)
Definition: ftcalc.h:168
PSH_Globals
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:41
op_setcurrentpoint
Definition: t1decode.c:70
FT_SizeRec_
Definition: freetype.h:1395
FT_Error
int FT_Error
Definition: fttypes.h:296
FT_DivFix
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:536
FT_PtrDist
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
op_closepath
Definition: t1decode.c:50
FT_Long
signed long FT_Long
Definition: fttypes.h:238
T1_BuilderRec_
Definition: psaux.h:559
T1_Face
struct T1_FaceRec_ * T1_Face
Definition: t1types.h:194
FT_Pos
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
FT_GlyphSlotRec_
Definition: freetype.h:1605
T1_Hints_FuncsRec_
Definition: pshints.h:342
op_rmoveto
Definition: t1decode.c:55
t1_builder_done
t1_builder_done(T1_Builder builder)
Definition: psobjs.c:1523
t1_builder_add_point1
t1_builder_add_point1(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1568
FT_SubGlyphRec_
Definition: ftgloadr.h:57
FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3218
op_hsbw
Definition: t1decode.c:47
left
GLint left
Definition: glew.h:7291
FT_MEM_ZERO
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
FT_SUBGLYPH_FLAG_USE_MY_METRICS
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3223
op_hstem
Definition: t1decode.c:61
T1_Hints_FuncsRec_::reset
T1_Hints_ResetFunc reset
Definition: pshints.h:349
NULL
#define NULL
Definition: ftobjs.h:61
FT_Int
signed int FT_Int
Definition: fttypes.h:216
T1_Parse_Have_Moveto
Definition: psaux.h:505
FT_ULONG_MAX
#define FT_ULONG_MAX
Definition: ftstdlib.h:67
FT_Render_Mode
enum FT_Render_Mode_ FT_Render_Mode
T1_BuilderRec_::no_recurse
FT_Bool no_recurse
Definition: psaux.h:577
n
GLclampd n
Definition: glew.h:7287
op_vstem3
Definition: t1decode.c:64
t1_builder_start_point
t1_builder_start_point(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1620
op_vhcurveto
Definition: t1decode.c:57
x
EGLSurface EGLint x
Definition: eglext.h:293
T1_Parse_Have_Width
Definition: psaux.h:504
PostScript
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid character code cannot render this glyph format invalid composite glyph invalid pixel size invalid library handle invalid face handle invalid glyph slot handle invalid cache manager handle too many modules out of memory cannot open stream invalid stream skip invalid stream operation nested frame access raster uninitialized raster overflow too many registered caches too few arguments code overflow division by zero found debug opcode nested DEFS execution context too long too many instruction definitions horizontal name table missing horizontal PostScript(post) table missing" ) FT_ERRORDEF_( Invalid_Horiz_Metrics
op_hmoveto
Definition: t1decode.c:52
T1_Hints_FuncsRec_::close
T1_Hints_CloseFunc close
Definition: pshints.h:346
T1_DecoderRec_::num_glyphs
FT_UInt num_glyphs
Definition: psaux.h:670
T1_FaceRec_::root
FT_FaceRec root
Definition: t1types.h:200
T1_Hints_FuncsRec_::apply
T1_Hints_ApplyFunc apply
Definition: pshints.h:350
ft_memset
#define ft_memset
Definition: ftstdlib.h:83
FT_Outline_
Definition: ftimage.h:383
op_return
Definition: t1decode.c:69
T1_BuilderRec_::left_bearing
FT_Vector left_bearing
Definition: psaux.h:571
FT_FACE_FIND_GLOBAL_SERVICE
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:132
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
T1_Parse_Have_Path
Definition: psaux.h:506
Fix2Int
#define Fix2Int(f)
Definition: t1decode.c:31
op_none
Definition: t1decode.c:45
T1_Hints_FuncsRec_::hints
T1_Hints hints
Definition: pshints.h:344
T1_Operator
enum T1_Operator_ T1_Operator
T1_BuilderRec_::base
FT_Outline * base
Definition: psaux.h:565
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
FT_Bool
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
FT_FaceRec_::internal
FT_Face_Internal internal
Definition: freetype.h:964
T1_BuilderRec_::loader
FT_GlyphLoader loader
Definition: psaux.h:564
t1_decoder_init
t1_decoder_init(T1_Decoder decoder, FT_Face face, FT_Size size, FT_GlyphSlot slot, FT_Byte **glyph_names, PS_Blend blend, FT_Bool hinting, FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback)
Definition: t1decode.c:1560
T1_BuilderRec_::glyph
FT_GlyphSlot glyph
Definition: psaux.h:563
FT_GlyphLoader
typedefFT_BEGIN_HEADER struct FT_GlyphLoaderRec_ * FT_GlyphLoader
Definition: ftgloadr.h:43
FT_ERROR
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
T1_BuilderRec_::pos_y
FT_Pos pos_y
Definition: psaux.h:569
FT_Byte
unsigned char FT_Byte
Definition: fttypes.h:150
FT_ASSERT
#define FT_ASSERT(condition)
Definition: ftdebug.h:204
op_pop
Definition: t1decode.c:68
op_callsubr
Definition: t1decode.c:67
FT_TRACE4
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
t1_args_count
static const FT_Int t1_args_count[op_max]
Definition: t1decode.c:79
FT_GlyphLoader_Add
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:323
op_div
Definition: t1decode.c:65
PS_BlendRec_
Definition: t1tables.h:262
t1_decoder_funcs
FT_CALLBACK_TABLE_DEF const T1_Decoder_FuncsRec t1_decoder_funcs
Definition: psauxmod.c:74
T1_Hints_FuncsRec_::stem
T1_Hints_SetStemFunc stem
Definition: pshints.h:347
FT_LOCAL_DEF
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
psobjs.h
T1_DecoderRec_::builder
T1_BuilderRec builder
Definition: psaux.h:661
PS_BlendRec_::num_designs
FT_UInt num_designs
Definition: t1tables.h:264
FT_FaceRec_
Definition: freetype.h:912
FT_GlyphLoader_CheckSubGlyphs
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:276
idx
FT_UInt idx
Definition: cffcmap.c:125
op_sbw
Definition: t1decode.c:49
error
FT_Error error
Definition: cffdrivr.c:407
FT_GlyphSlotRec_::num_subglyphs
FT_UInt num_subglyphs
Definition: freetype.h:1626
psauxerr.h
FT_Vector_::x
FT_Pos x
Definition: ftimage.h:77
FT_TRACE0
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
op_max
Definition: t1decode.c:73
FT_String
char FT_String
Definition: fttypes.h:183
face
GLenum face
Definition: gl2ext.h:1490
T1_BuilderRec_::parse_state
T1_ParseState parse_state
Definition: psaux.h:575
T1_BuilderRec_::current
FT_Outline * current
Definition: psaux.h:566
FT_Vector_::y
FT_Pos y
Definition: ftimage.h:78
op_rlineto
Definition: t1decode.c:54
op_endchar
Definition: t1decode.c:46
t1_decoder_parse_charstrings
t1_decoder_parse_charstrings(T1_Decoder decoder, FT_Byte *charstring_base, FT_UInt charstring_len)
Definition: t1decode.c:355
T1_Operator_
T1_Operator_
Definition: t1decode.c:43
T1_Hints_FuncsRec_::open
T1_Hints_OpenFunc open
Definition: pshints.h:345
limit
GLint limit
Definition: glew.h:11829
FT_Slot_InternalRec_::loader
FT_GlyphLoader loader
Definition: ftobjs.h:380
FT_Vector_
Definition: ftimage.h:75
T1_DecoderRec_::psnames
FT_Service_PsCMaps psnames
Definition: psaux.h:669
FT_GlyphSlotRec_::subglyphs
FT_SubGlyph subglyphs
Definition: freetype.h:1627
top
GLfloat GLfloat GLfloat top
Definition: glew.h:13816
FALSE
#define FALSE
Definition: ftobjs.h:57
t1_builder_close_contour
t1_builder_close_contour(T1_Builder builder)
Definition: psobjs.c:1645
FT_Outline_::n_points
short n_points
Definition: ftimage.h:386
T1_FaceRec_
Definition: t1types.h:198
T1_MAX_CHARSTRINGS_OPERANDS
#define T1_MAX_CHARSTRINGS_OPERANDS
Definition: ftoption.h:694
T1_Decoder_Callback
FT_Error(* T1_Decoder_Callback)(T1_Decoder decoder, FT_UInt glyph_index)
Definition: psaux.h:631
op_hlineto
Definition: t1decode.c:51
op_vlineto
Definition: t1decode.c:58
op_hstem3
Definition: t1decode.c:62
sizeof
sizeof(FT_AutofitterRec)
y
EGLSurface EGLint EGLint y
Definition: eglext.h:293
FT_MulFix
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:435
T1_Decoder_ZoneRec_::limit
FT_Byte * limit
Definition: psaux.h:621
T1_Hints_Funcs
struct T1_Hints_FuncsRec_ * T1_Hints_Funcs
Definition: pshints.h:117
value
EGLSurface EGLint void ** value
Definition: eglext.h:301
T1_MAX_SUBRS_CALLS
#define T1_MAX_SUBRS_CALLS
Definition: ftoption.h:684
t1_decoder_parse_glyph
t1_decoder_parse_glyph(T1_Decoder decoder, FT_UInt glyph)
Definition: t1decode.c:1551
T1_BuilderRec_::metrics_only
FT_Bool metrics_only
Definition: psaux.h:579
ft2build.h
T1_BuilderRec_::pos_x
FT_Pos pos_x
Definition: psaux.h:568
FT_Fixed
signed long FT_Fixed
Definition: fttypes.h:284
FT_GlyphSlotRec_::format
FT_Glyph_Format format
Definition: freetype.h:1618
op_vstem
Definition: t1decode.c:63
T1_Decoder_ZoneRec_::base
FT_Byte * base
Definition: psaux.h:620
T1_DecoderRec_
Definition: psaux.h:659
FT_UInt
unsigned int FT_UInt
Definition: fttypes.h:227
FT_GlyphSlot
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:450
T1_BuilderRec_::face
FT_Face face
Definition: psaux.h:562
T1_BuilderRec_::hints_globals
void * hints_globals
Definition: psaux.h:582
t1_lookup_glyph_by_stdcharcode
static FT_Int t1_lookup_glyph_by_stdcharcode(T1_Decoder decoder, FT_Int charcode)
Definition: t1decode.c:130
FT_GlyphSlotRec_::internal
FT_Slot_Internal internal
Definition: freetype.h:1637
op_vmoveto
Definition: t1decode.c:59
FT_TRACE5
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
T1_DecoderRec_::glyph_names
FT_Byte ** glyph_names
Definition: psaux.h:671
t1_builder_add_point
t1_builder_add_point(T1_Builder builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1544
T1_BuilderRec_::advance
FT_Vector advance
Definition: psaux.h:572
t1decode.h
op_unknown15
Definition: t1decode.c:71
T1_BuilderRec_::hints_funcs
void * hints_funcs
Definition: psaux.h:581
FT_GlyphLoader_Prepare
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:307
PS_BlendRec_::weight_vector
FT_Fixed * weight_vector
Definition: t1tables.h:271
t1_builder_init
t1_builder_init(T1_Builder builder, FT_Face face, FT_Size size, FT_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1467
op_hvcurveto
Definition: t1decode.c:53
i
int i
Definition: pngrutil.c:1377
t1operator_seac
static FT_Error t1operator_seac(T1_Decoder decoder, FT_Pos asb, FT_Pos adx, FT_Pos ady, FT_Int bchar, FT_Int achar)
Definition: t1decode.c:185
T1_DecoderRec_::seac
FT_Bool seac
Definition: psaux.h:695
T1_Hints_FuncsRec_::stem3
T1_Hints_SetStem3Func stem3
Definition: pshints.h:348
T1_Decoder_ZoneRec_::cursor
FT_Byte * cursor
Definition: psaux.h:619
t1_decoder_done
t1_decoder_done(T1_Decoder decoder)
Definition: t1decode.c:1608
ft_memcpy
#define ft_memcpy
Definition: ftstdlib.h:81
FT_UNUSED
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
op_rrcurveto
Definition: t1decode.c:56
TRUE
#define TRUE
Definition: ftobjs.h:53
op_seac
Definition: t1decode.c:48
t1_builder_check_points
t1_builder_check_points(T1_Builder builder, FT_Int count)
Definition: psobjs.c:1535
values
GLint GLsizei const GLuint64 * values
Definition: glew.h:3473
op_callothersubr
Definition: t1decode.c:66
T1_Parse_Start
Definition: psaux.h:503
ft_strcmp
#define ft_strcmp
Definition: ftstdlib.h:85
size
GLsizei size
Definition: gl2ext.h:1467
op_dotsection
Definition: t1decode.c:60