1/***************************************************************************/
2/* */
3/* cffparse.c */
4/* */
5/* CFF token stream parser (body) */
6/* */
7/* Copyright 1996-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 "cffparse.h"
21#include FT_INTERNAL_STREAM_H
22#include FT_INTERNAL_DEBUG_H
23#include FT_INTERNAL_CALC_H
24#include FT_INTERNAL_POSTSCRIPT_AUX_H
25
26#include "cfferrs.h"
27#include "cffpic.h"
28#include "cffload.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_cffparse
39
40
41 FT_LOCAL_DEF( FT_Error )
42 cff_parser_init( CFF_Parser parser,
43 FT_UInt code,
44 void* object,
45 FT_Library library,
46 FT_UInt stackSize,
47 FT_UShort num_designs,
48 FT_UShort num_axes )
49 {
50 FT_Memory memory = library->memory; /* for FT_NEW_ARRAY */
51 FT_Error error; /* for FT_NEW_ARRAY */
52
53
54 FT_ZERO( parser );
55
56#if 0
57 parser->top = parser->stack;
58#endif
59 parser->object_code = code;
60 parser->object = object;
61 parser->library = library;
62 parser->num_designs = num_designs;
63 parser->num_axes = num_axes;
64
65 /* allocate the stack buffer */
66 if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
67 {
68 FT_FREE( parser->stack );
69 goto Exit;
70 }
71
72 parser->stackSize = stackSize;
73 parser->top = parser->stack; /* empty stack */
74
75 Exit:
76 return error;
77 }
78
79
80 FT_LOCAL_DEF( void )
81 cff_parser_done( CFF_Parser parser )
82 {
83 FT_Memory memory = parser->library->memory; /* for FT_FREE */
84
85
86 FT_FREE( parser->stack );
87 }
88
89
90 /* read an integer */
91 static FT_Long
92 cff_parse_integer( FT_Byte* start,
93 FT_Byte* limit )
94 {
95 FT_Byte* p = start;
96 FT_Int v = *p++;
97 FT_Long val = 0;
98
99
100 if ( v == 28 )
101 {
102 if ( p + 2 > limit )
103 goto Bad;
104
105 val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
106 }
107 else if ( v == 29 )
108 {
109 if ( p + 4 > limit )
110 goto Bad;
111
112 val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
113 ( (FT_ULong)p[1] << 16 ) |
114 ( (FT_ULong)p[2] << 8 ) |
115 (FT_ULong)p[3] );
116 }
117 else if ( v < 247 )
118 {
119 val = v - 139;
120 }
121 else if ( v < 251 )
122 {
123 if ( p + 1 > limit )
124 goto Bad;
125
126 val = ( v - 247 ) * 256 + p[0] + 108;
127 }
128 else
129 {
130 if ( p + 1 > limit )
131 goto Bad;
132
133 val = -( v - 251 ) * 256 - p[0] - 108;
134 }
135
136 Exit:
137 return val;
138
139 Bad:
140 val = 0;
141 FT_TRACE4(( "!!!END OF DATA:!!!" ));
142 goto Exit;
143 }
144
145
146 static const FT_Long power_tens[] =
147 {
148 1L,
149 10L,
150 100L,
151 1000L,
152 10000L,
153 100000L,
154 1000000L,
155 10000000L,
156 100000000L,
157 1000000000L
158 };
159
160 /* maximum values allowed for multiplying */
161 /* with the corresponding `power_tens' element */
162 static const FT_Long power_ten_limits[] =
163 {
164 FT_LONG_MAX / 1L,
165 FT_LONG_MAX / 10L,
166 FT_LONG_MAX / 100L,
167 FT_LONG_MAX / 1000L,
168 FT_LONG_MAX / 10000L,
169 FT_LONG_MAX / 100000L,
170 FT_LONG_MAX / 1000000L,
171 FT_LONG_MAX / 10000000L,
172 FT_LONG_MAX / 100000000L,
173 FT_LONG_MAX / 1000000000L,
174 };
175
176
177 /* read a real */
178 static FT_Fixed
179 cff_parse_real( FT_Byte* start,
180 FT_Byte* limit,
181 FT_Long power_ten,
182 FT_Long* scaling )
183 {
184 FT_Byte* p = start;
185 FT_Int nib;
186 FT_UInt phase;
187
188 FT_Long result, number, exponent;
189 FT_Int sign = 0, exponent_sign = 0, have_overflow = 0;
190 FT_Long exponent_add, integer_length, fraction_length;
191
192
193 if ( scaling )
194 *scaling = 0;
195
196 result = 0;
197
198 number = 0;
199 exponent = 0;
200
201 exponent_add = 0;
202 integer_length = 0;
203 fraction_length = 0;
204
205 /* First of all, read the integer part. */
206 phase = 4;
207
208 for (;;)
209 {
210 /* If we entered this iteration with phase == 4, we need to */
211 /* read a new byte. This also skips past the initial 0x1E. */
212 if ( phase )
213 {
214 p++;
215
216 /* Make sure we don't read past the end. */
217 if ( p >= limit )
218 goto Bad;
219 }
220
221 /* Get the nibble. */
222 nib = (FT_Int)( p[0] >> phase ) & 0xF;
223 phase = 4 - phase;
224
225 if ( nib == 0xE )
226 sign = 1;
227 else if ( nib > 9 )
228 break;
229 else
230 {
231 /* Increase exponent if we can't add the digit. */
232 if ( number >= 0xCCCCCCCL )
233 exponent_add++;
234 /* Skip leading zeros. */
235 else if ( nib || number )
236 {
237 integer_length++;
238 number = number * 10 + nib;
239 }
240 }
241 }
242
243 /* Read fraction part, if any. */
244 if ( nib == 0xA )
245 for (;;)
246 {
247 /* If we entered this iteration with phase == 4, we need */
248 /* to read a new byte. */
249 if ( phase )
250 {
251 p++;
252
253 /* Make sure we don't read past the end. */
254 if ( p >= limit )
255 goto Bad;
256 }
257
258 /* Get the nibble. */
259 nib = ( p[0] >> phase ) & 0xF;
260 phase = 4 - phase;
261 if ( nib >= 10 )
262 break;
263
264 /* Skip leading zeros if possible. */
265 if ( !nib && !number )
266 exponent_add--;
267 /* Only add digit if we don't overflow. */
268 else if ( number < 0xCCCCCCCL && fraction_length < 9 )
269 {
270 fraction_length++;
271 number = number * 10 + nib;
272 }
273 }
274
275 /* Read exponent, if any. */
276 if ( nib == 12 )
277 {
278 exponent_sign = 1;
279 nib = 11;
280 }
281
282 if ( nib == 11 )
283 {
284 for (;;)
285 {
286 /* If we entered this iteration with phase == 4, */
287 /* we need to read a new byte. */
288 if ( phase )
289 {
290 p++;
291
292 /* Make sure we don't read past the end. */
293 if ( p >= limit )
294 goto Bad;
295 }
296
297 /* Get the nibble. */
298 nib = ( p[0] >> phase ) & 0xF;
299 phase = 4 - phase;
300 if ( nib >= 10 )
301 break;
302
303 /* Arbitrarily limit exponent. */
304 if ( exponent > 1000 )
305 have_overflow = 1;
306 else
307 exponent = exponent * 10 + nib;
308 }
309
310 if ( exponent_sign )
311 exponent = -exponent;
312 }
313
314 if ( !number )
315 goto Exit;
316
317 if ( have_overflow )
318 {
319 if ( exponent_sign )
320 goto Underflow;
321 else
322 goto Overflow;
323 }
324
325 /* We don't check `power_ten' and `exponent_add'. */
326 exponent += power_ten + exponent_add;
327
328 if ( scaling )
329 {
330 /* Only use `fraction_length'. */
331 fraction_length += integer_length;
332 exponent += integer_length;
333
334 if ( fraction_length <= 5 )
335 {
336 if ( number > 0x7FFFL )
337 {
338 result = FT_DivFix( number, 10 );
339 *scaling = exponent - fraction_length + 1;
340 }
341 else
342 {
343 if ( exponent > 0 )
344 {
345 FT_Long new_fraction_length, shift;
346
347
348 /* Make `scaling' as small as possible. */
349 new_fraction_length = FT_MIN( exponent, 5 );
350 shift = new_fraction_length - fraction_length;
351
352 if ( shift > 0 )
353 {
354 exponent -= new_fraction_length;
355 number *= power_tens[shift];
356 if ( number > 0x7FFFL )
357 {
358 number /= 10;
359 exponent += 1;
360 }
361 }
362 else
363 exponent -= fraction_length;
364 }
365 else
366 exponent -= fraction_length;
367
368 result = (FT_Long)( (FT_ULong)number << 16 );
369 *scaling = exponent;
370 }
371 }
372 else
373 {
374 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
375 {
376 result = FT_DivFix( number, power_tens[fraction_length - 4] );
377 *scaling = exponent - 4;
378 }
379 else
380 {
381 result = FT_DivFix( number, power_tens[fraction_length - 5] );
382 *scaling = exponent - 5;
383 }
384 }
385 }
386 else
387 {
388 integer_length += exponent;
389 fraction_length -= exponent;
390
391 if ( integer_length > 5 )
392 goto Overflow;
393 if ( integer_length < -5 )
394 goto Underflow;
395
396 /* Remove non-significant digits. */
397 if ( integer_length < 0 )
398 {
399 number /= power_tens[-integer_length];
400 fraction_length += integer_length;
401 }
402
403 /* this can only happen if exponent was non-zero */
404 if ( fraction_length == 10 )
405 {
406 number /= 10;
407 fraction_length -= 1;
408 }
409
410 /* Convert into 16.16 format. */
411 if ( fraction_length > 0 )
412 {
413 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
414 goto Exit;
415
416 result = FT_DivFix( number, power_tens[fraction_length] );
417 }
418 else
419 {
420 number *= power_tens[-fraction_length];
421
422 if ( number > 0x7FFFL )
423 goto Overflow;
424
425 result = (FT_Long)( (FT_ULong)number << 16 );
426 }
427 }
428
429 Exit:
430 if ( sign )
431 result = -result;
432
433 return result;
434
435 Overflow:
436 result = 0x7FFFFFFFL;
437 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
438 goto Exit;
439
440 Underflow:
441 result = 0;
442 FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
443 goto Exit;
444
445 Bad:
446 result = 0;
447 FT_TRACE4(( "!!!END OF DATA:!!!" ));
448 goto Exit;
449 }
450
451
452 /* read a number, either integer or real */
453 FT_LOCAL_DEF( FT_Long )
454 cff_parse_num( CFF_Parser parser,
455 FT_Byte** d )
456 {
457 if ( **d == 30 )
458 {
459 /* binary-coded decimal is truncated to integer */
460 return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
461 }
462
463 else if ( **d == 255 )
464 {
465 /* 16.16 fixed point is used internally for CFF2 blend results. */
466 /* Since these are trusted values, a limit check is not needed. */
467
468 /* After the 255, 4 bytes give the number. */
469 /* The blend value is converted to integer, with rounding; */
470 /* due to the right-shift we don't need the lowest byte. */
471#if 0
472 return (FT_Short)(
473 ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
474 ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
475 ( (FT_UInt32)*( d[0] + 3 ) << 8 ) |
476 (FT_UInt32)*( d[0] + 4 ) ) + 0x8000U ) >> 16 );
477#else
478 return (FT_Short)(
479 ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
480 ( (FT_UInt32)*( d[0] + 2 ) << 8 ) |
481 (FT_UInt32)*( d[0] + 3 ) ) + 0x80U ) >> 8 );
482#endif
483 }
484
485 else
486 return cff_parse_integer( *d, parser->limit );
487 }
488
489
490 /* read a floating point number, either integer or real */
491 static FT_Fixed
492 do_fixed( CFF_Parser parser,
493 FT_Byte** d,
494 FT_Long scaling )
495 {
496 if ( **d == 30 )
497 return cff_parse_real( *d, parser->limit, scaling, NULL );
498 else
499 {
500 FT_Long val = cff_parse_integer( *d, parser->limit );
501
502
503 if ( scaling )
504 {
505 if ( FT_ABS( val ) > power_ten_limits[scaling] )
506 {
507 val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
508 goto Overflow;
509 }
510
511 val *= power_tens[scaling];
512 }
513
514 if ( val > 0x7FFF )
515 {
516 val = 0x7FFFFFFFL;
517 goto Overflow;
518 }
519 else if ( val < -0x7FFF )
520 {
521 val = -0x7FFFFFFFL;
522 goto Overflow;
523 }
524
525 return (FT_Long)( (FT_ULong)val << 16 );
526
527 Overflow:
528 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
529 return val;
530 }
531 }
532
533
534 /* read a floating point number, either integer or real */
535 static FT_Fixed
536 cff_parse_fixed( CFF_Parser parser,
537 FT_Byte** d )
538 {
539 return do_fixed( parser, d, 0 );
540 }
541
542
543 /* read a floating point number, either integer or real, */
544 /* but return `10^scaling' times the number read in */
545 static FT_Fixed
546 cff_parse_fixed_scaled( CFF_Parser parser,
547 FT_Byte** d,
548 FT_Long scaling )
549 {
550 return do_fixed( parser, d, scaling );
551 }
552
553
554 /* read a floating point number, either integer or real, */
555 /* and return it as precise as possible -- `scaling' returns */
556 /* the scaling factor (as a power of 10) */
557 static FT_Fixed
558 cff_parse_fixed_dynamic( CFF_Parser parser,
559 FT_Byte** d,
560 FT_Long* scaling )
561 {
562 FT_ASSERT( scaling );
563
564 if ( **d == 30 )
565 return cff_parse_real( *d, parser->limit, 0, scaling );
566 else
567 {
568 FT_Long number;
569 FT_Int integer_length;
570
571
572 number = cff_parse_integer( d[0], d[1] );
573
574 if ( number > 0x7FFFL )
575 {
576 for ( integer_length = 5; integer_length < 10; integer_length++ )
577 if ( number < power_tens[integer_length] )
578 break;
579
580 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
581 {
582 *scaling = integer_length - 4;
583 return FT_DivFix( number, power_tens[integer_length - 4] );
584 }
585 else
586 {
587 *scaling = integer_length - 5;
588 return FT_DivFix( number, power_tens[integer_length - 5] );
589 }
590 }
591 else
592 {
593 *scaling = 0;
594 return (FT_Long)( (FT_ULong)number << 16 );
595 }
596 }
597 }
598
599
600 static FT_Error
601 cff_parse_font_matrix( CFF_Parser parser )
602 {
603 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
604 FT_Matrix* matrix = &dict->font_matrix;
605 FT_Vector* offset = &dict->font_offset;
606 FT_ULong* upm = &dict->units_per_em;
607 FT_Byte** data = parser->stack;
608 FT_Error error = FT_ERR( Stack_Underflow );
609
610
611 if ( parser->top >= parser->stack + 6 )
612 {
613 FT_Fixed values[6];
614 FT_Long scalings[6];
615
616 FT_Long min_scaling, max_scaling;
617 int i;
618
619
620 error = FT_Err_Ok;
621
622 dict->has_font_matrix = TRUE;
623
624 /* We expect a well-formed font matrix, this is, the matrix elements */
625 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
626 /* loss of precision, we use the magnitude of the largest matrix */
627 /* element to scale all other elements. The scaling factor is then */
628 /* contained in the `units_per_em' value. */
629
630 max_scaling = FT_LONG_MIN;
631 min_scaling = FT_LONG_MAX;
632
633 for ( i = 0; i < 6; i++ )
634 {
635 values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
636 if ( values[i] )
637 {
638 if ( scalings[i] > max_scaling )
639 max_scaling = scalings[i];
640 if ( scalings[i] < min_scaling )
641 min_scaling = scalings[i];
642 }
643 }
644
645 if ( max_scaling < -9 ||
646 max_scaling > 0 ||
647 ( max_scaling - min_scaling ) < 0 ||
648 ( max_scaling - min_scaling ) > 9 )
649 {
650 /* Return default matrix in case of unlikely values. */
651
652 FT_TRACE1(( "cff_parse_font_matrix:"
653 " strange scaling values (minimum %d, maximum %d),\n"
654 " "
655 " using default matrix\n", min_scaling, max_scaling ));
656
657 matrix->xx = 0x10000L;
658 matrix->yx = 0;
659 matrix->xy = 0;
660 matrix->yy = 0x10000L;
661 offset->x = 0;
662 offset->y = 0;
663 *upm = 1;
664
665 goto Exit;
666 }
667
668 for ( i = 0; i < 6; i++ )
669 {
670 FT_Fixed value = values[i];
671 FT_Long divisor, half_divisor;
672
673
674 if ( !value )
675 continue;
676
677 divisor = power_tens[max_scaling - scalings[i]];
678 half_divisor = divisor >> 1;
679
680 if ( value < 0 )
681 {
682 if ( FT_LONG_MIN + half_divisor < value )
683 values[i] = ( value - half_divisor ) / divisor;
684 else
685 values[i] = FT_LONG_MIN / divisor;
686 }
687 else
688 {
689 if ( FT_LONG_MAX - half_divisor > value )
690 values[i] = ( value + half_divisor ) / divisor;
691 else
692 values[i] = FT_LONG_MAX / divisor;
693 }
694 }
695
696 matrix->xx = values[0];
697 matrix->yx = values[1];
698 matrix->xy = values[2];
699 matrix->yy = values[3];
700 offset->x = values[4];
701 offset->y = values[5];
702
703 *upm = (FT_ULong)power_tens[-max_scaling];
704
705 FT_TRACE4(( " [%f %f %f %f %f %f]\n",
706 (double)matrix->xx / *upm / 65536,
707 (double)matrix->xy / *upm / 65536,
708 (double)matrix->yx / *upm / 65536,
709 (double)matrix->yy / *upm / 65536,
710 (double)offset->x / *upm / 65536,
711 (double)offset->y / *upm / 65536 ));
712 }
713
714 Exit:
715 return error;
716 }
717
718
719 static FT_Error
720 cff_parse_font_bbox( CFF_Parser parser )
721 {
722 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
723 FT_BBox* bbox = &dict->font_bbox;
724 FT_Byte** data = parser->stack;
725 FT_Error error;
726
727
728 error = FT_ERR( Stack_Underflow );
729
730 if ( parser->top >= parser->stack + 4 )
731 {
732 bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
733 bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
734 bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
735 bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data ) );
736 error = FT_Err_Ok;
737
738 FT_TRACE4(( " [%d %d %d %d]\n",
739 bbox->xMin / 65536,
740 bbox->yMin / 65536,
741 bbox->xMax / 65536,
742 bbox->yMax / 65536 ));
743 }
744
745 return error;
746 }
747
748
749 static FT_Error
750 cff_parse_private_dict( CFF_Parser parser )
751 {
752 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
753 FT_Byte** data = parser->stack;
754 FT_Error error;
755
756
757 error = FT_ERR( Stack_Underflow );
758
759 if ( parser->top >= parser->stack + 2 )
760 {
761 FT_Long tmp;
762
763
764 tmp = cff_parse_num( parser, data++ );
765 if ( tmp < 0 )
766 {
767 FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
768 error = FT_THROW( Invalid_File_Format );
769 goto Fail;
770 }
771 dict->private_size = (FT_ULong)tmp;
772
773 tmp = cff_parse_num( parser, data );
774 if ( tmp < 0 )
775 {
776 FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
777 error = FT_THROW( Invalid_File_Format );
778 goto Fail;
779 }
780 dict->private_offset = (FT_ULong)tmp;
781
782 FT_TRACE4(( " %lu %lu\n",
783 dict->private_size, dict->private_offset ));
784
785 error = FT_Err_Ok;
786 }
787
788 Fail:
789 return error;
790 }
791
792
793 /* The `MultipleMaster' operator comes before any */
794 /* top DICT operators that contain T2 charstrings. */
795
796 static FT_Error
797 cff_parse_multiple_master( CFF_Parser parser )
798 {
799 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
800 FT_Error error;
801
802
803#ifdef FT_DEBUG_LEVEL_TRACE
804 /* beautify tracing message */
805 if ( ft_trace_levels[FT_COMPONENT] < 4 )
806 FT_TRACE1(( "Multiple Master CFFs not supported yet,"
807 " handling first master design only\n" ));
808 else
809 FT_TRACE1(( " (not supported yet,"
810 " handling first master design only)\n" ));
811#endif
812
813 error = FT_ERR( Stack_Underflow );
814
815 /* currently, we handle only the first argument */
816 if ( parser->top >= parser->stack + 5 )
817 {
818 FT_Long num_designs = cff_parse_num( parser, parser->stack );
819
820
821 if ( num_designs > 16 || num_designs < 2 )
822 {
823 FT_ERROR(( "cff_parse_multiple_master:"
824 " Invalid number of designs\n" ));
825 error = FT_THROW( Invalid_File_Format );
826 }
827 else
828 {
829 dict->num_designs = (FT_UShort)num_designs;
830 dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 );
831
832 parser->num_designs = dict->num_designs;
833 parser->num_axes = dict->num_axes;
834
835 error = FT_Err_Ok;
836 }
837 }
838
839 return error;
840 }
841
842
843 static FT_Error
844 cff_parse_cid_ros( CFF_Parser parser )
845 {
846 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
847 FT_Byte** data = parser->stack;
848 FT_Error error;
849
850
851 error = FT_ERR( Stack_Underflow );
852
853 if ( parser->top >= parser->stack + 3 )
854 {
855 dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
856 dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
857 if ( **data == 30 )
858 FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
859 dict->cid_supplement = cff_parse_num( parser, data );
860 if ( dict->cid_supplement < 0 )
861 FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
862 dict->cid_supplement ));
863 error = FT_Err_Ok;
864
865 FT_TRACE4(( " %d %d %d\n",
866 dict->cid_registry,
867 dict->cid_ordering,
868 dict->cid_supplement ));
869 }
870
871 return error;
872 }
873
874
875 static FT_Error
876 cff_parse_vsindex( CFF_Parser parser )
877 {
878 /* vsindex operator can only be used in a Private DICT */
879 CFF_Private priv = (CFF_Private)parser->object;
880 FT_Byte** data = parser->stack;
881 CFF_Blend blend;
882 FT_Error error;
883
884
885 if ( !priv || !priv->subfont )
886 {
887 error = FT_THROW( Invalid_File_Format );
888 goto Exit;
889 }
890
891 blend = &priv->subfont->blend;
892
893 if ( blend->usedBV )
894 {
895 FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
896 error = FT_THROW( Syntax_Error );
897 goto Exit;
898 }
899
900 priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
901
902 FT_TRACE4(( " %d\n", priv->vsindex ));
903
904 error = FT_Err_Ok;
905
906 Exit:
907 return error;
908 }
909
910
911 static FT_Error
912 cff_parse_blend( CFF_Parser parser )
913 {
914 /* blend operator can only be used in a Private DICT */
915 CFF_Private priv = (CFF_Private)parser->object;
916 CFF_SubFont subFont;
917 CFF_Blend blend;
918 FT_UInt numBlends;
919 FT_Error error;
920
921
922 if ( !priv || !priv->subfont )
923 {
924 error = FT_THROW( Invalid_File_Format );
925 goto Exit;
926 }
927
928 subFont = priv->subfont;
929 blend = &subFont->blend;
930
931 if ( cff_blend_check_vector( blend,
932 priv->vsindex,
933 subFont->lenNDV,
934 subFont->NDV ) )
935 {
936 error = cff_blend_build_vector( blend,
937 priv->vsindex,
938 subFont->lenNDV,
939 subFont->NDV );
940 if ( error )
941 goto Exit;
942 }
943
944 numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
945 if ( numBlends > parser->stackSize )
946 {
947 FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
948 error = FT_THROW( Invalid_File_Format );
949 goto Exit;
950 }
951
952 FT_TRACE4(( " %d value%s blended\n",
953 numBlends,
954 numBlends == 1 ? "" : "s" ));
955
956 error = cff_blend_doBlend( subFont, parser, numBlends );
957
958 blend->usedBV = TRUE;
959
960 Exit:
961 return error;
962 }
963
964
965 /* maxstack operator increases parser and operand stacks for CFF2 */
966 static FT_Error
967 cff_parse_maxstack( CFF_Parser parser )
968 {
969 /* maxstack operator can only be used in a Top DICT */
970 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
971 FT_Byte** data = parser->stack;
972 FT_Error error = FT_Err_Ok;
973
974
975 if ( !dict )
976 {
977 error = FT_THROW( Invalid_File_Format );
978 goto Exit;
979 }
980
981 dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
982 if ( dict->maxstack > CFF2_MAX_STACK )
983 dict->maxstack = CFF2_MAX_STACK;
984 if ( dict->maxstack < CFF2_DEFAULT_STACK )
985 dict->maxstack = CFF2_DEFAULT_STACK;
986
987 FT_TRACE4(( " %d\n", dict->maxstack ));
988
989 Exit:
990 return error;
991 }
992
993
994#define CFF_FIELD_NUM( code, name, id ) \
995 CFF_FIELD( code, name, id, cff_kind_num )
996#define CFF_FIELD_FIXED( code, name, id ) \
997 CFF_FIELD( code, name, id, cff_kind_fixed )
998#define CFF_FIELD_FIXED_1000( code, name, id ) \
999 CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
1000#define CFF_FIELD_STRING( code, name, id ) \
1001 CFF_FIELD( code, name, id, cff_kind_string )
1002#define CFF_FIELD_BOOL( code, name, id ) \
1003 CFF_FIELD( code, name, id, cff_kind_bool )
1004
1005
1006#ifndef FT_CONFIG_OPTION_PIC
1007
1008
1009#undef CFF_FIELD
1010#undef CFF_FIELD_DELTA
1011
1012
1013#ifndef FT_DEBUG_LEVEL_TRACE
1014
1015
1016#define CFF_FIELD_CALLBACK( code, name, id ) \
1017 { \
1018 cff_kind_callback, \
1019 code | CFFCODE, \
1020 0, 0, \
1021 cff_parse_ ## name, \
1022 0, 0 \
1023 },
1024
1025#define CFF_FIELD_BLEND( code, id ) \
1026 { \
1027 cff_kind_blend, \
1028 code | CFFCODE, \
1029 0, 0, \
1030 cff_parse_blend, \
1031 0, 0 \
1032 },
1033
1034#define CFF_FIELD( code, name, id, kind ) \
1035 { \
1036 kind, \
1037 code | CFFCODE, \
1038 FT_FIELD_OFFSET( name ), \
1039 FT_FIELD_SIZE( name ), \
1040 0, 0, 0 \
1041 },
1042
1043#define CFF_FIELD_DELTA( code, name, max, id ) \
1044 { \
1045 cff_kind_delta, \
1046 code | CFFCODE, \
1047 FT_FIELD_OFFSET( name ), \
1048 FT_FIELD_SIZE_DELTA( name ), \
1049 0, \
1050 max, \
1051 FT_FIELD_OFFSET( num_ ## name ) \
1052 },
1053
1054 static const CFF_Field_Handler cff_field_handlers[] =
1055 {
1056
1057#include "cfftoken.h"
1058
1059 { 0, 0, 0, 0, 0, 0, 0 }
1060 };
1061
1062
1063#else /* FT_DEBUG_LEVEL_TRACE */
1064
1065
1066
1067#define CFF_FIELD_CALLBACK( code, name, id ) \
1068 { \
1069 cff_kind_callback, \
1070 code | CFFCODE, \
1071 0, 0, \
1072 cff_parse_ ## name, \
1073 0, 0, \
1074 id \
1075 },
1076
1077#define CFF_FIELD_BLEND( code, id ) \
1078 { \
1079 cff_kind_blend, \
1080 code | CFFCODE, \
1081 0, 0, \
1082 cff_parse_blend, \
1083 0, 0, \
1084 id \
1085 },
1086
1087#define CFF_FIELD( code, name, id, kind ) \
1088 { \
1089 kind, \
1090 code | CFFCODE, \
1091 FT_FIELD_OFFSET( name ), \
1092 FT_FIELD_SIZE( name ), \
1093 0, 0, 0, \
1094 id \
1095 },
1096
1097#define CFF_FIELD_DELTA( code, name, max, id ) \
1098 { \
1099 cff_kind_delta, \
1100 code | CFFCODE, \
1101 FT_FIELD_OFFSET( name ), \
1102 FT_FIELD_SIZE_DELTA( name ), \
1103 0, \
1104 max, \
1105 FT_FIELD_OFFSET( num_ ## name ), \
1106 id \
1107 },
1108
1109 static const CFF_Field_Handler cff_field_handlers[] =
1110 {
1111
1112#include "cfftoken.h"
1113
1114 { 0, 0, 0, 0, 0, 0, 0, 0 }
1115 };
1116
1117
1118#endif /* FT_DEBUG_LEVEL_TRACE */
1119
1120
1121#else /* FT_CONFIG_OPTION_PIC */
1122
1123
1124 void
1125 FT_Destroy_Class_cff_field_handlers( FT_Library library,
1126 CFF_Field_Handler* clazz )
1127 {
1128 FT_Memory memory = library->memory;
1129
1130
1131 if ( clazz )
1132 FT_FREE( clazz );
1133 }
1134
1135
1136 FT_Error
1137 FT_Create_Class_cff_field_handlers( FT_Library library,
1138 CFF_Field_Handler** output_class )
1139 {
1140 CFF_Field_Handler* clazz = NULL;
1141 FT_Error error;
1142 FT_Memory memory = library->memory;
1143
1144 int i = 0;
1145
1146
1147#undef CFF_FIELD
1148#define CFF_FIELD( code, name, id, kind ) i++;
1149#undef CFF_FIELD_DELTA
1150#define CFF_FIELD_DELTA( code, name, max, id ) i++;
1151#undef CFF_FIELD_CALLBACK
1152#define CFF_FIELD_CALLBACK( code, name, id ) i++;
1153#undef CFF_FIELD_BLEND
1154#define CFF_FIELD_BLEND( code, id ) i++;
1155
1156#include "cfftoken.h"
1157
1158 i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
1159
1160 if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
1161 return error;
1162
1163 i = 0;
1164
1165
1166#ifndef FT_DEBUG_LEVEL_TRACE
1167
1168
1169#undef CFF_FIELD_CALLBACK
1170#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
1171 clazz[i].kind = cff_kind_callback; \
1172 clazz[i].code = code_ | CFFCODE; \
1173 clazz[i].offset = 0; \
1174 clazz[i].size = 0; \
1175 clazz[i].reader = cff_parse_ ## name_; \
1176 clazz[i].array_max = 0; \
1177 clazz[i].count_offset = 0; \
1178 i++;
1179
1180#undef CFF_FIELD
1181#define CFF_FIELD( code_, name_, id_, kind_ ) \
1182 clazz[i].kind = kind_; \
1183 clazz[i].code = code_ | CFFCODE; \
1184 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1185 clazz[i].size = FT_FIELD_SIZE( name_ ); \
1186 clazz[i].reader = 0; \
1187 clazz[i].array_max = 0; \
1188 clazz[i].count_offset = 0; \
1189 i++; \
1190
1191#undef CFF_FIELD_DELTA
1192#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
1193 clazz[i].kind = cff_kind_delta; \
1194 clazz[i].code = code_ | CFFCODE; \
1195 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1196 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
1197 clazz[i].reader = 0; \
1198 clazz[i].array_max = max_; \
1199 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
1200 i++;
1201
1202#undef CFF_FIELD_BLEND
1203#define CFF_FIELD_BLEND( code_, id_ ) \
1204 clazz[i].kind = cff_kind_blend; \
1205 clazz[i].code = code_ | CFFCODE; \
1206 clazz[i].offset = 0; \
1207 clazz[i].size = 0; \
1208 clazz[i].reader = cff_parse_blend; \
1209 clazz[i].array_max = 0; \
1210 clazz[i].count_offset = 0; \
1211 i++;
1212
1213#include "cfftoken.h"
1214
1215 clazz[i].kind = 0;
1216 clazz[i].code = 0;
1217 clazz[i].offset = 0;
1218 clazz[i].size = 0;
1219 clazz[i].reader = 0;
1220 clazz[i].array_max = 0;
1221 clazz[i].count_offset = 0;
1222
1223
1224#else /* FT_DEBUG_LEVEL_TRACE */
1225
1226
1227#undef CFF_FIELD_CALLBACK
1228#define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
1229 clazz[i].kind = cff_kind_callback; \
1230 clazz[i].code = code_ | CFFCODE; \
1231 clazz[i].offset = 0; \
1232 clazz[i].size = 0; \
1233 clazz[i].reader = cff_parse_ ## name_; \
1234 clazz[i].array_max = 0; \
1235 clazz[i].count_offset = 0; \
1236 clazz[i].id = id_; \
1237 i++;
1238
1239#undef CFF_FIELD
1240#define CFF_FIELD( code_, name_, id_, kind_ ) \
1241 clazz[i].kind = kind_; \
1242 clazz[i].code = code_ | CFFCODE; \
1243 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1244 clazz[i].size = FT_FIELD_SIZE( name_ ); \
1245 clazz[i].reader = 0; \
1246 clazz[i].array_max = 0; \
1247 clazz[i].count_offset = 0; \
1248 clazz[i].id = id_; \
1249 i++; \
1250
1251#undef CFF_FIELD_DELTA
1252#define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
1253 clazz[i].kind = cff_kind_delta; \
1254 clazz[i].code = code_ | CFFCODE; \
1255 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1256 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
1257 clazz[i].reader = 0; \
1258 clazz[i].array_max = max_; \
1259 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
1260 clazz[i].id = id_; \
1261 i++;
1262
1263#undef CFF_FIELD_BLEND
1264#define CFF_FIELD_BLEND( code_, id_ ) \
1265 clazz[i].kind = cff_kind_blend; \
1266 clazz[i].code = code_ | CFFCODE; \
1267 clazz[i].offset = 0; \
1268 clazz[i].size = 0; \
1269 clazz[i].reader = cff_parse_blend; \
1270 clazz[i].array_max = 0; \
1271 clazz[i].count_offset = 0; \
1272 clazz[i].id = id_; \
1273 i++;
1274
1275#include "cfftoken.h"
1276
1277 clazz[i].kind = 0;
1278 clazz[i].code = 0;
1279 clazz[i].offset = 0;
1280 clazz[i].size = 0;
1281 clazz[i].reader = 0;
1282 clazz[i].array_max = 0;
1283 clazz[i].count_offset = 0;
1284 clazz[i].id = 0;
1285
1286
1287#endif /* FT_DEBUG_LEVEL_TRACE */
1288
1289
1290 *output_class = clazz;
1291
1292 return FT_Err_Ok;
1293 }
1294
1295
1296#endif /* FT_CONFIG_OPTION_PIC */
1297
1298
1299 FT_LOCAL_DEF( FT_Error )
1300 cff_parser_run( CFF_Parser parser,
1301 FT_Byte* start,
1302 FT_Byte* limit )
1303 {
1304#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1305 PSAux_Service psaux;
1306#endif
1307
1308 FT_Byte* p = start;
1309 FT_Error error = FT_Err_Ok;
1310 FT_Library library = parser->library;
1311
1312 FT_UNUSED( library );
1313
1314
1315 parser->top = parser->stack;
1316 parser->start = start;
1317 parser->limit = limit;
1318 parser->cursor = start;
1319
1320 while ( p < limit )
1321 {
1322 FT_UInt v = *p;
1323
1324 /* Opcode 31 is legacy MM T2 operator, not a number. */
1325 /* Opcode 255 is reserved and should not appear in fonts; */
1326 /* it is used internally for CFF2 blends. */
1327 if ( v >= 27 && v != 31 && v != 255 )
1328 {
1329 /* it's a number; we will push its position on the stack */
1330 if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1331 goto Stack_Overflow;
1332
1333 *parser->top++ = p;
1334
1335 /* now, skip it */
1336 if ( v == 30 )
1337 {
1338 /* skip real number */
1339 p++;
1340 for (;;)
1341 {
1342 /* An unterminated floating point number at the */
1343 /* end of a dictionary is invalid but harmless. */
1344 if ( p >= limit )
1345 goto Exit;
1346 v = p[0] >> 4;
1347 if ( v == 15 )
1348 break;
1349 v = p[0] & 0xF;
1350 if ( v == 15 )
1351 break;
1352 p++;
1353 }
1354 }
1355 else if ( v == 28 )
1356 p += 2;
1357 else if ( v == 29 )
1358 p += 4;
1359 else if ( v > 246 )
1360 p += 1;
1361 }
1362#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1363 else if ( v == 31 )
1364 {
1365 /* a Type 2 charstring */
1366
1367 CFF_Decoder decoder;
1368 CFF_FontRec cff_rec;
1369 FT_Byte* charstring_base;
1370 FT_ULong charstring_len;
1371
1372 FT_Fixed* stack;
1373 FT_Byte* q;
1374
1375
1376 charstring_base = ++p;
1377
1378 /* search `endchar' operator */
1379 for (;;)
1380 {
1381 if ( p >= limit )
1382 goto Exit;
1383 if ( *p == 14 )
1384 break;
1385 p++;
1386 }
1387
1388 charstring_len = (FT_ULong)( p - charstring_base ) + 1;
1389
1390 /* construct CFF_Decoder object */
1391 FT_ZERO( &decoder );
1392 FT_ZERO( &cff_rec );
1393
1394 cff_rec.top_font.font_dict.num_designs = parser->num_designs;
1395 cff_rec.top_font.font_dict.num_axes = parser->num_axes;
1396 decoder.cff = &cff_rec;
1397
1398 psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" );
1399 if ( !psaux )
1400 {
1401 FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" ));
1402 error = FT_THROW( Missing_Module );
1403 goto Exit;
1404 }
1405
1406 error = psaux->cff_decoder_funcs->parse_charstrings_old(
1407 &decoder, charstring_base, charstring_len, 1 );
1408
1409 /* Now copy the stack data in the temporary decoder object, */
1410 /* converting it back to charstring number representations */
1411 /* (this is ugly, I know). */
1412 /* */
1413 /* We overwrite the original top DICT charstring under the */
1414 /* assumption that the charstring representation of the result */
1415 /* of `cff_decoder_parse_charstrings' is shorter, which should */
1416 /* be always true. */
1417
1418 q = charstring_base - 1;
1419 stack = decoder.stack;
1420
1421 while ( stack < decoder.top )
1422 {
1423 FT_ULong num;
1424 FT_Bool neg;
1425
1426
1427 if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1428 goto Stack_Overflow;
1429
1430 *parser->top++ = q;
1431
1432 if ( *stack < 0 )
1433 {
1434 num = (FT_ULong)-*stack;
1435 neg = 1;
1436 }
1437 else
1438 {
1439 num = (FT_ULong)*stack;
1440 neg = 0;
1441 }
1442
1443 if ( num & 0xFFFFU )
1444 {
1445 if ( neg )
1446 num = (FT_ULong)-num;
1447
1448 *q++ = 255;
1449 *q++ = ( num & 0xFF000000U ) >> 24;
1450 *q++ = ( num & 0x00FF0000U ) >> 16;
1451 *q++ = ( num & 0x0000FF00U ) >> 8;
1452 *q++ = num & 0x000000FFU;
1453 }
1454 else
1455 {
1456 num >>= 16;
1457
1458 if ( neg )
1459 {
1460 if ( num <= 107 )
1461 *q++ = (FT_Byte)( 139 - num );
1462 else if ( num <= 1131 )
1463 {
1464 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
1465 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1466 }
1467 else
1468 {
1469 num = (FT_ULong)-num;
1470
1471 *q++ = 28;
1472 *q++ = (FT_Byte)( num >> 8 );
1473 *q++ = (FT_Byte)( num & 0xFF );
1474 }
1475 }
1476 else
1477 {
1478 if ( num <= 107 )
1479 *q++ = (FT_Byte)( num + 139 );
1480 else if ( num <= 1131 )
1481 {
1482 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
1483 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1484 }
1485 else
1486 {
1487 *q++ = 28;
1488 *q++ = (FT_Byte)( num >> 8 );
1489 *q++ = (FT_Byte)( num & 0xFF );
1490 }
1491 }
1492 }
1493
1494 stack++;
1495 }
1496 }
1497#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
1498 else
1499 {
1500 /* This is not a number, hence it's an operator. Compute its code */
1501 /* and look for it in our current list. */
1502
1503 FT_UInt code;
1504 FT_UInt num_args;
1505 const CFF_Field_Handler* field;
1506
1507
1508 if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
1509 goto Stack_Overflow;
1510
1511 num_args = (FT_UInt)( parser->top - parser->stack );
1512 *parser->top = p;
1513 code = v;
1514
1515 if ( v == 12 )
1516 {
1517 /* two byte operator */
1518 p++;
1519 if ( p >= limit )
1520 goto Syntax_Error;
1521
1522 code = 0x100 | p[0];
1523 }
1524 code = code | parser->object_code;
1525
1526 for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
1527 {
1528 if ( field->code == (FT_Int)code )
1529 {
1530 /* we found our field's handler; read it */
1531 FT_Long val;
1532 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
1533
1534
1535#ifdef FT_DEBUG_LEVEL_TRACE
1536 FT_TRACE4(( " %s", field->id ));
1537#endif
1538
1539 /* check that we have enough arguments -- except for */
1540 /* delta encoded arrays, which can be empty */
1541 if ( field->kind != cff_kind_delta && num_args < 1 )
1542 goto Stack_Underflow;
1543
1544 switch ( field->kind )
1545 {
1546 case cff_kind_bool:
1547 case cff_kind_string:
1548 case cff_kind_num:
1549 val = cff_parse_num( parser, parser->stack );
1550 goto Store_Number;
1551
1552 case cff_kind_fixed:
1553 val = cff_parse_fixed( parser, parser->stack );
1554 goto Store_Number;
1555
1556 case cff_kind_fixed_thousand:
1557 val = cff_parse_fixed_scaled( parser, parser->stack, 3 );
1558
1559 Store_Number:
1560 switch ( field->size )
1561 {
1562 case (8 / FT_CHAR_BIT):
1563 *(FT_Byte*)q = (FT_Byte)val;
1564 break;
1565
1566 case (16 / FT_CHAR_BIT):
1567 *(FT_Short*)q = (FT_Short)val;
1568 break;
1569
1570 case (32 / FT_CHAR_BIT):
1571 *(FT_Int32*)q = (FT_Int)val;
1572 break;
1573
1574 default: /* for 64-bit systems */
1575 *(FT_Long*)q = val;
1576 }
1577
1578#ifdef FT_DEBUG_LEVEL_TRACE
1579 switch ( field->kind )
1580 {
1581 case cff_kind_bool:
1582 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1583 break;
1584
1585 case cff_kind_string:
1586 FT_TRACE4(( " %ld (SID)\n", val ));
1587 break;
1588
1589 case cff_kind_num:
1590 FT_TRACE4(( " %ld\n", val ));
1591 break;
1592
1593 case cff_kind_fixed:
1594 FT_TRACE4(( " %f\n", (double)val / 65536 ));
1595 break;
1596
1597 case cff_kind_fixed_thousand:
1598 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1599
1600 default:
1601 ; /* never reached */
1602 }
1603#endif
1604
1605 break;
1606
1607 case cff_kind_delta:
1608 {
1609 FT_Byte* qcount = (FT_Byte*)parser->object +
1610 field->count_offset;
1611
1612 FT_Byte** data = parser->stack;
1613
1614
1615 if ( num_args > field->array_max )
1616 num_args = field->array_max;
1617
1618 FT_TRACE4(( " [" ));
1619
1620 /* store count */
1621 *qcount = (FT_Byte)num_args;
1622
1623 val = 0;
1624 while ( num_args > 0 )
1625 {
1626 val = ADD_LONG( val, cff_parse_num( parser, data++ ) );
1627 switch ( field->size )
1628 {
1629 case (8 / FT_CHAR_BIT):
1630 *(FT_Byte*)q = (FT_Byte)val;
1631 break;
1632
1633 case (16 / FT_CHAR_BIT):
1634 *(FT_Short*)q = (FT_Short)val;
1635 break;
1636
1637 case (32 / FT_CHAR_BIT):
1638 *(FT_Int32*)q = (FT_Int)val;
1639 break;
1640
1641 default: /* for 64-bit systems */
1642 *(FT_Long*)q = val;
1643 }
1644
1645 FT_TRACE4(( " %ld", val ));
1646
1647 q += field->size;
1648 num_args--;
1649 }
1650
1651 FT_TRACE4(( "]\n" ));
1652 }
1653 break;
1654
1655 default: /* callback or blend */
1656 error = field->reader( parser );
1657 if ( error )
1658 goto Exit;
1659 }
1660 goto Found;
1661 }
1662 }
1663
1664 /* this is an unknown operator, or it is unsupported; */
1665 /* we will ignore it for now. */
1666
1667 Found:
1668 /* clear stack */
1669 /* TODO: could clear blend stack here, */
1670 /* but we don't have access to subFont */
1671 if ( field->kind != cff_kind_blend )
1672 parser->top = parser->stack;
1673 }
1674 p++;
1675 }
1676
1677 Exit:
1678 return error;
1679
1680 Stack_Overflow:
1681 error = FT_THROW( Invalid_Argument );
1682 goto Exit;
1683
1684 Stack_Underflow:
1685 error = FT_THROW( Invalid_Argument );
1686 goto Exit;
1687
1688 Syntax_Error:
1689 error = FT_THROW( Invalid_Argument );
1690 goto Exit;
1691 }
1692
1693
1694/* END */
1695