[CMAKE]
[reactos.git] / lib / 3rdparty / freetype / src / cff / cffparse.c
1 /***************************************************************************/
2 /* */
3 /* cffparse.c */
4 /* */
5 /* CFF token stream parser (body) */
6 /* */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010 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
24 #include "cfferrs.h"
25 #include "cffpic.h"
26
27
28 /*************************************************************************/
29 /* */
30 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
31 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
32 /* messages during execution. */
33 /* */
34 #undef FT_COMPONENT
35 #define FT_COMPONENT trace_cffparse
36
37
38
39
40 FT_LOCAL_DEF( void )
41 cff_parser_init( CFF_Parser parser,
42 FT_UInt code,
43 void* object,
44 FT_Library library)
45 {
46 FT_MEM_ZERO( parser, sizeof ( *parser ) );
47
48 parser->top = parser->stack;
49 parser->object_code = code;
50 parser->object = object;
51 parser->library = library;
52 }
53
54
55 /* read an integer */
56 static FT_Long
57 cff_parse_integer( FT_Byte* start,
58 FT_Byte* limit )
59 {
60 FT_Byte* p = start;
61 FT_Int v = *p++;
62 FT_Long val = 0;
63
64
65 if ( v == 28 )
66 {
67 if ( p + 2 > limit )
68 goto Bad;
69
70 val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
71 p += 2;
72 }
73 else if ( v == 29 )
74 {
75 if ( p + 4 > limit )
76 goto Bad;
77
78 val = ( (FT_Long)p[0] << 24 ) |
79 ( (FT_Long)p[1] << 16 ) |
80 ( (FT_Long)p[2] << 8 ) |
81 p[3];
82 p += 4;
83 }
84 else if ( v < 247 )
85 {
86 val = v - 139;
87 }
88 else if ( v < 251 )
89 {
90 if ( p + 1 > limit )
91 goto Bad;
92
93 val = ( v - 247 ) * 256 + p[0] + 108;
94 p++;
95 }
96 else
97 {
98 if ( p + 1 > limit )
99 goto Bad;
100
101 val = -( v - 251 ) * 256 - p[0] - 108;
102 p++;
103 }
104
105 Exit:
106 return val;
107
108 Bad:
109 val = 0;
110 goto Exit;
111 }
112
113
114 static const FT_Long power_tens[] =
115 {
116 1L,
117 10L,
118 100L,
119 1000L,
120 10000L,
121 100000L,
122 1000000L,
123 10000000L,
124 100000000L,
125 1000000000L
126 };
127
128
129 /* read a real */
130 static FT_Fixed
131 cff_parse_real( FT_Byte* start,
132 FT_Byte* limit,
133 FT_Long power_ten,
134 FT_Long* scaling )
135 {
136 FT_Byte* p = start;
137 FT_UInt nib;
138 FT_UInt phase;
139
140 FT_Long result, number, exponent;
141 FT_Int sign = 0, exponent_sign = 0;
142 FT_Long exponent_add, integer_length, fraction_length;
143
144
145 if ( scaling )
146 *scaling = 0;
147
148 result = 0;
149
150 number = 0;
151 exponent = 0;
152
153 exponent_add = 0;
154 integer_length = 0;
155 fraction_length = 0;
156
157 /* First of all, read the integer part. */
158 phase = 4;
159
160 for (;;)
161 {
162 /* If we entered this iteration with phase == 4, we need to */
163 /* read a new byte. This also skips past the initial 0x1E. */
164 if ( phase )
165 {
166 p++;
167
168 /* Make sure we don't read past the end. */
169 if ( p >= limit )
170 goto Exit;
171 }
172
173 /* Get the nibble. */
174 nib = ( p[0] >> phase ) & 0xF;
175 phase = 4 - phase;
176
177 if ( nib == 0xE )
178 sign = 1;
179 else if ( nib > 9 )
180 break;
181 else
182 {
183 /* Increase exponent if we can't add the digit. */
184 if ( number >= 0xCCCCCCCL )
185 exponent_add++;
186 /* Skip leading zeros. */
187 else if ( nib || number )
188 {
189 integer_length++;
190 number = number * 10 + nib;
191 }
192 }
193 }
194
195 /* Read fraction part, if any. */
196 if ( nib == 0xa )
197 for (;;)
198 {
199 /* If we entered this iteration with phase == 4, we need */
200 /* to read a new byte. */
201 if ( phase )
202 {
203 p++;
204
205 /* Make sure we don't read past the end. */
206 if ( p >= limit )
207 goto Exit;
208 }
209
210 /* Get the nibble. */
211 nib = ( p[0] >> phase ) & 0xF;
212 phase = 4 - phase;
213 if ( nib >= 10 )
214 break;
215
216 /* Skip leading zeros if possible. */
217 if ( !nib && !number )
218 exponent_add--;
219 /* Only add digit if we don't overflow. */
220 else if ( number < 0xCCCCCCCL && fraction_length < 9 )
221 {
222 fraction_length++;
223 number = number * 10 + nib;
224 }
225 }
226
227 /* Read exponent, if any. */
228 if ( nib == 12 )
229 {
230 exponent_sign = 1;
231 nib = 11;
232 }
233
234 if ( nib == 11 )
235 {
236 for (;;)
237 {
238 /* If we entered this iteration with phase == 4, */
239 /* we need to read a new byte. */
240 if ( phase )
241 {
242 p++;
243
244 /* Make sure we don't read past the end. */
245 if ( p >= limit )
246 goto Exit;
247 }
248
249 /* Get the nibble. */
250 nib = ( p[0] >> phase ) & 0xF;
251 phase = 4 - phase;
252 if ( nib >= 10 )
253 break;
254
255 exponent = exponent * 10 + nib;
256
257 /* Arbitrarily limit exponent. */
258 if ( exponent > 1000 )
259 goto Exit;
260 }
261
262 if ( exponent_sign )
263 exponent = -exponent;
264 }
265
266 /* We don't check `power_ten' and `exponent_add'. */
267 exponent += power_ten + exponent_add;
268
269 if ( scaling )
270 {
271 /* Only use `fraction_length'. */
272 fraction_length += integer_length;
273 exponent += integer_length;
274
275 if ( fraction_length <= 5 )
276 {
277 if ( number > 0x7FFFL )
278 {
279 result = FT_DivFix( number, 10 );
280 *scaling = exponent - fraction_length + 1;
281 }
282 else
283 {
284 if ( exponent > 0 )
285 {
286 FT_Long new_fraction_length, shift;
287
288
289 /* Make `scaling' as small as possible. */
290 new_fraction_length = FT_MIN( exponent, 5 );
291 exponent -= new_fraction_length;
292 shift = new_fraction_length - fraction_length;
293
294 number *= power_tens[shift];
295 if ( number > 0x7FFFL )
296 {
297 number /= 10;
298 exponent += 1;
299 }
300 }
301 else
302 exponent -= fraction_length;
303
304 result = number << 16;
305 *scaling = exponent;
306 }
307 }
308 else
309 {
310 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
311 {
312 result = FT_DivFix( number, power_tens[fraction_length - 4] );
313 *scaling = exponent - 4;
314 }
315 else
316 {
317 result = FT_DivFix( number, power_tens[fraction_length - 5] );
318 *scaling = exponent - 5;
319 }
320 }
321 }
322 else
323 {
324 integer_length += exponent;
325 fraction_length -= exponent;
326
327 /* Check for overflow and underflow. */
328 if ( FT_ABS( integer_length ) > 5 )
329 goto Exit;
330
331 /* Remove non-significant digits. */
332 if ( integer_length < 0 )
333 {
334 number /= power_tens[-integer_length];
335 fraction_length += integer_length;
336 }
337
338 /* this can only happen if exponent was non-zero */
339 if ( fraction_length == 10 )
340 {
341 number /= 10;
342 fraction_length -= 1;
343 }
344
345 /* Convert into 16.16 format. */
346 if ( fraction_length > 0 )
347 {
348 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
349 goto Exit;
350
351 result = FT_DivFix( number, power_tens[fraction_length] );
352 }
353 else
354 {
355 number *= power_tens[-fraction_length];
356
357 if ( number > 0x7FFFL )
358 goto Exit;
359
360 result = number << 16;
361 }
362 }
363
364 if ( sign )
365 result = -result;
366
367 Exit:
368 return result;
369 }
370
371
372 /* read a number, either integer or real */
373 static FT_Long
374 cff_parse_num( FT_Byte** d )
375 {
376 return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
377 : cff_parse_integer( d[0], d[1] );
378 }
379
380
381 /* read a floating point number, either integer or real */
382 static FT_Fixed
383 cff_parse_fixed( FT_Byte** d )
384 {
385 return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
386 : cff_parse_integer( d[0], d[1] ) << 16;
387 }
388
389
390 /* read a floating point number, either integer or real, */
391 /* but return `10^scaling' times the number read in */
392 static FT_Fixed
393 cff_parse_fixed_scaled( FT_Byte** d,
394 FT_Long scaling )
395 {
396 return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
397 : ( cff_parse_integer( d[0], d[1] ) *
398 power_tens[scaling] ) << 16;
399 }
400
401
402 /* read a floating point number, either integer or real, */
403 /* and return it as precise as possible -- `scaling' returns */
404 /* the scaling factor (as a power of 10) */
405 static FT_Fixed
406 cff_parse_fixed_dynamic( FT_Byte** d,
407 FT_Long* scaling )
408 {
409 FT_ASSERT( scaling );
410
411 if ( **d == 30 )
412 return cff_parse_real( d[0], d[1], 0, scaling );
413 else
414 {
415 FT_Long number;
416 FT_Int integer_length;
417
418
419 number = cff_parse_integer( d[0], d[1] );
420
421 if ( number > 0x7FFFL )
422 {
423 for ( integer_length = 5; integer_length < 10; integer_length++ )
424 if ( number < power_tens[integer_length] )
425 break;
426
427 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
428 {
429 *scaling = integer_length - 4;
430 return FT_DivFix( number, power_tens[integer_length - 4] );
431 }
432 else
433 {
434 *scaling = integer_length - 5;
435 return FT_DivFix( number, power_tens[integer_length - 5] );
436 }
437 }
438 else
439 {
440 *scaling = 0;
441 return number << 16;
442 }
443 }
444 }
445
446
447 static FT_Error
448 cff_parse_font_matrix( CFF_Parser parser )
449 {
450 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
451 FT_Matrix* matrix = &dict->font_matrix;
452 FT_Vector* offset = &dict->font_offset;
453 FT_ULong* upm = &dict->units_per_em;
454 FT_Byte** data = parser->stack;
455 FT_Error error = CFF_Err_Stack_Underflow;
456
457
458 if ( parser->top >= parser->stack + 6 )
459 {
460 FT_Long scaling;
461
462
463 error = CFF_Err_Ok;
464
465 /* We expect a well-formed font matrix, this is, the matrix elements */
466 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
467 /* loss of precision, we use the magnitude of element `xx' to scale */
468 /* all other elements. The scaling factor is then contained in the */
469 /* `units_per_em' value. */
470
471 matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
472
473 scaling = -scaling;
474
475 if ( scaling < 0 || scaling > 9 )
476 {
477 /* Return default matrix in case of unlikely values. */
478 matrix->xx = 0x10000L;
479 matrix->yx = 0;
480 matrix->yx = 0;
481 matrix->yy = 0x10000L;
482 offset->x = 0;
483 offset->y = 0;
484 *upm = 1;
485
486 goto Exit;
487 }
488
489 matrix->yx = cff_parse_fixed_scaled( data++, scaling );
490 matrix->xy = cff_parse_fixed_scaled( data++, scaling );
491 matrix->yy = cff_parse_fixed_scaled( data++, scaling );
492 offset->x = cff_parse_fixed_scaled( data++, scaling );
493 offset->y = cff_parse_fixed_scaled( data, scaling );
494
495 *upm = power_tens[scaling];
496 }
497
498 Exit:
499 return error;
500 }
501
502
503 static FT_Error
504 cff_parse_font_bbox( CFF_Parser parser )
505 {
506 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
507 FT_BBox* bbox = &dict->font_bbox;
508 FT_Byte** data = parser->stack;
509 FT_Error error;
510
511
512 error = CFF_Err_Stack_Underflow;
513
514 if ( parser->top >= parser->stack + 4 )
515 {
516 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
517 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
518 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
519 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
520 error = CFF_Err_Ok;
521 }
522
523 return error;
524 }
525
526
527 static FT_Error
528 cff_parse_private_dict( CFF_Parser parser )
529 {
530 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
531 FT_Byte** data = parser->stack;
532 FT_Error error;
533
534
535 error = CFF_Err_Stack_Underflow;
536
537 if ( parser->top >= parser->stack + 2 )
538 {
539 dict->private_size = cff_parse_num( data++ );
540 dict->private_offset = cff_parse_num( data );
541 error = CFF_Err_Ok;
542 }
543
544 return error;
545 }
546
547
548 static FT_Error
549 cff_parse_cid_ros( CFF_Parser parser )
550 {
551 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
552 FT_Byte** data = parser->stack;
553 FT_Error error;
554
555
556 error = CFF_Err_Stack_Underflow;
557
558 if ( parser->top >= parser->stack + 3 )
559 {
560 dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
561 dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
562 if ( **data == 30 )
563 FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
564 dict->cid_supplement = cff_parse_num( data );
565 if ( dict->cid_supplement < 0 )
566 FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
567 dict->cid_supplement ));
568 error = CFF_Err_Ok;
569 }
570
571 return error;
572 }
573
574
575 #define CFF_FIELD_NUM( code, name ) \
576 CFF_FIELD( code, name, cff_kind_num )
577 #define CFF_FIELD_FIXED( code, name ) \
578 CFF_FIELD( code, name, cff_kind_fixed )
579 #define CFF_FIELD_FIXED_1000( code, name ) \
580 CFF_FIELD( code, name, cff_kind_fixed_thousand )
581 #define CFF_FIELD_STRING( code, name ) \
582 CFF_FIELD( code, name, cff_kind_string )
583 #define CFF_FIELD_BOOL( code, name ) \
584 CFF_FIELD( code, name, cff_kind_bool )
585 #define CFF_FIELD_DELTA( code, name, max ) \
586 CFF_FIELD( code, name, cff_kind_delta )
587
588 #define CFFCODE_TOPDICT 0x1000
589 #define CFFCODE_PRIVATE 0x2000
590
591 #ifndef FT_CONFIG_OPTION_PIC
592
593 #define CFF_FIELD_CALLBACK( code, name ) \
594 { \
595 cff_kind_callback, \
596 code | CFFCODE, \
597 0, 0, \
598 cff_parse_ ## name, \
599 0, 0 \
600 },
601
602 #undef CFF_FIELD
603 #define CFF_FIELD( code, name, kind ) \
604 { \
605 kind, \
606 code | CFFCODE, \
607 FT_FIELD_OFFSET( name ), \
608 FT_FIELD_SIZE( name ), \
609 0, 0, 0 \
610 },
611
612 #undef CFF_FIELD_DELTA
613 #define CFF_FIELD_DELTA( code, name, max ) \
614 { \
615 cff_kind_delta, \
616 code | CFFCODE, \
617 FT_FIELD_OFFSET( name ), \
618 FT_FIELD_SIZE_DELTA( name ), \
619 0, \
620 max, \
621 FT_FIELD_OFFSET( num_ ## name ) \
622 },
623
624 static const CFF_Field_Handler cff_field_handlers[] =
625 {
626
627 #include "cfftoken.h"
628
629 { 0, 0, 0, 0, 0, 0, 0 }
630 };
631
632
633 #else /* FT_CONFIG_OPTION_PIC */
634
635 void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
636 {
637 FT_Memory memory = library->memory;
638 if ( clazz )
639 FT_FREE( clazz );
640 }
641
642 FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
643 {
644 CFF_Field_Handler* clazz;
645 FT_Error error;
646 FT_Memory memory = library->memory;
647 int i=0;
648
649 #undef CFF_FIELD
650 #undef CFF_FIELD_DELTA
651 #undef CFF_FIELD_CALLBACK
652 #define CFF_FIELD_CALLBACK( code, name ) i++;
653 #define CFF_FIELD( code, name, kind ) i++;
654 #define CFF_FIELD_DELTA( code, name, max ) i++;
655
656 #include "cfftoken.h"
657 i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
658
659 if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
660 return error;
661
662 i=0;
663 #undef CFF_FIELD
664 #undef CFF_FIELD_DELTA
665 #undef CFF_FIELD_CALLBACK
666
667 #define CFF_FIELD_CALLBACK( code_, name_ ) \
668 clazz[i].kind = cff_kind_callback; \
669 clazz[i].code = code_ | CFFCODE; \
670 clazz[i].offset = 0; \
671 clazz[i].size = 0; \
672 clazz[i].reader = cff_parse_ ## name_; \
673 clazz[i].array_max = 0; \
674 clazz[i].count_offset = 0; \
675 i++;
676
677 #undef CFF_FIELD
678 #define CFF_FIELD( code_, name_, kind_ ) \
679 clazz[i].kind = kind_; \
680 clazz[i].code = code_ | CFFCODE; \
681 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
682 clazz[i].size = FT_FIELD_SIZE( name_ ); \
683 clazz[i].reader = 0; \
684 clazz[i].array_max = 0; \
685 clazz[i].count_offset = 0; \
686 i++; \
687
688 #undef CFF_FIELD_DELTA
689 #define CFF_FIELD_DELTA( code_, name_, max_ ) \
690 clazz[i].kind = cff_kind_delta; \
691 clazz[i].code = code_ | CFFCODE; \
692 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
693 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
694 clazz[i].reader = 0; \
695 clazz[i].array_max = max_; \
696 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
697 i++;
698
699 #include "cfftoken.h"
700
701 clazz[i].kind = 0;
702 clazz[i].code = 0;
703 clazz[i].offset = 0;
704 clazz[i].size = 0;
705 clazz[i].reader = 0;
706 clazz[i].array_max = 0;
707 clazz[i].count_offset = 0;
708
709 *output_class = clazz;
710 return CFF_Err_Ok;
711 }
712
713
714 #endif /* FT_CONFIG_OPTION_PIC */
715
716
717 FT_LOCAL_DEF( FT_Error )
718 cff_parser_run( CFF_Parser parser,
719 FT_Byte* start,
720 FT_Byte* limit )
721 {
722 FT_Byte* p = start;
723 FT_Error error = CFF_Err_Ok;
724 FT_Library library = parser->library;
725 FT_UNUSED(library);
726
727
728 parser->top = parser->stack;
729 parser->start = start;
730 parser->limit = limit;
731 parser->cursor = start;
732
733 while ( p < limit )
734 {
735 FT_UInt v = *p;
736
737
738 if ( v >= 27 && v != 31 )
739 {
740 /* it's a number; we will push its position on the stack */
741 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
742 goto Stack_Overflow;
743
744 *parser->top ++ = p;
745
746 /* now, skip it */
747 if ( v == 30 )
748 {
749 /* skip real number */
750 p++;
751 for (;;)
752 {
753 /* An unterminated floating point number at the */
754 /* end of a dictionary is invalid but harmless. */
755 if ( p >= limit )
756 goto Exit;
757 v = p[0] >> 4;
758 if ( v == 15 )
759 break;
760 v = p[0] & 0xF;
761 if ( v == 15 )
762 break;
763 p++;
764 }
765 }
766 else if ( v == 28 )
767 p += 2;
768 else if ( v == 29 )
769 p += 4;
770 else if ( v > 246 )
771 p += 1;
772 }
773 else
774 {
775 /* This is not a number, hence it's an operator. Compute its code */
776 /* and look for it in our current list. */
777
778 FT_UInt code;
779 FT_UInt num_args = (FT_UInt)
780 ( parser->top - parser->stack );
781 const CFF_Field_Handler* field;
782
783
784 *parser->top = p;
785 code = v;
786 if ( v == 12 )
787 {
788 /* two byte operator */
789 p++;
790 if ( p >= limit )
791 goto Syntax_Error;
792
793 code = 0x100 | p[0];
794 }
795 code = code | parser->object_code;
796
797 for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
798 {
799 if ( field->code == (FT_Int)code )
800 {
801 /* we found our field's handler; read it */
802 FT_Long val;
803 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
804
805
806 /* check that we have enough arguments -- except for */
807 /* delta encoded arrays, which can be empty */
808 if ( field->kind != cff_kind_delta && num_args < 1 )
809 goto Stack_Underflow;
810
811 switch ( field->kind )
812 {
813 case cff_kind_bool:
814 case cff_kind_string:
815 case cff_kind_num:
816 val = cff_parse_num( parser->stack );
817 goto Store_Number;
818
819 case cff_kind_fixed:
820 val = cff_parse_fixed( parser->stack );
821 goto Store_Number;
822
823 case cff_kind_fixed_thousand:
824 val = cff_parse_fixed_scaled( parser->stack, 3 );
825
826 Store_Number:
827 switch ( field->size )
828 {
829 case (8 / FT_CHAR_BIT):
830 *(FT_Byte*)q = (FT_Byte)val;
831 break;
832
833 case (16 / FT_CHAR_BIT):
834 *(FT_Short*)q = (FT_Short)val;
835 break;
836
837 case (32 / FT_CHAR_BIT):
838 *(FT_Int32*)q = (FT_Int)val;
839 break;
840
841 default: /* for 64-bit systems */
842 *(FT_Long*)q = val;
843 }
844 break;
845
846 case cff_kind_delta:
847 {
848 FT_Byte* qcount = (FT_Byte*)parser->object +
849 field->count_offset;
850
851 FT_Byte** data = parser->stack;
852
853
854 if ( num_args > field->array_max )
855 num_args = field->array_max;
856
857 /* store count */
858 *qcount = (FT_Byte)num_args;
859
860 val = 0;
861 while ( num_args > 0 )
862 {
863 val += cff_parse_num( data++ );
864 switch ( field->size )
865 {
866 case (8 / FT_CHAR_BIT):
867 *(FT_Byte*)q = (FT_Byte)val;
868 break;
869
870 case (16 / FT_CHAR_BIT):
871 *(FT_Short*)q = (FT_Short)val;
872 break;
873
874 case (32 / FT_CHAR_BIT):
875 *(FT_Int32*)q = (FT_Int)val;
876 break;
877
878 default: /* for 64-bit systems */
879 *(FT_Long*)q = val;
880 }
881
882 q += field->size;
883 num_args--;
884 }
885 }
886 break;
887
888 default: /* callback */
889 error = field->reader( parser );
890 if ( error )
891 goto Exit;
892 }
893 goto Found;
894 }
895 }
896
897 /* this is an unknown operator, or it is unsupported; */
898 /* we will ignore it for now. */
899
900 Found:
901 /* clear stack */
902 parser->top = parser->stack;
903 }
904 p++;
905 }
906
907 Exit:
908 return error;
909
910 Stack_Overflow:
911 error = CFF_Err_Invalid_Argument;
912 goto Exit;
913
914 Stack_Underflow:
915 error = CFF_Err_Invalid_Argument;
916 goto Exit;
917
918 Syntax_Error:
919 error = CFF_Err_Invalid_Argument;
920 goto Exit;
921 }
922
923
924 /* END */