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