1/****************************************************************************
2 *
3 * cffdecode.c
4 *
5 * PostScript CFF (Type 2) decoding routines (body).
6 *
7 * Copyright (C) 2017-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19#include <ft2build.h>
20#include FT_FREETYPE_H
21#include FT_INTERNAL_DEBUG_H
22#include FT_INTERNAL_SERVICE_H
23#include FT_SERVICE_CFF_TABLE_LOAD_H
24
25#include "cffdecode.h"
26#include "psobjs.h"
27
28#include "psauxerr.h"
29
30
31 /**************************************************************************
32 *
33 * The macro FT_COMPONENT is used in trace mode. It is an implicit
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35 * messages during execution.
36 */
37#undef FT_COMPONENT
38#define FT_COMPONENT cffdecode
39
40
41#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
42
43 typedef enum CFF_Operator_
44 {
45 cff_op_unknown = 0,
46
47 cff_op_rmoveto,
48 cff_op_hmoveto,
49 cff_op_vmoveto,
50
51 cff_op_rlineto,
52 cff_op_hlineto,
53 cff_op_vlineto,
54
55 cff_op_rrcurveto,
56 cff_op_hhcurveto,
57 cff_op_hvcurveto,
58 cff_op_rcurveline,
59 cff_op_rlinecurve,
60 cff_op_vhcurveto,
61 cff_op_vvcurveto,
62
63 cff_op_flex,
64 cff_op_hflex,
65 cff_op_hflex1,
66 cff_op_flex1,
67
68 cff_op_endchar,
69
70 cff_op_hstem,
71 cff_op_vstem,
72 cff_op_hstemhm,
73 cff_op_vstemhm,
74
75 cff_op_hintmask,
76 cff_op_cntrmask,
77 cff_op_dotsection, /* deprecated, acts as no-op */
78
79 cff_op_abs,
80 cff_op_add,
81 cff_op_sub,
82 cff_op_div,
83 cff_op_neg,
84 cff_op_random,
85 cff_op_mul,
86 cff_op_sqrt,
87
88 cff_op_blend,
89
90 cff_op_drop,
91 cff_op_exch,
92 cff_op_index,
93 cff_op_roll,
94 cff_op_dup,
95
96 cff_op_put,
97 cff_op_get,
98 cff_op_store,
99 cff_op_load,
100
101 cff_op_and,
102 cff_op_or,
103 cff_op_not,
104 cff_op_eq,
105 cff_op_ifelse,
106
107 cff_op_callsubr,
108 cff_op_callgsubr,
109 cff_op_return,
110
111 /* Type 1 opcodes: invalid but seen in real life */
112 cff_op_hsbw,
113 cff_op_closepath,
114 cff_op_callothersubr,
115 cff_op_pop,
116 cff_op_seac,
117 cff_op_sbw,
118 cff_op_setcurrentpoint,
119
120 /* do not remove */
121 cff_op_max
122
123 } CFF_Operator;
124
125
126#define CFF_COUNT_CHECK_WIDTH 0x80
127#define CFF_COUNT_EXACT 0x40
128#define CFF_COUNT_CLEAR_STACK 0x20
129
130 /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
131 /* used for checking the width and requested numbers of arguments */
132 /* only; they are set to zero afterwards */
133
134 /* the other two flags are informative only and unused currently */
135
136 static const FT_Byte cff_argument_counts[] =
137 {
138 0, /* unknown */
139
140 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
141 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
142 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
143
144 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
145 0 | CFF_COUNT_CLEAR_STACK,
146 0 | CFF_COUNT_CLEAR_STACK,
147
148 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
149 0 | CFF_COUNT_CLEAR_STACK,
150 0 | CFF_COUNT_CLEAR_STACK,
151 0 | CFF_COUNT_CLEAR_STACK,
152 0 | CFF_COUNT_CLEAR_STACK,
153 0 | CFF_COUNT_CLEAR_STACK,
154 0 | CFF_COUNT_CLEAR_STACK,
155
156 13, /* flex */
157 7,
158 9,
159 11,
160
161 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
162
163 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
164 2 | CFF_COUNT_CHECK_WIDTH,
165 2 | CFF_COUNT_CHECK_WIDTH,
166 2 | CFF_COUNT_CHECK_WIDTH,
167
168 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
169 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
170 0, /* dotsection */
171
172 1, /* abs */
173 2,
174 2,
175 2,
176 1,
177 0,
178 2,
179 1,
180
181 1, /* blend */
182
183 1, /* drop */
184 2,
185 1,
186 2,
187 1,
188
189 2, /* put */
190 1,
191 4,
192 3,
193
194 2, /* and */
195 2,
196 1,
197 2,
198 4,
199
200 1, /* callsubr */
201 1,
202 0,
203
204 2, /* hsbw */
205 0,
206 0,
207 0,
208 5, /* seac */
209 4, /* sbw */
210 2 /* setcurrentpoint */
211 };
212
213
214 static FT_Error
215 cff_operator_seac( CFF_Decoder* decoder,
216 FT_Pos asb,
217 FT_Pos adx,
218 FT_Pos ady,
219 FT_Int bchar,
220 FT_Int achar )
221 {
222 FT_Error error;
223 CFF_Builder* builder = &decoder->builder;
224 FT_Int bchar_index, achar_index;
225 TT_Face face = decoder->builder.face;
226 FT_Vector left_bearing, advance;
227 FT_Byte* charstring;
228 FT_ULong charstring_len;
229 FT_Pos glyph_width;
230
231
232 if ( decoder->seac )
233 {
234 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
235 return FT_THROW( Syntax_Error );
236 }
237
238 adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
239 ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
240
241#ifdef FT_CONFIG_OPTION_INCREMENTAL
242 /* Incremental fonts don't necessarily have valid charsets. */
243 /* They use the character code, not the glyph index, in this case. */
244 if ( face->root.internal->incremental_interface )
245 {
246 bchar_index = bchar;
247 achar_index = achar;
248 }
249 else
250#endif /* FT_CONFIG_OPTION_INCREMENTAL */
251 {
252 CFF_Font cff = (CFF_Font)(face->extra.data);
253
254
255 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
256 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
257 }
258
259 if ( bchar_index < 0 || achar_index < 0 )
260 {
261 FT_ERROR(( "cff_operator_seac:"
262 " invalid seac character code arguments\n" ));
263 return FT_THROW( Syntax_Error );
264 }
265
266 /* If we are trying to load a composite glyph, do not load the */
267 /* accent character and return the array of subglyphs. */
268 if ( builder->no_recurse )
269 {
270 FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
271 FT_GlyphLoader loader = glyph->internal->loader;
272 FT_SubGlyph subg;
273
274
275 /* reallocate subglyph array if necessary */
276 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
277 if ( error )
278 goto Exit;
279
280 subg = loader->current.subglyphs;
281
282 /* subglyph 0 = base character */
283 subg->index = bchar_index;
284 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
285 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
286 subg->arg1 = 0;
287 subg->arg2 = 0;
288 subg++;
289
290 /* subglyph 1 = accent character */
291 subg->index = achar_index;
292 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
293 subg->arg1 = (FT_Int)( adx >> 16 );
294 subg->arg2 = (FT_Int)( ady >> 16 );
295
296 /* set up remaining glyph fields */
297 glyph->num_subglyphs = 2;
298 glyph->subglyphs = loader->base.subglyphs;
299 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
300
301 loader->current.num_subglyphs = 2;
302 }
303
304 FT_GlyphLoader_Prepare( builder->loader );
305
306 /* First load `bchar' in builder */
307 error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index,
308 &charstring, &charstring_len );
309 if ( !error )
310 {
311 /* the seac operator must not be nested */
312 decoder->seac = TRUE;
313 error = cff_decoder_parse_charstrings( decoder, charstring,
314 charstring_len, 0 );
315 decoder->seac = FALSE;
316
317 decoder->free_glyph_callback( face, &charstring, charstring_len );
318
319 if ( error )
320 goto Exit;
321 }
322
323 /* Save the left bearing, advance and glyph width of the base */
324 /* character as they will be erased by the next load. */
325
326 left_bearing = builder->left_bearing;
327 advance = builder->advance;
328 glyph_width = decoder->glyph_width;
329
330 builder->left_bearing.x = 0;
331 builder->left_bearing.y = 0;
332
333 builder->pos_x = adx - asb;
334 builder->pos_y = ady;
335
336 /* Now load `achar' on top of the base outline. */
337 error = decoder->get_glyph_callback( face, (FT_UInt)achar_index,
338 &charstring, &charstring_len );
339 if ( !error )
340 {
341 /* the seac operator must not be nested */
342 decoder->seac = TRUE;
343 error = cff_decoder_parse_charstrings( decoder, charstring,
344 charstring_len, 0 );
345 decoder->seac = FALSE;
346
347 decoder->free_glyph_callback( face, &charstring, charstring_len );
348
349 if ( error )
350 goto Exit;
351 }
352
353 /* Restore the left side bearing, advance and glyph width */
354 /* of the base character. */
355 builder->left_bearing = left_bearing;
356 builder->advance = advance;
357 decoder->glyph_width = glyph_width;
358
359 builder->pos_x = 0;
360 builder->pos_y = 0;
361
362 Exit:
363 return error;
364 }
365
366#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
367
368
369 /*************************************************************************/
370 /*************************************************************************/
371 /*************************************************************************/
372 /********** *********/
373 /********** *********/
374 /********** GENERIC CHARSTRING PARSING *********/
375 /********** *********/
376 /********** *********/
377 /*************************************************************************/
378 /*************************************************************************/
379 /*************************************************************************/
380
381 /**************************************************************************
382 *
383 * @Function:
384 * cff_compute_bias
385 *
386 * @Description:
387 * Computes the bias value in dependence of the number of glyph
388 * subroutines.
389 *
390 * @Input:
391 * in_charstring_type ::
392 * The `CharstringType' value of the top DICT
393 * dictionary.
394 *
395 * num_subrs ::
396 * The number of glyph subroutines.
397 *
398 * @Return:
399 * The bias value.
400 */
401 static FT_Int
402 cff_compute_bias( FT_Int in_charstring_type,
403 FT_UInt num_subrs )
404 {
405 FT_Int result;
406
407
408 if ( in_charstring_type == 1 )
409 result = 0;
410 else if ( num_subrs < 1240 )
411 result = 107;
412 else if ( num_subrs < 33900U )
413 result = 1131;
414 else
415 result = 32768U;
416
417 return result;
418 }
419
420
421 FT_LOCAL_DEF( FT_Int )
422 cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
423 FT_Int charcode )
424 {
425 FT_UInt n;
426 FT_UShort glyph_sid;
427
428 FT_Service_CFFLoad cffload;
429
430
431 /* CID-keyed fonts don't have glyph names */
432 if ( !cff->charset.sids )
433 return -1;
434
435 /* check range of standard char code */
436 if ( charcode < 0 || charcode > 255 )
437 return -1;
438
439#if 0
440 /* retrieve cffload from list of current modules */
441 FT_Service_CFFLoad cffload;
442
443
444 FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
445 if ( !cffload )
446 {
447 FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:"
448 " the `cffload' module is not available\n" ));
449 return FT_THROW( Unimplemented_Feature );
450 }
451#endif
452
453 cffload = (FT_Service_CFFLoad)cff->cffload;
454
455 /* Get code to SID mapping from `cff_standard_encoding'. */
456 glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
457
458 for ( n = 0; n < cff->num_glyphs; n++ )
459 {
460 if ( cff->charset.sids[n] == glyph_sid )
461 return (FT_Int)n;
462 }
463
464 return -1;
465 }
466
467
468#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
469
470 /**************************************************************************
471 *
472 * @Function:
473 * cff_decoder_parse_charstrings
474 *
475 * @Description:
476 * Parses a given Type 2 charstrings program.
477 *
478 * @InOut:
479 * decoder ::
480 * The current Type 1 decoder.
481 *
482 * @Input:
483 * charstring_base ::
484 * The base of the charstring stream.
485 *
486 * charstring_len ::
487 * The length in bytes of the charstring stream.
488 *
489 * in_dict ::
490 * Set to 1 if function is called from top or
491 * private DICT (needed for Multiple Master CFFs).
492 *
493 * @Return:
494 * FreeType error code. 0 means success.
495 */
496 FT_LOCAL_DEF( FT_Error )
497 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
498 FT_Byte* charstring_base,
499 FT_ULong charstring_len,
500 FT_Bool in_dict )
501 {
502 FT_Error error;
503 CFF_Decoder_Zone* zone;
504 FT_Byte* ip;
505 FT_Byte* limit;
506 CFF_Builder* builder = &decoder->builder;
507 FT_Pos x, y;
508 FT_Fixed* stack;
509 FT_Int charstring_type =
510 decoder->cff->top_font.font_dict.charstring_type;
511 FT_UShort num_designs =
512 decoder->cff->top_font.font_dict.num_designs;
513 FT_UShort num_axes =
514 decoder->cff->top_font.font_dict.num_axes;
515
516 T2_Hints_Funcs hinter;
517
518
519 /* set default width */
520 decoder->num_hints = 0;
521 decoder->read_width = 1;
522
523 /* initialize the decoder */
524 decoder->top = decoder->stack;
525 decoder->zone = decoder->zones;
526 zone = decoder->zones;
527 stack = decoder->top;
528
529 hinter = (T2_Hints_Funcs)builder->hints_funcs;
530
531 builder->path_begun = 0;
532
533 zone->base = charstring_base;
534 limit = zone->limit = charstring_base + charstring_len;
535 ip = zone->cursor = zone->base;
536
537 error = FT_Err_Ok;
538
539 x = builder->pos_x;
540 y = builder->pos_y;
541
542 /* begin hints recording session, if any */
543 if ( hinter )
544 hinter->open( hinter->hints );
545
546 /* now execute loop */
547 while ( ip < limit )
548 {
549 CFF_Operator op;
550 FT_Byte v;
551
552
553 /*********************************************************************
554 *
555 * Decode operator or operand
556 */
557 v = *ip++;
558 if ( v >= 32 || v == 28 )
559 {
560 FT_Int shift = 16;
561 FT_Int32 val;
562
563
564 /* this is an operand, push it on the stack */
565
566 /* if we use shifts, all computations are done with unsigned */
567 /* values; the conversion to a signed value is the last step */
568 if ( v == 28 )
569 {
570 if ( ip + 1 >= limit )
571 goto Syntax_Error;
572 val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
573 ip += 2;
574 }
575 else if ( v < 247 )
576 val = (FT_Int32)v - 139;
577 else if ( v < 251 )
578 {
579 if ( ip >= limit )
580 goto Syntax_Error;
581 val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
582 }
583 else if ( v < 255 )
584 {
585 if ( ip >= limit )
586 goto Syntax_Error;
587 val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
588 }
589 else
590 {
591 if ( ip + 3 >= limit )
592 goto Syntax_Error;
593 val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
594 ( (FT_UInt32)ip[1] << 16 ) |
595 ( (FT_UInt32)ip[2] << 8 ) |
596 (FT_UInt32)ip[3] );
597 ip += 4;
598 if ( charstring_type == 2 )
599 shift = 0;
600 }
601 if ( decoder->top - stack >= CFF_MAX_OPERANDS )
602 goto Stack_Overflow;
603
604 val = (FT_Int32)( (FT_UInt32)val << shift );
605 *decoder->top++ = val;
606
607#ifdef FT_DEBUG_LEVEL_TRACE
608 if ( !( val & 0xFFFFL ) )
609 FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
610 else
611 FT_TRACE4(( " %.5f", val / 65536.0 ));
612#endif
613
614 }
615 else
616 {
617 /* The specification says that normally arguments are to be taken */
618 /* from the bottom of the stack. However, this seems not to be */
619 /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
620 /* arguments similar to a PS interpreter. */
621
622 FT_Fixed* args = decoder->top;
623 FT_Int num_args = (FT_Int)( args - decoder->stack );
624 FT_Int req_args;
625
626
627 /* find operator */
628 op = cff_op_unknown;
629
630 switch ( v )
631 {
632 case 1:
633 op = cff_op_hstem;
634 break;
635 case 3:
636 op = cff_op_vstem;
637 break;
638 case 4:
639 op = cff_op_vmoveto;
640 break;
641 case 5:
642 op = cff_op_rlineto;
643 break;
644 case 6:
645 op = cff_op_hlineto;
646 break;
647 case 7:
648 op = cff_op_vlineto;
649 break;
650 case 8:
651 op = cff_op_rrcurveto;
652 break;
653 case 9:
654 op = cff_op_closepath;
655 break;
656 case 10:
657 op = cff_op_callsubr;
658 break;
659 case 11:
660 op = cff_op_return;
661 break;
662 case 12:
663 if ( ip >= limit )
664 goto Syntax_Error;
665 v = *ip++;
666
667 switch ( v )
668 {
669 case 0:
670 op = cff_op_dotsection;
671 break;
672 case 1: /* this is actually the Type1 vstem3 operator */
673 op = cff_op_vstem;
674 break;
675 case 2: /* this is actually the Type1 hstem3 operator */
676 op = cff_op_hstem;
677 break;
678 case 3:
679 op = cff_op_and;
680 break;
681 case 4:
682 op = cff_op_or;
683 break;
684 case 5:
685 op = cff_op_not;
686 break;
687 case 6:
688 op = cff_op_seac;
689 break;
690 case 7:
691 op = cff_op_sbw;
692 break;
693 case 8:
694 op = cff_op_store;
695 break;
696 case 9:
697 op = cff_op_abs;
698 break;
699 case 10:
700 op = cff_op_add;
701 break;
702 case 11:
703 op = cff_op_sub;
704 break;
705 case 12:
706 op = cff_op_div;
707 break;
708 case 13:
709 op = cff_op_load;
710 break;
711 case 14:
712 op = cff_op_neg;
713 break;
714 case 15:
715 op = cff_op_eq;
716 break;
717 case 16:
718 op = cff_op_callothersubr;
719 break;
720 case 17:
721 op = cff_op_pop;
722 break;
723 case 18:
724 op = cff_op_drop;
725 break;
726 case 20:
727 op = cff_op_put;
728 break;
729 case 21:
730 op = cff_op_get;
731 break;
732 case 22:
733 op = cff_op_ifelse;
734 break;
735 case 23:
736 op = cff_op_random;
737 break;
738 case 24:
739 op = cff_op_mul;
740 break;
741 case 26:
742 op = cff_op_sqrt;
743 break;
744 case 27:
745 op = cff_op_dup;
746 break;
747 case 28:
748 op = cff_op_exch;
749 break;
750 case 29:
751 op = cff_op_index;
752 break;
753 case 30:
754 op = cff_op_roll;
755 break;
756 case 33:
757 op = cff_op_setcurrentpoint;
758 break;
759 case 34:
760 op = cff_op_hflex;
761 break;
762 case 35:
763 op = cff_op_flex;
764 break;
765 case 36:
766 op = cff_op_hflex1;
767 break;
768 case 37:
769 op = cff_op_flex1;
770 break;
771 default:
772 FT_TRACE4(( " unknown op (12, %d)\n", v ));
773 break;
774 }
775 break;
776 case 13:
777 op = cff_op_hsbw;
778 break;
779 case 14:
780 op = cff_op_endchar;
781 break;
782 case 16:
783 op = cff_op_blend;
784 break;
785 case 18:
786 op = cff_op_hstemhm;
787 break;
788 case 19:
789 op = cff_op_hintmask;
790 break;
791 case 20:
792 op = cff_op_cntrmask;
793 break;
794 case 21:
795 op = cff_op_rmoveto;
796 break;
797 case 22:
798 op = cff_op_hmoveto;
799 break;
800 case 23:
801 op = cff_op_vstemhm;
802 break;
803 case 24:
804 op = cff_op_rcurveline;
805 break;
806 case 25:
807 op = cff_op_rlinecurve;
808 break;
809 case 26:
810 op = cff_op_vvcurveto;
811 break;
812 case 27:
813 op = cff_op_hhcurveto;
814 break;
815 case 29:
816 op = cff_op_callgsubr;
817 break;
818 case 30:
819 op = cff_op_vhcurveto;
820 break;
821 case 31:
822 op = cff_op_hvcurveto;
823 break;
824 default:
825 FT_TRACE4(( " unknown op (%d)\n", v ));
826 break;
827 }
828
829 if ( op == cff_op_unknown )
830 continue;
831
832 /* in Multiple Master CFFs, T2 charstrings can appear in */
833 /* dictionaries, but some operators are prohibited */
834 if ( in_dict )
835 {
836 switch ( op )
837 {
838 case cff_op_hstem:
839 case cff_op_vstem:
840 case cff_op_vmoveto:
841 case cff_op_rlineto:
842 case cff_op_hlineto:
843 case cff_op_vlineto:
844 case cff_op_rrcurveto:
845 case cff_op_hstemhm:
846 case cff_op_hintmask:
847 case cff_op_cntrmask:
848 case cff_op_rmoveto:
849 case cff_op_hmoveto:
850 case cff_op_vstemhm:
851 case cff_op_rcurveline:
852 case cff_op_rlinecurve:
853 case cff_op_vvcurveto:
854 case cff_op_hhcurveto:
855 case cff_op_vhcurveto:
856 case cff_op_hvcurveto:
857 case cff_op_hflex:
858 case cff_op_flex:
859 case cff_op_hflex1:
860 case cff_op_flex1:
861 case cff_op_callsubr:
862 case cff_op_callgsubr:
863 /* deprecated opcodes */
864 case cff_op_dotsection:
865 /* invalid Type 1 opcodes */
866 case cff_op_hsbw:
867 case cff_op_closepath:
868 case cff_op_callothersubr:
869 case cff_op_seac:
870 case cff_op_sbw:
871 case cff_op_setcurrentpoint:
872 goto MM_Error;
873
874 default:
875 break;
876 }
877 }
878
879 /* check arguments */
880 req_args = cff_argument_counts[op];
881 if ( req_args & CFF_COUNT_CHECK_WIDTH )
882 {
883 if ( num_args > 0 && decoder->read_width )
884 {
885 /* If `nominal_width' is non-zero, the number is really a */
886 /* difference against `nominal_width'. Else, the number here */
887 /* is truly a width, not a difference against `nominal_width'. */
888 /* If the font does not set `nominal_width', then */
889 /* `nominal_width' defaults to zero, and so we can set */
890 /* `glyph_width' to `nominal_width' plus number on the stack */
891 /* -- for either case. */
892
893 FT_Int set_width_ok;
894
895
896 switch ( op )
897 {
898 case cff_op_hmoveto:
899 case cff_op_vmoveto:
900 set_width_ok = num_args & 2;
901 break;
902
903 case cff_op_hstem:
904 case cff_op_vstem:
905 case cff_op_hstemhm:
906 case cff_op_vstemhm:
907 case cff_op_rmoveto:
908 case cff_op_hintmask:
909 case cff_op_cntrmask:
910 set_width_ok = num_args & 1;
911 break;
912
913 case cff_op_endchar:
914 /* If there is a width specified for endchar, we either have */
915 /* 1 argument or 5 arguments. We like to argue. */
916 set_width_ok = in_dict
917 ? 0
918 : ( ( num_args == 5 ) || ( num_args == 1 ) );
919 break;
920
921 default:
922 set_width_ok = 0;
923 break;
924 }
925
926 if ( set_width_ok )
927 {
928 decoder->glyph_width = decoder->nominal_width +
929 ( stack[0] >> 16 );
930
931 if ( decoder->width_only )
932 {
933 /* we only want the advance width; stop here */
934 break;
935 }
936
937 /* Consumed an argument. */
938 num_args--;
939 }
940 }
941
942 decoder->read_width = 0;
943 req_args = 0;
944 }
945
946 req_args &= 0x000F;
947 if ( num_args < req_args )
948 goto Stack_Underflow;
949 args -= req_args;
950 num_args -= req_args;
951
952 /* At this point, `args' points to the first argument of the */
953 /* operand in case `req_args' isn't zero. Otherwise, we have */
954 /* to adjust `args' manually. */
955
956 /* Note that we only pop arguments from the stack which we */
957 /* really need and can digest so that we can continue in case */
958 /* of superfluous stack elements. */
959
960 switch ( op )
961 {
962 case cff_op_hstem:
963 case cff_op_vstem:
964 case cff_op_hstemhm:
965 case cff_op_vstemhm:
966 /* the number of arguments is always even here */
967 FT_TRACE4(( "%s\n",
968 op == cff_op_hstem ? " hstem" :
969 ( op == cff_op_vstem ? " vstem" :
970 ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
971
972 if ( hinter )
973 hinter->stems( hinter->hints,
974 ( op == cff_op_hstem || op == cff_op_hstemhm ),
975 num_args / 2,
976 args - ( num_args & ~1 ) );
977
978 decoder->num_hints += num_args / 2;
979 args = stack;
980 break;
981
982 case cff_op_hintmask:
983 case cff_op_cntrmask:
984 FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
985 : " cntrmask" ));
986
987 /* implement vstem when needed -- */
988 /* the specification doesn't say it, but this also works */
989 /* with the 'cntrmask' operator */
990 /* */
991 if ( num_args > 0 )
992 {
993 if ( hinter )
994 hinter->stems( hinter->hints,
995 0,
996 num_args / 2,
997 args - ( num_args & ~1 ) );
998
999 decoder->num_hints += num_args / 2;
1000 }
1001
1002 /* In a valid charstring there must be at least one byte */
1003 /* after `hintmask' or `cntrmask' (e.g., for a `return' */
1004 /* instruction). Additionally, there must be space for */
1005 /* `num_hints' bits. */
1006
1007 if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
1008 goto Syntax_Error;
1009
1010 if ( hinter )
1011 {
1012 if ( op == cff_op_hintmask )
1013 hinter->hintmask( hinter->hints,
1014 (FT_UInt)builder->current->n_points,
1015 (FT_UInt)decoder->num_hints,
1016 ip );
1017 else
1018 hinter->counter( hinter->hints,
1019 (FT_UInt)decoder->num_hints,
1020 ip );
1021 }
1022
1023#ifdef FT_DEBUG_LEVEL_TRACE
1024 {
1025 FT_UInt maskbyte;
1026
1027
1028 FT_TRACE4(( " (maskbytes:" ));
1029
1030 for ( maskbyte = 0;
1031 maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1032 maskbyte++, ip++ )
1033 FT_TRACE4(( " 0x%02X", *ip ));
1034
1035 FT_TRACE4(( ")\n" ));
1036 }
1037#else
1038 ip += ( decoder->num_hints + 7 ) >> 3;
1039#endif
1040 args = stack;
1041 break;
1042
1043 case cff_op_rmoveto:
1044 FT_TRACE4(( " rmoveto\n" ));
1045
1046 cff_builder_close_contour( builder );
1047 builder->path_begun = 0;
1048 x = ADD_LONG( x, args[-2] );
1049 y = ADD_LONG( y, args[-1] );
1050 args = stack;
1051 break;
1052
1053 case cff_op_vmoveto:
1054 FT_TRACE4(( " vmoveto\n" ));
1055
1056 cff_builder_close_contour( builder );
1057 builder->path_begun = 0;
1058 y = ADD_LONG( y, args[-1] );
1059 args = stack;
1060 break;
1061
1062 case cff_op_hmoveto:
1063 FT_TRACE4(( " hmoveto\n" ));
1064
1065 cff_builder_close_contour( builder );
1066 builder->path_begun = 0;
1067 x = ADD_LONG( x, args[-1] );
1068 args = stack;
1069 break;
1070
1071 case cff_op_rlineto:
1072 FT_TRACE4(( " rlineto\n" ));
1073
1074 if ( cff_builder_start_point( builder, x, y ) ||
1075 cff_check_points( builder, num_args / 2 ) )
1076 goto Fail;
1077
1078 if ( num_args < 2 )
1079 goto Stack_Underflow;
1080
1081 args -= num_args & ~1;
1082 while ( args < decoder->top )
1083 {
1084 x = ADD_LONG( x, args[0] );
1085 y = ADD_LONG( y, args[1] );
1086 cff_builder_add_point( builder, x, y, 1 );
1087 args += 2;
1088 }
1089 args = stack;
1090 break;
1091
1092 case cff_op_hlineto:
1093 case cff_op_vlineto:
1094 {
1095 FT_Int phase = ( op == cff_op_hlineto );
1096
1097
1098 FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
1099 : " vlineto" ));
1100
1101 if ( num_args < 0 )
1102 goto Stack_Underflow;
1103
1104 /* there exist subsetted fonts (found in PDFs) */
1105 /* which call `hlineto' without arguments */
1106 if ( num_args == 0 )
1107 break;
1108
1109 if ( cff_builder_start_point( builder, x, y ) ||
1110 cff_check_points( builder, num_args ) )
1111 goto Fail;
1112
1113 args = stack;
1114 while ( args < decoder->top )
1115 {
1116 if ( phase )
1117 x = ADD_LONG( x, args[0] );
1118 else
1119 y = ADD_LONG( y, args[0] );
1120
1121 if ( cff_builder_add_point1( builder, x, y ) )
1122 goto Fail;
1123
1124 args++;
1125 phase ^= 1;
1126 }
1127 args = stack;
1128 }
1129 break;
1130
1131 case cff_op_rrcurveto:
1132 {
1133 FT_Int nargs;
1134
1135
1136 FT_TRACE4(( " rrcurveto\n" ));
1137
1138 if ( num_args < 6 )
1139 goto Stack_Underflow;
1140
1141 nargs = num_args - num_args % 6;
1142
1143 if ( cff_builder_start_point( builder, x, y ) ||
1144 cff_check_points( builder, nargs / 2 ) )
1145 goto Fail;
1146
1147 args -= nargs;
1148 while ( args < decoder->top )
1149 {
1150 x = ADD_LONG( x, args[0] );
1151 y = ADD_LONG( y, args[1] );
1152 cff_builder_add_point( builder, x, y, 0 );
1153
1154 x = ADD_LONG( x, args[2] );
1155 y = ADD_LONG( y, args[3] );
1156 cff_builder_add_point( builder, x, y, 0 );
1157
1158 x = ADD_LONG( x, args[4] );
1159 y = ADD_LONG( y, args[5] );
1160 cff_builder_add_point( builder, x, y, 1 );
1161
1162 args += 6;
1163 }
1164 args = stack;
1165 }
1166 break;
1167
1168 case cff_op_vvcurveto:
1169 {
1170 FT_Int nargs;
1171
1172
1173 FT_TRACE4(( " vvcurveto\n" ));
1174
1175 if ( num_args < 4 )
1176 goto Stack_Underflow;
1177
1178 /* if num_args isn't of the form 4n or 4n+1, */
1179 /* we enforce it by clearing the second bit */
1180
1181 nargs = num_args & ~2;
1182
1183 if ( cff_builder_start_point( builder, x, y ) )
1184 goto Fail;
1185
1186 args -= nargs;
1187
1188 if ( nargs & 1 )
1189 {
1190 x = ADD_LONG( x, args[0] );
1191 args++;
1192 nargs--;
1193 }
1194
1195 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1196 goto Fail;
1197
1198 while ( args < decoder->top )
1199 {
1200 y = ADD_LONG( y, args[0] );
1201 cff_builder_add_point( builder, x, y, 0 );
1202
1203 x = ADD_LONG( x, args[1] );
1204 y = ADD_LONG( y, args[2] );
1205 cff_builder_add_point( builder, x, y, 0 );
1206
1207 y = ADD_LONG( y, args[3] );
1208 cff_builder_add_point( builder, x, y, 1 );
1209
1210 args += 4;
1211 }
1212 args = stack;
1213 }
1214 break;
1215
1216 case cff_op_hhcurveto:
1217 {
1218 FT_Int nargs;
1219
1220
1221 FT_TRACE4(( " hhcurveto\n" ));
1222
1223 if ( num_args < 4 )
1224 goto Stack_Underflow;
1225
1226 /* if num_args isn't of the form 4n or 4n+1, */
1227 /* we enforce it by clearing the second bit */
1228
1229 nargs = num_args & ~2;
1230
1231 if ( cff_builder_start_point( builder, x, y ) )
1232 goto Fail;
1233
1234 args -= nargs;
1235 if ( nargs & 1 )
1236 {
1237 y = ADD_LONG( y, args[0] );
1238 args++;
1239 nargs--;
1240 }
1241
1242 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1243 goto Fail;
1244
1245 while ( args < decoder->top )
1246 {
1247 x = ADD_LONG( x, args[0] );
1248 cff_builder_add_point( builder, x, y, 0 );
1249
1250 x = ADD_LONG( x, args[1] );
1251 y = ADD_LONG( y, args[2] );
1252 cff_builder_add_point( builder, x, y, 0 );
1253
1254 x = ADD_LONG( x, args[3] );
1255 cff_builder_add_point( builder, x, y, 1 );
1256
1257 args += 4;
1258 }
1259 args = stack;
1260 }
1261 break;
1262
1263 case cff_op_vhcurveto:
1264 case cff_op_hvcurveto:
1265 {
1266 FT_Int phase;
1267 FT_Int nargs;
1268
1269
1270 FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
1271 : " hvcurveto" ));
1272
1273 if ( cff_builder_start_point( builder, x, y ) )
1274 goto Fail;
1275
1276 if ( num_args < 4 )
1277 goto Stack_Underflow;
1278
1279 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1280 /* we enforce it by clearing the second bit */
1281
1282 nargs = num_args & ~2;
1283
1284 args -= nargs;
1285 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1286 goto Stack_Underflow;
1287
1288 phase = ( op == cff_op_hvcurveto );
1289
1290 while ( nargs >= 4 )
1291 {
1292 nargs -= 4;
1293 if ( phase )
1294 {
1295 x = ADD_LONG( x, args[0] );
1296 cff_builder_add_point( builder, x, y, 0 );
1297
1298 x = ADD_LONG( x, args[1] );
1299 y = ADD_LONG( y, args[2] );
1300 cff_builder_add_point( builder, x, y, 0 );
1301
1302 y = ADD_LONG( y, args[3] );
1303 if ( nargs == 1 )
1304 x = ADD_LONG( x, args[4] );
1305 cff_builder_add_point( builder, x, y, 1 );
1306 }
1307 else
1308 {
1309 y = ADD_LONG( y, args[0] );
1310 cff_builder_add_point( builder, x, y, 0 );
1311
1312 x = ADD_LONG( x, args[1] );
1313 y = ADD_LONG( y, args[2] );
1314 cff_builder_add_point( builder, x, y, 0 );
1315
1316 x = ADD_LONG( x, args[3] );
1317 if ( nargs == 1 )
1318 y = ADD_LONG( y, args[4] );
1319 cff_builder_add_point( builder, x, y, 1 );
1320 }
1321 args += 4;
1322 phase ^= 1;
1323 }
1324 args = stack;
1325 }
1326 break;
1327
1328 case cff_op_rlinecurve:
1329 {
1330 FT_Int num_lines;
1331 FT_Int nargs;
1332
1333
1334 FT_TRACE4(( " rlinecurve\n" ));
1335
1336 if ( num_args < 8 )
1337 goto Stack_Underflow;
1338
1339 nargs = num_args & ~1;
1340 num_lines = ( nargs - 6 ) / 2;
1341
1342 if ( cff_builder_start_point( builder, x, y ) ||
1343 cff_check_points( builder, num_lines + 3 ) )
1344 goto Fail;
1345
1346 args -= nargs;
1347
1348 /* first, add the line segments */
1349 while ( num_lines > 0 )
1350 {
1351 x = ADD_LONG( x, args[0] );
1352 y = ADD_LONG( y, args[1] );
1353 cff_builder_add_point( builder, x, y, 1 );
1354
1355 args += 2;
1356 num_lines--;
1357 }
1358
1359 /* then the curve */
1360 x = ADD_LONG( x, args[0] );
1361 y = ADD_LONG( y, args[1] );
1362 cff_builder_add_point( builder, x, y, 0 );
1363
1364 x = ADD_LONG( x, args[2] );
1365 y = ADD_LONG( y, args[3] );
1366 cff_builder_add_point( builder, x, y, 0 );
1367
1368 x = ADD_LONG( x, args[4] );
1369 y = ADD_LONG( y, args[5] );
1370 cff_builder_add_point( builder, x, y, 1 );
1371
1372 args = stack;
1373 }
1374 break;
1375
1376 case cff_op_rcurveline:
1377 {
1378 FT_Int num_curves;
1379 FT_Int nargs;
1380
1381
1382 FT_TRACE4(( " rcurveline\n" ));
1383
1384 if ( num_args < 8 )
1385 goto Stack_Underflow;
1386
1387 nargs = num_args - 2;
1388 nargs = nargs - nargs % 6 + 2;
1389 num_curves = ( nargs - 2 ) / 6;
1390
1391 if ( cff_builder_start_point( builder, x, y ) ||
1392 cff_check_points( builder, num_curves * 3 + 2 ) )
1393 goto Fail;
1394
1395 args -= nargs;
1396
1397 /* first, add the curves */
1398 while ( num_curves > 0 )
1399 {
1400 x = ADD_LONG( x, args[0] );
1401 y = ADD_LONG( y, args[1] );
1402 cff_builder_add_point( builder, x, y, 0 );
1403
1404 x = ADD_LONG( x, args[2] );
1405 y = ADD_LONG( y, args[3] );
1406 cff_builder_add_point( builder, x, y, 0 );
1407
1408 x = ADD_LONG( x, args[4] );
1409 y = ADD_LONG( y, args[5] );
1410 cff_builder_add_point( builder, x, y, 1 );
1411
1412 args += 6;
1413 num_curves--;
1414 }
1415
1416 /* then the final line */
1417 x = ADD_LONG( x, args[0] );
1418 y = ADD_LONG( y, args[1] );
1419 cff_builder_add_point( builder, x, y, 1 );
1420
1421 args = stack;
1422 }
1423 break;
1424
1425 case cff_op_hflex1:
1426 {
1427 FT_Pos start_y;
1428
1429
1430 FT_TRACE4(( " hflex1\n" ));
1431
1432 /* adding five more points: 4 control points, 1 on-curve point */
1433 /* -- make sure we have enough space for the start point if it */
1434 /* needs to be added */
1435 if ( cff_builder_start_point( builder, x, y ) ||
1436 cff_check_points( builder, 6 ) )
1437 goto Fail;
1438
1439 /* record the starting point's y position for later use */
1440 start_y = y;
1441
1442 /* first control point */
1443 x = ADD_LONG( x, args[0] );
1444 y = ADD_LONG( y, args[1] );
1445 cff_builder_add_point( builder, x, y, 0 );
1446
1447 /* second control point */
1448 x = ADD_LONG( x, args[2] );
1449 y = ADD_LONG( y, args[3] );
1450 cff_builder_add_point( builder, x, y, 0 );
1451
1452 /* join point; on curve, with y-value the same as the last */
1453 /* control point's y-value */
1454 x = ADD_LONG( x, args[4] );
1455 cff_builder_add_point( builder, x, y, 1 );
1456
1457 /* third control point, with y-value the same as the join */
1458 /* point's y-value */
1459 x = ADD_LONG( x, args[5] );
1460 cff_builder_add_point( builder, x, y, 0 );
1461
1462 /* fourth control point */
1463 x = ADD_LONG( x, args[6] );
1464 y = ADD_LONG( y, args[7] );
1465 cff_builder_add_point( builder, x, y, 0 );
1466
1467 /* ending point, with y-value the same as the start */
1468 x = ADD_LONG( x, args[8] );
1469 y = start_y;
1470 cff_builder_add_point( builder, x, y, 1 );
1471
1472 args = stack;
1473 break;
1474 }
1475
1476 case cff_op_hflex:
1477 {
1478 FT_Pos start_y;
1479
1480
1481 FT_TRACE4(( " hflex\n" ));
1482
1483 /* adding six more points; 4 control points, 2 on-curve points */
1484 if ( cff_builder_start_point( builder, x, y ) ||
1485 cff_check_points( builder, 6 ) )
1486 goto Fail;
1487
1488 /* record the starting point's y-position for later use */
1489 start_y = y;
1490
1491 /* first control point */
1492 x = ADD_LONG( x, args[0] );
1493 cff_builder_add_point( builder, x, y, 0 );
1494
1495 /* second control point */
1496 x = ADD_LONG( x, args[1] );
1497 y = ADD_LONG( y, args[2] );
1498 cff_builder_add_point( builder, x, y, 0 );
1499
1500 /* join point; on curve, with y-value the same as the last */
1501 /* control point's y-value */
1502 x = ADD_LONG( x, args[3] );
1503 cff_builder_add_point( builder, x, y, 1 );
1504
1505 /* third control point, with y-value the same as the join */
1506 /* point's y-value */
1507 x = ADD_LONG( x, args[4] );
1508 cff_builder_add_point( builder, x, y, 0 );
1509
1510 /* fourth control point */
1511 x = ADD_LONG( x, args[5] );
1512 y = start_y;
1513 cff_builder_add_point( builder, x, y, 0 );
1514
1515 /* ending point, with y-value the same as the start point's */
1516 /* y-value -- we don't add this point, though */
1517 x = ADD_LONG( x, args[6] );
1518 cff_builder_add_point( builder, x, y, 1 );
1519
1520 args = stack;
1521 break;
1522 }
1523
1524 case cff_op_flex1:
1525 {
1526 FT_Pos start_x, start_y; /* record start x, y values for */
1527 /* alter use */
1528 FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
1529 /* algorithm below */
1530 FT_Int horizontal, count;
1531 FT_Fixed* temp;
1532
1533
1534 FT_TRACE4(( " flex1\n" ));
1535
1536 /* adding six more points; 4 control points, 2 on-curve points */
1537 if ( cff_builder_start_point( builder, x, y ) ||
1538 cff_check_points( builder, 6 ) )
1539 goto Fail;
1540
1541 /* record the starting point's x, y position for later use */
1542 start_x = x;
1543 start_y = y;
1544
1545 /* XXX: figure out whether this is supposed to be a horizontal */
1546 /* or vertical flex; the Type 2 specification is vague... */
1547
1548 temp = args;
1549
1550 /* grab up to the last argument */
1551 for ( count = 5; count > 0; count-- )
1552 {
1553 dx = ADD_LONG( dx, temp[0] );
1554 dy = ADD_LONG( dy, temp[1] );
1555 temp += 2;
1556 }
1557
1558 if ( dx < 0 )
1559 dx = NEG_LONG( dx );
1560 if ( dy < 0 )
1561 dy = NEG_LONG( dy );
1562
1563 /* strange test, but here it is... */
1564 horizontal = ( dx > dy );
1565
1566 for ( count = 5; count > 0; count-- )
1567 {
1568 x = ADD_LONG( x, args[0] );
1569 y = ADD_LONG( y, args[1] );
1570 cff_builder_add_point( builder, x, y,
1571 FT_BOOL( count == 3 ) );
1572 args += 2;
1573 }
1574
1575 /* is last operand an x- or y-delta? */
1576 if ( horizontal )
1577 {
1578 x = ADD_LONG( x, args[0] );
1579 y = start_y;
1580 }
1581 else
1582 {
1583 x = start_x;
1584 y = ADD_LONG( y, args[0] );
1585 }
1586
1587 cff_builder_add_point( builder, x, y, 1 );
1588
1589 args = stack;
1590 break;
1591 }
1592
1593 case cff_op_flex:
1594 {
1595 FT_UInt count;
1596
1597
1598 FT_TRACE4(( " flex\n" ));
1599
1600 if ( cff_builder_start_point( builder, x, y ) ||
1601 cff_check_points( builder, 6 ) )
1602 goto Fail;
1603
1604 for ( count = 6; count > 0; count-- )
1605 {
1606 x = ADD_LONG( x, args[0] );
1607 y = ADD_LONG( y, args[1] );
1608 cff_builder_add_point( builder, x, y,
1609 FT_BOOL( count == 4 || count == 1 ) );
1610 args += 2;
1611 }
1612
1613 args = stack;
1614 }
1615 break;
1616
1617 case cff_op_seac:
1618 FT_TRACE4(( " seac\n" ));
1619
1620 error = cff_operator_seac( decoder,
1621 args[0], args[1], args[2],
1622 (FT_Int)( args[3] >> 16 ),
1623 (FT_Int)( args[4] >> 16 ) );
1624
1625 /* add current outline to the glyph slot */
1626 FT_GlyphLoader_Add( builder->loader );
1627
1628 /* return now! */
1629 FT_TRACE4(( "\n" ));
1630 return error;
1631
1632 case cff_op_endchar:
1633 /* in dictionaries, `endchar' simply indicates end of data */
1634 if ( in_dict )
1635 return error;
1636
1637 FT_TRACE4(( " endchar\n" ));
1638
1639 /* We are going to emulate the seac operator. */
1640 if ( num_args >= 4 )
1641 {
1642 /* Save glyph width so that the subglyphs don't overwrite it. */
1643 FT_Pos glyph_width = decoder->glyph_width;
1644
1645
1646 error = cff_operator_seac( decoder,
1647 0L, args[-4], args[-3],
1648 (FT_Int)( args[-2] >> 16 ),
1649 (FT_Int)( args[-1] >> 16 ) );
1650
1651 decoder->glyph_width = glyph_width;
1652 }
1653 else
1654 {
1655 cff_builder_close_contour( builder );
1656
1657 /* close hints recording session */
1658 if ( hinter )
1659 {
1660 if ( hinter->close( hinter->hints,
1661 (FT_UInt)builder->current->n_points ) )
1662 goto Syntax_Error;
1663
1664 /* apply hints to the loaded glyph outline now */
1665 error = hinter->apply( hinter->hints,
1666 builder->current,
1667 (PSH_Globals)builder->hints_globals,
1668 decoder->hint_mode );
1669 if ( error )
1670 goto Fail;
1671 }
1672
1673 /* add current outline to the glyph slot */
1674 FT_GlyphLoader_Add( builder->loader );
1675 }
1676
1677 /* return now! */
1678 FT_TRACE4(( "\n" ));
1679 return error;
1680
1681 case cff_op_abs:
1682 FT_TRACE4(( " abs\n" ));
1683
1684 if ( args[0] < 0 )
1685 {
1686 if ( args[0] == FT_LONG_MIN )
1687 args[0] = FT_LONG_MAX;
1688 else
1689 args[0] = -args[0];
1690 }
1691 args++;
1692 break;
1693
1694 case cff_op_add:
1695 FT_TRACE4(( " add\n" ));
1696
1697 args[0] = ADD_LONG( args[0], args[1] );
1698 args++;
1699 break;
1700
1701 case cff_op_sub:
1702 FT_TRACE4(( " sub\n" ));
1703
1704 args[0] = SUB_LONG( args[0], args[1] );
1705 args++;
1706 break;
1707
1708 case cff_op_div:
1709 FT_TRACE4(( " div\n" ));
1710
1711 args[0] = FT_DivFix( args[0], args[1] );
1712 args++;
1713 break;
1714
1715 case cff_op_neg:
1716 FT_TRACE4(( " neg\n" ));
1717
1718 if ( args[0] == FT_LONG_MIN )
1719 args[0] = FT_LONG_MAX;
1720 args[0] = -args[0];
1721 args++;
1722 break;
1723
1724 case cff_op_random:
1725 {
1726 FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random
1727 : &decoder->current_subfont->random;
1728
1729
1730 FT_TRACE4(( " random\n" ));
1731
1732 /* only use the lower 16 bits of `random' */
1733 /* to generate a number in the range (0;1] */
1734 args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
1735 args++;
1736
1737 *randval = cff_random( *randval );
1738 }
1739 break;
1740
1741 case cff_op_mul:
1742 FT_TRACE4(( " mul\n" ));
1743
1744 args[0] = FT_MulFix( args[0], args[1] );
1745 args++;
1746 break;
1747
1748 case cff_op_sqrt:
1749 FT_TRACE4(( " sqrt\n" ));
1750
1751 /* without upper limit the loop below might not finish */
1752 if ( args[0] > 0x7FFFFFFFL )
1753 args[0] = 46341;
1754 else if ( args[0] > 0 )
1755 {
1756 FT_Fixed root = args[0];
1757 FT_Fixed new_root;
1758
1759
1760 for (;;)
1761 {
1762 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1763 if ( new_root == root )
1764 break;
1765 root = new_root;
1766 }
1767 args[0] = new_root;
1768 }
1769 else
1770 args[0] = 0;
1771 args++;
1772 break;
1773
1774 case cff_op_drop:
1775 /* nothing */
1776 FT_TRACE4(( " drop\n" ));
1777
1778 break;
1779
1780 case cff_op_exch:
1781 {
1782 FT_Fixed tmp;
1783
1784
1785 FT_TRACE4(( " exch\n" ));
1786
1787 tmp = args[0];
1788 args[0] = args[1];
1789 args[1] = tmp;
1790 args += 2;
1791 }
1792 break;
1793
1794 case cff_op_index:
1795 {
1796 FT_Int idx = (FT_Int)( args[0] >> 16 );
1797
1798
1799 FT_TRACE4(( " index\n" ));
1800
1801 if ( idx < 0 )
1802 idx = 0;
1803 else if ( idx > num_args - 2 )
1804 idx = num_args - 2;
1805 args[0] = args[-( idx + 1 )];
1806 args++;
1807 }
1808 break;
1809
1810 case cff_op_roll:
1811 {
1812 FT_Int count = (FT_Int)( args[0] >> 16 );
1813 FT_Int idx = (FT_Int)( args[1] >> 16 );
1814
1815
1816 FT_TRACE4(( " roll\n" ));
1817
1818 if ( count <= 0 )
1819 count = 1;
1820
1821 args -= count;
1822 if ( args < stack )
1823 goto Stack_Underflow;
1824
1825 if ( idx >= 0 )
1826 {
1827 idx = idx % count;
1828 while ( idx > 0 )
1829 {
1830 FT_Fixed tmp = args[count - 1];
1831 FT_Int i;
1832
1833
1834 for ( i = count - 2; i >= 0; i-- )
1835 args[i + 1] = args[i];
1836 args[0] = tmp;
1837 idx--;
1838 }
1839 }
1840 else
1841 {
1842 /* before C99 it is implementation-defined whether */
1843 /* the result of `%' is negative if the first operand */
1844 /* is negative */
1845 idx = -( NEG_INT( idx ) % count );
1846 while ( idx < 0 )
1847 {
1848 FT_Fixed tmp = args[0];
1849 FT_Int i;
1850
1851
1852 for ( i = 0; i < count - 1; i++ )
1853 args[i] = args[i + 1];
1854 args[count - 1] = tmp;
1855 idx++;
1856 }
1857 }
1858 args += count;
1859 }
1860 break;
1861
1862 case cff_op_dup:
1863 FT_TRACE4(( " dup\n" ));
1864
1865 args[1] = args[0];
1866 args += 2;
1867 break;
1868
1869 case cff_op_put:
1870 {
1871 FT_Fixed val = args[0];
1872 FT_Int idx = (FT_Int)( args[1] >> 16 );
1873
1874
1875 FT_TRACE4(( " put\n" ));
1876
1877 /* the Type2 specification before version 16-March-2000 */
1878 /* didn't give a hard-coded size limit of the temporary */
1879 /* storage array; instead, an argument of the */
1880 /* `MultipleMaster' operator set the size */
1881 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1882 decoder->buildchar[idx] = val;
1883 }
1884 break;
1885
1886 case cff_op_get:
1887 {
1888 FT_Int idx = (FT_Int)( args[0] >> 16 );
1889 FT_Fixed val = 0;
1890
1891
1892 FT_TRACE4(( " get\n" ));
1893
1894 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1895 val = decoder->buildchar[idx];
1896
1897 args[0] = val;
1898 args++;
1899 }
1900 break;
1901
1902 case cff_op_store:
1903 /* this operator was removed from the Type2 specification */
1904 /* in version 16-March-2000 */
1905
1906 /* since we currently don't handle interpolation of multiple */
1907 /* master fonts, this is a no-op */
1908 FT_TRACE4(( " store\n" ));
1909 break;
1910
1911 case cff_op_load:
1912 /* this operator was removed from the Type2 specification */
1913 /* in version 16-March-2000 */
1914 {
1915 FT_Int reg_idx = (FT_Int)args[0];
1916 FT_Int idx = (FT_Int)args[1];
1917 FT_Int count = (FT_Int)args[2];
1918
1919
1920 FT_TRACE4(( " load\n" ));
1921
1922 /* since we currently don't handle interpolation of multiple */
1923 /* master fonts, we store a vector [1 0 0 ...] in the */
1924 /* temporary storage array regardless of the Registry index */
1925 if ( reg_idx >= 0 && reg_idx <= 2 &&
1926 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1927 count >= 0 && count <= num_axes )
1928 {
1929 FT_Int end, i;
1930
1931
1932 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
1933
1934 if ( idx < end )
1935 decoder->buildchar[idx] = 1 << 16;
1936
1937 for ( i = idx + 1; i < end; i++ )
1938 decoder->buildchar[i] = 0;
1939 }
1940 }
1941 break;
1942
1943 case cff_op_blend:
1944 /* this operator was removed from the Type2 specification */
1945 /* in version 16-March-2000 */
1946 if ( num_designs )
1947 {
1948 FT_Int num_results = (FT_Int)( args[0] >> 16 );
1949
1950
1951 FT_TRACE4(( " blend\n" ));
1952
1953 if ( num_results < 0 )
1954 goto Syntax_Error;
1955
1956 if ( num_results > num_args ||
1957 num_results * (FT_Int)num_designs > num_args )
1958 goto Stack_Underflow;
1959
1960 /* since we currently don't handle interpolation of multiple */
1961 /* master fonts, return the `num_results' values of the */
1962 /* first master */
1963 args -= num_results * ( num_designs - 1 );
1964 num_args -= num_results * ( num_designs - 1 );
1965 }
1966 else
1967 goto Syntax_Error;
1968 break;
1969
1970 case cff_op_dotsection:
1971 /* this operator is deprecated and ignored by the parser */
1972 FT_TRACE4(( " dotsection\n" ));
1973 break;
1974
1975 case cff_op_closepath:
1976 /* this is an invalid Type 2 operator; however, there */
1977 /* exist fonts which are incorrectly converted from probably */
1978 /* Type 1 to CFF, and some parsers seem to accept it */
1979
1980 FT_TRACE4(( " closepath (invalid op)\n" ));
1981
1982 args = stack;
1983 break;
1984
1985 case cff_op_hsbw:
1986 /* this is an invalid Type 2 operator; however, there */
1987 /* exist fonts which are incorrectly converted from probably */
1988 /* Type 1 to CFF, and some parsers seem to accept it */
1989
1990 FT_TRACE4(( " hsbw (invalid op)\n" ));
1991
1992 decoder->glyph_width =
1993 ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) );
1994
1995 decoder->builder.left_bearing.x = args[0];
1996 decoder->builder.left_bearing.y = 0;
1997
1998 x = ADD_LONG( decoder->builder.pos_x, args[0] );
1999 y = decoder->builder.pos_y;
2000 args = stack;
2001 break;
2002
2003 case cff_op_sbw:
2004 /* this is an invalid Type 2 operator; however, there */
2005 /* exist fonts which are incorrectly converted from probably */
2006 /* Type 1 to CFF, and some parsers seem to accept it */
2007
2008 FT_TRACE4(( " sbw (invalid op)\n" ));
2009
2010 decoder->glyph_width =
2011 ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) );
2012
2013 decoder->builder.left_bearing.x = args[0];
2014 decoder->builder.left_bearing.y = args[1];
2015
2016 x = ADD_LONG( decoder->builder.pos_x, args[0] );
2017 y = ADD_LONG( decoder->builder.pos_y, args[1] );
2018 args = stack;
2019 break;
2020
2021 case cff_op_setcurrentpoint:
2022 /* this is an invalid Type 2 operator; however, there */
2023 /* exist fonts which are incorrectly converted from probably */
2024 /* Type 1 to CFF, and some parsers seem to accept it */
2025
2026 FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2027
2028 x = ADD_LONG( decoder->builder.pos_x, args[0] );
2029 y = ADD_LONG( decoder->builder.pos_y, args[1] );
2030 args = stack;
2031 break;
2032
2033 case cff_op_callothersubr:
2034 {
2035 FT_Fixed arg;
2036
2037
2038 /* this is an invalid Type 2 operator; however, there */
2039 /* exist fonts which are incorrectly converted from */
2040 /* probably Type 1 to CFF, and some parsers seem to accept */
2041 /* it */
2042
2043 FT_TRACE4(( " callothersubr (invalid op)\n" ));
2044
2045 /* subsequent `pop' operands should add the arguments, */
2046 /* this is the implementation described for `unknown' */
2047 /* other subroutines in the Type1 spec. */
2048 /* */
2049 /* XXX Fix return arguments (see discussion below). */
2050
2051 arg = 2 + ( args[-2] >> 16 );
2052 if ( arg >= CFF_MAX_OPERANDS )
2053 goto Stack_Underflow;
2054
2055 args -= arg;
2056 if ( args < stack )
2057 goto Stack_Underflow;
2058 }
2059 break;
2060
2061 case cff_op_pop:
2062 /* this is an invalid Type 2 operator; however, there */
2063 /* exist fonts which are incorrectly converted from probably */
2064 /* Type 1 to CFF, and some parsers seem to accept it */
2065
2066 FT_TRACE4(( " pop (invalid op)\n" ));
2067
2068 /* XXX Increasing `args' is wrong: After a certain number of */
2069 /* `pop's we get a stack overflow. Reason for doing it is */
2070 /* code like this (actually found in a CFF font): */
2071 /* */
2072 /* 17 1 3 callothersubr */
2073 /* pop */
2074 /* callsubr */
2075 /* */
2076 /* Since we handle `callothersubr' as a no-op, and */
2077 /* `callsubr' needs at least one argument, `pop' can't be a */
2078 /* no-op too as it basically should be. */
2079 /* */
2080 /* The right solution would be to provide real support for */
2081 /* `callothersubr' as done in `t1decode.c', however, given */
2082 /* the fact that CFF fonts with `pop' are invalid, it is */
2083 /* questionable whether it is worth the time. */
2084 args++;
2085 break;
2086
2087 case cff_op_and:
2088 {
2089 FT_Fixed cond = ( args[0] && args[1] );
2090
2091
2092 FT_TRACE4(( " and\n" ));
2093
2094 args[0] = cond ? 0x10000L : 0;
2095 args++;
2096 }
2097 break;
2098
2099 case cff_op_or:
2100 {
2101 FT_Fixed cond = ( args[0] || args[1] );
2102
2103
2104 FT_TRACE4(( " or\n" ));
2105
2106 args[0] = cond ? 0x10000L : 0;
2107 args++;
2108 }
2109 break;
2110
2111 case cff_op_not:
2112 {
2113 FT_Fixed cond = !args[0];
2114
2115
2116 FT_TRACE4(( " not\n" ));
2117
2118 args[0] = cond ? 0x10000L : 0;
2119 args++;
2120 }
2121 break;
2122
2123 case cff_op_eq:
2124 {
2125 FT_Fixed cond = ( args[0] == args[1] );
2126
2127
2128 FT_TRACE4(( " eq\n" ));
2129
2130 args[0] = cond ? 0x10000L : 0;
2131 args++;
2132 }
2133 break;
2134
2135 case cff_op_ifelse:
2136 {
2137 FT_Fixed cond = ( args[2] <= args[3] );
2138
2139
2140 FT_TRACE4(( " ifelse\n" ));
2141
2142 if ( !cond )
2143 args[0] = args[1];
2144 args++;
2145 }
2146 break;
2147
2148 case cff_op_callsubr:
2149 {
2150 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2151 decoder->locals_bias );
2152
2153
2154 FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
2155 idx,
2156 zone - decoder->zones + 1 ));
2157
2158 if ( idx >= decoder->num_locals )
2159 {
2160 FT_ERROR(( "cff_decoder_parse_charstrings:"
2161 " invalid local subr index\n" ));
2162 goto Syntax_Error;
2163 }
2164
2165 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2166 {
2167 FT_ERROR(( "cff_decoder_parse_charstrings:"
2168 " too many nested subrs\n" ));
2169 goto Syntax_Error;
2170 }
2171
2172 zone->cursor = ip; /* save current instruction pointer */
2173
2174 zone++;
2175 zone->base = decoder->locals[idx];
2176 zone->limit = decoder->locals[idx + 1];
2177 zone->cursor = zone->base;
2178
2179 if ( !zone->base || zone->limit == zone->base )
2180 {
2181 FT_ERROR(( "cff_decoder_parse_charstrings:"
2182 " invoking empty subrs\n" ));
2183 goto Syntax_Error;
2184 }
2185
2186 decoder->zone = zone;
2187 ip = zone->base;
2188 limit = zone->limit;
2189 }
2190 break;
2191
2192 case cff_op_callgsubr:
2193 {
2194 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2195 decoder->globals_bias );
2196
2197
2198 FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
2199 idx,
2200 zone - decoder->zones + 1 ));
2201
2202 if ( idx >= decoder->num_globals )
2203 {
2204 FT_ERROR(( "cff_decoder_parse_charstrings:"
2205 " invalid global subr index\n" ));
2206 goto Syntax_Error;
2207 }
2208
2209 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2210 {
2211 FT_ERROR(( "cff_decoder_parse_charstrings:"
2212 " too many nested subrs\n" ));
2213 goto Syntax_Error;
2214 }
2215
2216 zone->cursor = ip; /* save current instruction pointer */
2217
2218 zone++;
2219 zone->base = decoder->globals[idx];
2220 zone->limit = decoder->globals[idx + 1];
2221 zone->cursor = zone->base;
2222
2223 if ( !zone->base || zone->limit == zone->base )
2224 {
2225 FT_ERROR(( "cff_decoder_parse_charstrings:"
2226 " invoking empty subrs\n" ));
2227 goto Syntax_Error;
2228 }
2229
2230 decoder->zone = zone;
2231 ip = zone->base;
2232 limit = zone->limit;
2233 }
2234 break;
2235
2236 case cff_op_return:
2237 FT_TRACE4(( " return (leaving level %d)\n",
2238 decoder->zone - decoder->zones ));
2239
2240 if ( decoder->zone <= decoder->zones )
2241 {
2242 FT_ERROR(( "cff_decoder_parse_charstrings:"
2243 " unexpected return\n" ));
2244 goto Syntax_Error;
2245 }
2246
2247 decoder->zone--;
2248 zone = decoder->zone;
2249 ip = zone->cursor;
2250 limit = zone->limit;
2251 break;
2252
2253 default:
2254 FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2255
2256 if ( ip[-1] == 12 )
2257 FT_ERROR(( " %d", ip[0] ));
2258 FT_ERROR(( "\n" ));
2259
2260 return FT_THROW( Unimplemented_Feature );
2261 }
2262
2263 decoder->top = args;
2264
2265 if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2266 goto Stack_Overflow;
2267
2268 } /* general operator processing */
2269
2270 } /* while ip < limit */
2271
2272 FT_TRACE4(( "..end..\n\n" ));
2273
2274 Fail:
2275 return error;
2276
2277 MM_Error:
2278 FT_TRACE4(( "cff_decoder_parse_charstrings:"
2279 " invalid opcode found in top DICT charstring\n"));
2280 return FT_THROW( Invalid_File_Format );
2281
2282 Syntax_Error:
2283 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2284 return FT_THROW( Invalid_File_Format );
2285
2286 Stack_Underflow:
2287 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2288 return FT_THROW( Too_Few_Arguments );
2289
2290 Stack_Overflow:
2291 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2292 return FT_THROW( Stack_Overflow );
2293 }
2294
2295#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2296
2297
2298 /**************************************************************************
2299 *
2300 * @Function:
2301 * cff_decoder_init
2302 *
2303 * @Description:
2304 * Initializes a given glyph decoder.
2305 *
2306 * @InOut:
2307 * decoder ::
2308 * A pointer to the glyph builder to initialize.
2309 *
2310 * @Input:
2311 * face ::
2312 * The current face object.
2313 *
2314 * size ::
2315 * The current size object.
2316 *
2317 * slot ::
2318 * The current glyph object.
2319 *
2320 * hinting ::
2321 * Whether hinting is active.
2322 *
2323 * hint_mode ::
2324 * The hinting mode.
2325 */
2326 FT_LOCAL_DEF( void )
2327 cff_decoder_init( CFF_Decoder* decoder,
2328 TT_Face face,
2329 CFF_Size size,
2330 CFF_GlyphSlot slot,
2331 FT_Bool hinting,
2332 FT_Render_Mode hint_mode,
2333 CFF_Decoder_Get_Glyph_Callback get_callback,
2334 CFF_Decoder_Free_Glyph_Callback free_callback )
2335 {
2336 CFF_Font cff = (CFF_Font)face->extra.data;
2337
2338
2339 /* clear everything */
2340 FT_ZERO( decoder );
2341
2342 /* initialize builder */
2343 cff_builder_init( &decoder->builder, face, size, slot, hinting );
2344
2345 /* initialize Type2 decoder */
2346 decoder->cff = cff;
2347 decoder->num_globals = cff->global_subrs_index.count;
2348 decoder->globals = cff->global_subrs;
2349 decoder->globals_bias = cff_compute_bias(
2350 cff->top_font.font_dict.charstring_type,
2351 decoder->num_globals );
2352
2353 decoder->hint_mode = hint_mode;
2354
2355 decoder->get_glyph_callback = get_callback;
2356 decoder->free_glyph_callback = free_callback;
2357 }
2358
2359
2360 /* this function is used to select the subfont */
2361 /* and the locals subrs array */
2362 FT_LOCAL_DEF( FT_Error )
2363 cff_decoder_prepare( CFF_Decoder* decoder,
2364 CFF_Size size,
2365 FT_UInt glyph_index )
2366 {
2367 CFF_Builder *builder = &decoder->builder;
2368 CFF_Font cff = (CFF_Font)builder->face->extra.data;
2369 CFF_SubFont sub = &cff->top_font;
2370 FT_Error error = FT_Err_Ok;
2371
2372 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload;
2373
2374
2375 /* manage CID fonts */
2376 if ( cff->num_subfonts )
2377 {
2378 FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select,
2379 glyph_index );
2380
2381
2382 if ( fd_index >= cff->num_subfonts )
2383 {
2384 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
2385 error = FT_THROW( Invalid_File_Format );
2386 goto Exit;
2387 }
2388
2389 FT_TRACE3(( " in subfont %d:\n", fd_index ));
2390
2391 sub = cff->subfonts[fd_index];
2392
2393 if ( builder->hints_funcs && size )
2394 {
2395 FT_Size ftsize = FT_SIZE( size );
2396 CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data;
2397
2398
2399 /* for CFFs without subfonts, this value has already been set */
2400 builder->hints_globals = (void *)internal->subfonts[fd_index];
2401 }
2402 }
2403
2404 decoder->num_locals = sub->local_subrs_index.count;
2405 decoder->locals = sub->local_subrs;
2406 decoder->locals_bias = cff_compute_bias(
2407 decoder->cff->top_font.font_dict.charstring_type,
2408 decoder->num_locals );
2409
2410 decoder->glyph_width = sub->private_dict.default_width;
2411 decoder->nominal_width = sub->private_dict.nominal_width;
2412
2413 decoder->current_subfont = sub;
2414
2415 Exit:
2416 return error;
2417 }
2418
2419
2420/* END */
2421