ReactOS 0.4.16-dev-959-g2ec3a19
cffdecode.c
Go to the documentation of this file.
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 {
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 */
277 if ( error )
278 goto Exit;
279
280 subg = loader->current.subglyphs;
281
282 /* subglyph 0 = base character */
283 subg->index = bchar_index;
286 subg->arg1 = 0;
287 subg->arg2 = 0;
288 subg++;
289
290 /* subglyph 1 = accent character */
291 subg->index = achar_index;
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 {
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
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 */
497 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
498 FT_Byte* charstring_base,
499 FT_ULong charstring_len,
500 FT_Bool in_dict )
501 {
504 FT_Byte* ip;
505 FT_Byte* limit;
506 CFF_Builder* builder = &decoder->builder;
507 FT_Pos x, y;
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
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 {
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 {
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 {
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
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 )
2328 TT_Face face,
2329 CFF_Size size,
2331 FT_Bool hinting,
2332 FT_Render_Mode hint_mode,
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(
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 */
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;
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 );
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 */
ios_base &_STLP_CALL internal(ios_base &__s)
Definition: _ios_base.h:311
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
static int start_x
Definition: maze.c:118
static int start_y
Definition: maze.c:118
static HRESULT get_callback(IBindCtx *pbc, IBindStatusCallback **callback)
Definition: binding.c:1411
cff_decoder_init(CFF_Decoder *decoder, TT_Face face, CFF_Size size, CFF_GlyphSlot slot, FT_Bool hinting, FT_Render_Mode hint_mode, CFF_Decoder_Get_Glyph_Callback get_callback, CFF_Decoder_Free_Glyph_Callback free_callback)
Definition: cffdecode.c:2327
static FT_Int cff_compute_bias(FT_Int in_charstring_type, FT_UInt num_subrs)
Definition: cffdecode.c:402
cff_decoder_prepare(CFF_Decoder *decoder, CFF_Size size, FT_UInt glyph_index)
Definition: cffdecode.c:2363
cff_lookup_glyph_by_stdcharcode(CFF_Font cff, FT_Int charcode)
Definition: cffdecode.c:422
CFF_Font cff
Definition: cffdrivr.c:702
struct CFF_InternalRec_ * CFF_Internal
struct CFF_FontRec_ * CFF_Font
Definition: cfftypes.h:157
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
unsigned int idx
Definition: utils.c:41
int Fail
Definition: ehthrow.cxx:24
enum FT_Render_Mode_ FT_Render_Mode
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3967
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:548
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3962
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
return FT_Err_Ok
Definition: ftbbox.c:527
#define NEG_INT(a)
Definition: ftcalc.h:470
#define NEG_LONG(a)
Definition: ftcalc.h:479
#define SUB_LONG(a, b)
Definition: ftcalc.h:475
#define ADD_LONG(a, b)
Definition: ftcalc.h:473
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:387
#define FT_ERROR(varformat)
Definition: ftdebug.h:209
#define FT_TRACE3(varformat)
Definition: ftdebug.h:188
#define FT_THROW(e)
Definition: ftdebug.h:241
#define FT_TRACE4(varformat)
Definition: ftdebug.h:189
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:312
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_SIZE(x)
Definition: ftobjs.h:600
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:127
#define FT_LONG_MIN
Definition: ftstdlib.h:66
#define FT_LONG_MAX
Definition: ftstdlib.h:67
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
unsigned short FT_UShort
Definition: fttypes.h:209
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:591
signed int FT_Int
Definition: fttypes.h:220
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLsizeiptr size
Definition: glext.h:5919
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLint limit
Definition: glext.h:10326
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const struct T2_Hints_FuncsRec_ * T2_Hints_Funcs
Definition: pshints.h:404
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:41
JSAMPARRAY JDIMENSION num_lines
Definition: jpeglib.h:1017
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
#define error(str)
Definition: mkdosfs.c:1605
DWORD zone
Definition: sec_mgr.c:1754
#define shift
Definition: input.c:1755
#define L(x)
Definition: ntvdm.h:50
#define CFF_MAX_OPERANDS
Definition: psaux.h:1147
#define CFF_MAX_SUBRS_CALLS
Definition: psaux.h:1148
FT_Error(* CFF_Decoder_Get_Glyph_Callback)(TT_Face face, FT_UInt glyph_index, FT_Byte **pointer, FT_ULong *length)
Definition: psaux.h:620
void(* CFF_Decoder_Free_Glyph_Callback)(TT_Face face, FT_Byte **pointer, FT_ULong length)
Definition: psaux.h:626
#define CFF_MAX_TRANS_ELEMENTS
Definition: psaux.h:1154
cff_builder_add_point1(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1966
cff_builder_add_point(CFF_Builder *builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1928
cff_check_points(CFF_Builder *builder, FT_Int count)
Definition: psobjs.c:1919
cff_builder_start_point(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:2011
cff_random(FT_UInt32 r)
Definition: psobjs.c:2588
cff_builder_init(CFF_Builder *builder, TT_Face face, CFF_Size size, CFF_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1841
cff_builder_close_contour(CFF_Builder *builder)
Definition: psobjs.c:2033
static calc_node_t temp
Definition: rpn_ieee.c:38
#define args
Definition: format.c:66
static void Exit(void)
Definition: sock.c:1330
FT_Pos pos_x
Definition: psaux.h:1117
FT_Vector left_bearing
Definition: psaux.h:1120
FT_GlyphLoader loader
Definition: psaux.h:1113
TT_Face face
Definition: psaux.h:1111
FT_Pos pos_y
Definition: psaux.h:1118
CFF_GlyphSlot glyph
Definition: psaux.h:1112
void * hints_globals
Definition: psaux.h:1132
void * hints_funcs
Definition: psaux.h:1131
FT_Vector advance
Definition: psaux.h:1121
FT_Bool path_begun
Definition: psaux.h:1125
FT_Outline * current
Definition: psaux.h:1115
FT_Bool no_recurse
Definition: psaux.h:1127
FT_UShort * sids
Definition: cfftypes.h:103
FT_Int charstring_type
Definition: cfftypes.h:198
FT_Byte ** global_subrs
Definition: cfftypes.h:370
FT_UInt num_subfonts
Definition: cfftypes.h:379
CFF_SubFont subfonts[CFF_MAX_CID_FONTS]
Definition: cfftypes.h:380
CFF_CharsetRec charset
Definition: cfftypes.h:360
CFF_SubFontRec top_font
Definition: cfftypes.h:378
CFF_FDSelectRec fd_select
Definition: cfftypes.h:382
const void * cffload
Definition: cfftypes.h:391
CFF_IndexRec global_subrs_index
Definition: cfftypes.h:357
FT_UInt num_glyphs
Definition: cfftypes.h:345
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:305
void * data
Definition: fttypes.h:469
FT_SubGlyph subglyphs
Definition: freetype.h:1899
FT_UInt num_subglyphs
Definition: freetype.h:1898
FT_Slot_Internal internal
Definition: freetype.h:1909
FT_Glyph_Format format
Definition: freetype.h:1890
short n_points
Definition: ftimage.h:340
FT_Size_Internal internal
Definition: freetype.h:1650
void * module_data
Definition: ftobjs.h:461
FT_GlyphLoader loader
Definition: ftobjs.h:427
FT_Pos x
Definition: ftimage.h:78
FT_Pos y
Definition: ftimage.h:79
T2_Hints_StemsFunc stems
Definition: pshints.h:660
T2_Hints_OpenFunc open
Definition: pshints.h:658
T2_Hints_CloseFunc close
Definition: pshints.h:659
T2_Hints_ApplyFunc apply
Definition: pshints.h:663
T2_Hints_CounterFunc counter
Definition: pshints.h:662
T2_Hints_MaskFunc hintmask
Definition: pshints.h:661
T2_Hints hints
Definition: pshints.h:657
FT_Generic extra
Definition: tttypes.h:1650
Definition: vfat.h:185
Definition: match.c:390
Definition: dhcpd.h:62
Definition: format.c:80
void * arg
Definition: msvc.h:10