ReactOS 0.4.16-dev-2354-g16de117
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-2020 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>
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 {
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 */
276 if ( error )
277 goto Exit;
278
279 subg = loader->current.subglyphs;
280
281 /* subglyph 0 = base character */
282 subg->index = bchar_index;
285 subg->arg1 = 0;
286 subg->arg2 = 0;
287 subg++;
288
289 /* subglyph 1 = accent character */
290 subg->index = achar_index;
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 {
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
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 */
496 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
497 FT_Byte* charstring_base,
498 FT_ULong charstring_len,
499 FT_Bool in_dict )
500 {
503 FT_Byte* ip;
504 FT_Byte* limit;
505 CFF_Builder* builder = &decoder->builder;
506 FT_Pos x, y;
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
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 {
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 {
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 {
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_Int idx = (FT_Int)( 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 >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
1884 decoder->buildchar[idx] = val;
1885 }
1886 break;
1887
1888 case cff_op_get:
1889 {
1890 FT_Int idx = (FT_Int)( args[0] >> 16 );
1891 FT_Fixed val = 0;
1892
1893
1894 FT_TRACE4(( " get\n" ));
1895
1896 if ( idx >= 0 && 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_Int reg_idx = (FT_Int)args[0];
1918 FT_Int idx = (FT_Int)args[1];
1919 FT_Int count = (FT_Int)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 >= 0 && reg_idx <= 2 &&
1928 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1929 count >= 0 && count <= num_axes )
1930 {
1931 FT_Int end, i;
1932
1933
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 %d)\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 %d)\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 %d)\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\n" ));
2275
2276 Fail:
2277 return error;
2278
2279 MM_Error:
2280 FT_TRACE4(( "cff_decoder_parse_charstrings:"
2281 " invalid opcode found in top DICT charstring\n"));
2282 return FT_THROW( Invalid_File_Format );
2283
2284 Syntax_Error:
2285 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2286 return FT_THROW( Invalid_File_Format );
2287
2288 Stack_Underflow:
2289 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2290 return FT_THROW( Too_Few_Arguments );
2291
2292 Stack_Overflow:
2293 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2294 return FT_THROW( Stack_Overflow );
2295 }
2296
2297#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2298
2299
2300 /**************************************************************************
2301 *
2302 * @Function:
2303 * cff_decoder_init
2304 *
2305 * @Description:
2306 * Initializes a given glyph decoder.
2307 *
2308 * @InOut:
2309 * decoder ::
2310 * A pointer to the glyph builder to initialize.
2311 *
2312 * @Input:
2313 * face ::
2314 * The current face object.
2315 *
2316 * size ::
2317 * The current size object.
2318 *
2319 * slot ::
2320 * The current glyph object.
2321 *
2322 * hinting ::
2323 * Whether hinting is active.
2324 *
2325 * hint_mode ::
2326 * The hinting mode.
2327 */
2328 FT_LOCAL_DEF( void )
2330 TT_Face face,
2331 CFF_Size size,
2333 FT_Bool hinting,
2334 FT_Render_Mode hint_mode,
2336 CFF_Decoder_Free_Glyph_Callback free_callback )
2337 {
2338 CFF_Font cff = (CFF_Font)face->extra.data;
2339
2340
2341 /* clear everything */
2342 FT_ZERO( decoder );
2343
2344 /* initialize builder */
2345 cff_builder_init( &decoder->builder, face, size, slot, hinting );
2346
2347 /* initialize Type2 decoder */
2348 decoder->cff = cff;
2349 decoder->num_globals = cff->global_subrs_index.count;
2350 decoder->globals = cff->global_subrs;
2351 decoder->globals_bias = cff_compute_bias(
2353 decoder->num_globals );
2354
2355 decoder->hint_mode = hint_mode;
2356
2357 decoder->get_glyph_callback = get_callback;
2358 decoder->free_glyph_callback = free_callback;
2359 }
2360
2361
2362 /* this function is used to select the subfont */
2363 /* and the locals subrs array */
2366 CFF_Size size,
2367 FT_UInt glyph_index )
2368 {
2369 CFF_Builder *builder = &decoder->builder;
2370 CFF_Font cff = (CFF_Font)builder->face->extra.data;
2371 CFF_SubFont sub = &cff->top_font;
2373
2374 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload;
2375
2376
2377 /* manage CID fonts */
2378 if ( cff->num_subfonts )
2379 {
2380 FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select,
2381 glyph_index );
2382
2383
2384 if ( fd_index >= cff->num_subfonts )
2385 {
2386 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
2387 error = FT_THROW( Invalid_File_Format );
2388 goto Exit;
2389 }
2390
2391 FT_TRACE3(( " in subfont %d:\n", fd_index ));
2392
2393 sub = cff->subfonts[fd_index];
2394
2395 if ( builder->hints_funcs && size )
2396 {
2397 FT_Size ftsize = FT_SIZE( size );
2399
2400
2401 /* for CFFs without subfonts, this value has already been set */
2402 builder->hints_globals = (void *)internal->subfonts[fd_index];
2403 }
2404 }
2405
2406 decoder->num_locals = sub->local_subrs_index.count;
2407 decoder->locals = sub->local_subrs;
2408 decoder->locals_bias = cff_compute_bias(
2409 decoder->cff->top_font.font_dict.charstring_type,
2410 decoder->num_locals );
2411
2412 decoder->glyph_width = sub->private_dict.default_width;
2413 decoder->nominal_width = sub->private_dict.nominal_width;
2414
2415 decoder->current_subfont = sub;
2416
2417 Exit:
2418 return error;
2419 }
2420
2421
2422/* 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:2329
static FT_Int cff_compute_bias(FT_Int in_charstring_type, FT_UInt num_subrs)
Definition: cffdecode.c:401
cff_decoder_prepare(CFF_Decoder *decoder, CFF_Size size, FT_UInt glyph_index)
Definition: cffdecode.c:2365
cff_lookup_glyph_by_stdcharcode(CFF_Font cff, FT_Int charcode)
Definition: cffdecode.c:421
CFF_Font cff
Definition: cffdrivr.c:701
struct CFF_InternalRec_ * CFF_Internal
struct CFF_FontRec_ * CFF_Font
Definition: cfftypes.h:156
#define FT_LOCAL_DEF(x)
#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
#define L(x)
Definition: resources.c:13
int Fail
Definition: ehthrow.cxx:24
enum FT_Render_Mode_ FT_Render_Mode
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:607
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3960
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:532
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3955
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:508
return FT_Err_Ok
Definition: ftbbox.c:526
#define NEG_INT(a)
Definition: ftcalc.h:469
#define NEG_LONG(a)
Definition: ftcalc.h:478
#define SUB_LONG(a, b)
Definition: ftcalc.h:474
#define ADD_LONG(a, b)
Definition: ftcalc.h:472
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_TRACE3(varformat)
Definition: ftdebug.h:190
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:340
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:324
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:293
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define FT_SIZE(x)
Definition: ftobjs.h:598
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:128
#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:403
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:40
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 CFF_MAX_OPERANDS
Definition: psaux.h:1146
#define CFF_MAX_SUBRS_CALLS
Definition: psaux.h:1147
FT_Error(* CFF_Decoder_Get_Glyph_Callback)(TT_Face face, FT_UInt glyph_index, FT_Byte **pointer, FT_ULong *length)
Definition: psaux.h:619
void(* CFF_Decoder_Free_Glyph_Callback)(TT_Face face, FT_Byte **pointer, FT_ULong length)
Definition: psaux.h:625
#define CFF_MAX_TRANS_ELEMENTS
Definition: psaux.h:1153
cff_builder_add_point1(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1965
cff_builder_add_point(CFF_Builder *builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1927
cff_check_points(CFF_Builder *builder, FT_Int count)
Definition: psobjs.c:1918
cff_builder_start_point(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:2010
cff_random(FT_UInt32 r)
Definition: psobjs.c:2587
cff_builder_init(CFF_Builder *builder, TT_Face face, CFF_Size size, CFF_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1840
cff_builder_close_contour(CFF_Builder *builder)
Definition: psobjs.c:2032
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:1116
FT_Vector left_bearing
Definition: psaux.h:1119
FT_GlyphLoader loader
Definition: psaux.h:1112
TT_Face face
Definition: psaux.h:1110
FT_Pos pos_y
Definition: psaux.h:1117
CFF_GlyphSlot glyph
Definition: psaux.h:1111
void * hints_globals
Definition: psaux.h:1131
void * hints_funcs
Definition: psaux.h:1130
FT_Vector advance
Definition: psaux.h:1120
FT_Bool path_begun
Definition: psaux.h:1124
FT_Outline * current
Definition: psaux.h:1114
FT_Bool no_recurse
Definition: psaux.h:1126
FT_UShort * sids
Definition: cfftypes.h:102
FT_Int charstring_type
Definition: cfftypes.h:197
FT_Byte ** global_subrs
Definition: cfftypes.h:369
FT_UInt num_subfonts
Definition: cfftypes.h:378
CFF_SubFont subfonts[CFF_MAX_CID_FONTS]
Definition: cfftypes.h:379
CFF_CharsetRec charset
Definition: cfftypes.h:359
CFF_SubFontRec top_font
Definition: cfftypes.h:377
CFF_FDSelectRec fd_select
Definition: cfftypes.h:381
const void * cffload
Definition: cfftypes.h:390
CFF_IndexRec global_subrs_index
Definition: cfftypes.h:356
FT_UInt num_glyphs
Definition: cfftypes.h:344
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:304
void * data
Definition: fttypes.h:469
FT_SubGlyph subglyphs
Definition: freetype.h:1893
FT_UInt num_subglyphs
Definition: freetype.h:1892
FT_Slot_Internal internal
Definition: freetype.h:1903
FT_Glyph_Format format
Definition: freetype.h:1884
short n_points
Definition: ftimage.h:339
FT_Size_Internal internal
Definition: freetype.h:1637
void * module_data
Definition: ftobjs.h:459
FT_GlyphLoader loader
Definition: ftobjs.h:425
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
T2_Hints_StemsFunc stems
Definition: pshints.h:659
T2_Hints_OpenFunc open
Definition: pshints.h:657
T2_Hints_CloseFunc close
Definition: pshints.h:658
T2_Hints_ApplyFunc apply
Definition: pshints.h:662
T2_Hints_CounterFunc counter
Definition: pshints.h:661
T2_Hints_MaskFunc hintmask
Definition: pshints.h:660
T2_Hints hints
Definition: pshints.h:656
FT_Generic extra
Definition: tttypes.h:1576
Definition: vfat.h:185
Definition: match.c:390
Definition: dhcpd.h:62
Definition: format.c:80
void * arg
Definition: msvc.h:10