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