1 | /**************************************************************************** |
2 | * |
3 | * cffparse.c |
4 | * |
5 | * CFF token stream parser (body) |
6 | * |
7 | * Copyright (C) 1996-2019 by |
8 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
9 | * |
10 | * This file is part of the FreeType project, and may only be used, |
11 | * modified, and distributed under the terms of the FreeType project |
12 | * license, LICENSE.TXT. By continuing to use, modify, or distribute |
13 | * this file you indicate that you have read the license and |
14 | * understand and accept it fully. |
15 | * |
16 | */ |
17 | |
18 | |
19 | #include <ft2build.h> |
20 | #include "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 | #include FT_LIST_H |
26 | |
27 | #include "cfferrs.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 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 | |
609 | |
610 | if ( parser->top >= parser->stack + 6 ) |
611 | { |
612 | FT_Fixed values[6]; |
613 | FT_Long scalings[6]; |
614 | |
615 | FT_Long min_scaling, max_scaling; |
616 | int i; |
617 | |
618 | |
619 | dict->has_font_matrix = TRUE; |
620 | |
621 | /* We expect a well-formed font matrix, this is, the matrix elements */ |
622 | /* `xx' and `yy' are of approximately the same magnitude. To avoid */ |
623 | /* loss of precision, we use the magnitude of the largest matrix */ |
624 | /* element to scale all other elements. The scaling factor is then */ |
625 | /* contained in the `units_per_em' value. */ |
626 | |
627 | max_scaling = FT_LONG_MIN; |
628 | min_scaling = FT_LONG_MAX; |
629 | |
630 | for ( i = 0; i < 6; i++ ) |
631 | { |
632 | values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] ); |
633 | if ( values[i] ) |
634 | { |
635 | if ( scalings[i] > max_scaling ) |
636 | max_scaling = scalings[i]; |
637 | if ( scalings[i] < min_scaling ) |
638 | min_scaling = scalings[i]; |
639 | } |
640 | } |
641 | |
642 | if ( max_scaling < -9 || |
643 | max_scaling > 0 || |
644 | ( max_scaling - min_scaling ) < 0 || |
645 | ( max_scaling - min_scaling ) > 9 ) |
646 | { |
647 | FT_TRACE1(( "cff_parse_font_matrix:" |
648 | " strange scaling values (minimum %d, maximum %d),\n" |
649 | " " |
650 | " using default matrix\n" , min_scaling, max_scaling )); |
651 | goto Unlikely; |
652 | } |
653 | |
654 | for ( i = 0; i < 6; i++ ) |
655 | { |
656 | FT_Fixed value = values[i]; |
657 | FT_Long divisor, half_divisor; |
658 | |
659 | |
660 | if ( !value ) |
661 | continue; |
662 | |
663 | divisor = power_tens[max_scaling - scalings[i]]; |
664 | half_divisor = divisor >> 1; |
665 | |
666 | if ( value < 0 ) |
667 | { |
668 | if ( FT_LONG_MIN + half_divisor < value ) |
669 | values[i] = ( value - half_divisor ) / divisor; |
670 | else |
671 | values[i] = FT_LONG_MIN / divisor; |
672 | } |
673 | else |
674 | { |
675 | if ( FT_LONG_MAX - half_divisor > value ) |
676 | values[i] = ( value + half_divisor ) / divisor; |
677 | else |
678 | values[i] = FT_LONG_MAX / divisor; |
679 | } |
680 | } |
681 | |
682 | matrix->xx = values[0]; |
683 | matrix->yx = values[1]; |
684 | matrix->xy = values[2]; |
685 | matrix->yy = values[3]; |
686 | offset->x = values[4]; |
687 | offset->y = values[5]; |
688 | |
689 | *upm = (FT_ULong)power_tens[-max_scaling]; |
690 | |
691 | FT_TRACE4(( " [%f %f %f %f %f %f]\n" , |
692 | (double)matrix->xx / *upm / 65536, |
693 | (double)matrix->xy / *upm / 65536, |
694 | (double)matrix->yx / *upm / 65536, |
695 | (double)matrix->yy / *upm / 65536, |
696 | (double)offset->x / *upm / 65536, |
697 | (double)offset->y / *upm / 65536 )); |
698 | |
699 | if ( !FT_Matrix_Check( matrix ) ) |
700 | { |
701 | FT_TRACE1(( "cff_parse_font_matrix:" |
702 | " degenerate values, using default matrix\n" )); |
703 | goto Unlikely; |
704 | } |
705 | |
706 | return FT_Err_Ok; |
707 | } |
708 | else |
709 | return FT_THROW( Stack_Underflow ); |
710 | |
711 | Unlikely: |
712 | /* Return default matrix in case of unlikely values. */ |
713 | |
714 | matrix->xx = 0x10000L; |
715 | matrix->yx = 0; |
716 | matrix->xy = 0; |
717 | matrix->yy = 0x10000L; |
718 | offset->x = 0; |
719 | offset->y = 0; |
720 | *upm = 1; |
721 | |
722 | return FT_Err_Ok; |
723 | } |
724 | |
725 | |
726 | static FT_Error |
727 | cff_parse_font_bbox( CFF_Parser parser ) |
728 | { |
729 | CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; |
730 | FT_BBox* bbox = &dict->font_bbox; |
731 | FT_Byte** data = parser->stack; |
732 | FT_Error error; |
733 | |
734 | |
735 | error = FT_ERR( Stack_Underflow ); |
736 | |
737 | if ( parser->top >= parser->stack + 4 ) |
738 | { |
739 | bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); |
740 | bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); |
741 | bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); |
742 | bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data ) ); |
743 | error = FT_Err_Ok; |
744 | |
745 | FT_TRACE4(( " [%d %d %d %d]\n" , |
746 | bbox->xMin / 65536, |
747 | bbox->yMin / 65536, |
748 | bbox->xMax / 65536, |
749 | bbox->yMax / 65536 )); |
750 | } |
751 | |
752 | return error; |
753 | } |
754 | |
755 | |
756 | static FT_Error |
757 | cff_parse_private_dict( CFF_Parser parser ) |
758 | { |
759 | CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; |
760 | FT_Byte** data = parser->stack; |
761 | FT_Error error; |
762 | |
763 | |
764 | error = FT_ERR( Stack_Underflow ); |
765 | |
766 | if ( parser->top >= parser->stack + 2 ) |
767 | { |
768 | FT_Long tmp; |
769 | |
770 | |
771 | tmp = cff_parse_num( parser, data++ ); |
772 | if ( tmp < 0 ) |
773 | { |
774 | FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); |
775 | error = FT_THROW( Invalid_File_Format ); |
776 | goto Fail; |
777 | } |
778 | dict->private_size = (FT_ULong)tmp; |
779 | |
780 | tmp = cff_parse_num( parser, data ); |
781 | if ( tmp < 0 ) |
782 | { |
783 | FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); |
784 | error = FT_THROW( Invalid_File_Format ); |
785 | goto Fail; |
786 | } |
787 | dict->private_offset = (FT_ULong)tmp; |
788 | |
789 | FT_TRACE4(( " %lu %lu\n" , |
790 | dict->private_size, dict->private_offset )); |
791 | |
792 | error = FT_Err_Ok; |
793 | } |
794 | |
795 | Fail: |
796 | return error; |
797 | } |
798 | |
799 | |
800 | /* The `MultipleMaster' operator comes before any */ |
801 | /* top DICT operators that contain T2 charstrings. */ |
802 | |
803 | static FT_Error |
804 | cff_parse_multiple_master( CFF_Parser parser ) |
805 | { |
806 | CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; |
807 | FT_Error error; |
808 | |
809 | |
810 | #ifdef FT_DEBUG_LEVEL_TRACE |
811 | /* beautify tracing message */ |
812 | if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] < 4 ) |
813 | FT_TRACE1(( "Multiple Master CFFs not supported yet," |
814 | " handling first master design only\n" )); |
815 | else |
816 | FT_TRACE1(( " (not supported yet," |
817 | " handling first master design only)\n" )); |
818 | #endif |
819 | |
820 | error = FT_ERR( Stack_Underflow ); |
821 | |
822 | /* currently, we handle only the first argument */ |
823 | if ( parser->top >= parser->stack + 5 ) |
824 | { |
825 | FT_Long num_designs = cff_parse_num( parser, parser->stack ); |
826 | |
827 | |
828 | if ( num_designs > 16 || num_designs < 2 ) |
829 | { |
830 | FT_ERROR(( "cff_parse_multiple_master:" |
831 | " Invalid number of designs\n" )); |
832 | error = FT_THROW( Invalid_File_Format ); |
833 | } |
834 | else |
835 | { |
836 | dict->num_designs = (FT_UShort)num_designs; |
837 | dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 ); |
838 | |
839 | parser->num_designs = dict->num_designs; |
840 | parser->num_axes = dict->num_axes; |
841 | |
842 | error = FT_Err_Ok; |
843 | } |
844 | } |
845 | |
846 | return error; |
847 | } |
848 | |
849 | |
850 | static FT_Error |
851 | cff_parse_cid_ros( CFF_Parser parser ) |
852 | { |
853 | CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; |
854 | FT_Byte** data = parser->stack; |
855 | FT_Error error; |
856 | |
857 | |
858 | error = FT_ERR( Stack_Underflow ); |
859 | |
860 | if ( parser->top >= parser->stack + 3 ) |
861 | { |
862 | dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ ); |
863 | dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ ); |
864 | if ( **data == 30 ) |
865 | FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); |
866 | dict->cid_supplement = cff_parse_num( parser, data ); |
867 | if ( dict->cid_supplement < 0 ) |
868 | FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n" , |
869 | dict->cid_supplement )); |
870 | error = FT_Err_Ok; |
871 | |
872 | FT_TRACE4(( " %d %d %d\n" , |
873 | dict->cid_registry, |
874 | dict->cid_ordering, |
875 | dict->cid_supplement )); |
876 | } |
877 | |
878 | return error; |
879 | } |
880 | |
881 | |
882 | static FT_Error |
883 | cff_parse_vsindex( CFF_Parser parser ) |
884 | { |
885 | /* vsindex operator can only be used in a Private DICT */ |
886 | CFF_Private priv = (CFF_Private)parser->object; |
887 | FT_Byte** data = parser->stack; |
888 | CFF_Blend blend; |
889 | FT_Error error; |
890 | |
891 | |
892 | if ( !priv || !priv->subfont ) |
893 | { |
894 | error = FT_THROW( Invalid_File_Format ); |
895 | goto Exit; |
896 | } |
897 | |
898 | blend = &priv->subfont->blend; |
899 | |
900 | if ( blend->usedBV ) |
901 | { |
902 | FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" )); |
903 | error = FT_THROW( Syntax_Error ); |
904 | goto Exit; |
905 | } |
906 | |
907 | priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ ); |
908 | |
909 | FT_TRACE4(( " %d\n" , priv->vsindex )); |
910 | |
911 | error = FT_Err_Ok; |
912 | |
913 | Exit: |
914 | return error; |
915 | } |
916 | |
917 | |
918 | static FT_Error |
919 | cff_parse_blend( CFF_Parser parser ) |
920 | { |
921 | /* blend operator can only be used in a Private DICT */ |
922 | CFF_Private priv = (CFF_Private)parser->object; |
923 | CFF_SubFont subFont; |
924 | CFF_Blend blend; |
925 | FT_UInt numBlends; |
926 | FT_Error error; |
927 | |
928 | |
929 | if ( !priv || !priv->subfont ) |
930 | { |
931 | error = FT_THROW( Invalid_File_Format ); |
932 | goto Exit; |
933 | } |
934 | |
935 | subFont = priv->subfont; |
936 | blend = &subFont->blend; |
937 | |
938 | if ( cff_blend_check_vector( blend, |
939 | priv->vsindex, |
940 | subFont->lenNDV, |
941 | subFont->NDV ) ) |
942 | { |
943 | error = cff_blend_build_vector( blend, |
944 | priv->vsindex, |
945 | subFont->lenNDV, |
946 | subFont->NDV ); |
947 | if ( error ) |
948 | goto Exit; |
949 | } |
950 | |
951 | numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 ); |
952 | if ( numBlends > parser->stackSize ) |
953 | { |
954 | FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" )); |
955 | error = FT_THROW( Invalid_File_Format ); |
956 | goto Exit; |
957 | } |
958 | |
959 | FT_TRACE4(( " %d value%s blended\n" , |
960 | numBlends, |
961 | numBlends == 1 ? "" : "s" )); |
962 | |
963 | error = cff_blend_doBlend( subFont, parser, numBlends ); |
964 | |
965 | blend->usedBV = TRUE; |
966 | |
967 | Exit: |
968 | return error; |
969 | } |
970 | |
971 | |
972 | /* maxstack operator increases parser and operand stacks for CFF2 */ |
973 | static FT_Error |
974 | cff_parse_maxstack( CFF_Parser parser ) |
975 | { |
976 | /* maxstack operator can only be used in a Top DICT */ |
977 | CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; |
978 | FT_Byte** data = parser->stack; |
979 | FT_Error error = FT_Err_Ok; |
980 | |
981 | |
982 | if ( !dict ) |
983 | { |
984 | error = FT_THROW( Invalid_File_Format ); |
985 | goto Exit; |
986 | } |
987 | |
988 | dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ ); |
989 | if ( dict->maxstack > CFF2_MAX_STACK ) |
990 | dict->maxstack = CFF2_MAX_STACK; |
991 | if ( dict->maxstack < CFF2_DEFAULT_STACK ) |
992 | dict->maxstack = CFF2_DEFAULT_STACK; |
993 | |
994 | FT_TRACE4(( " %d\n" , dict->maxstack )); |
995 | |
996 | Exit: |
997 | return error; |
998 | } |
999 | |
1000 | |
1001 | #define CFF_FIELD_NUM( code, name, id ) \ |
1002 | CFF_FIELD( code, name, id, cff_kind_num ) |
1003 | #define CFF_FIELD_FIXED( code, name, id ) \ |
1004 | CFF_FIELD( code, name, id, cff_kind_fixed ) |
1005 | #define CFF_FIELD_FIXED_1000( code, name, id ) \ |
1006 | CFF_FIELD( code, name, id, cff_kind_fixed_thousand ) |
1007 | #define CFF_FIELD_STRING( code, name, id ) \ |
1008 | CFF_FIELD( code, name, id, cff_kind_string ) |
1009 | #define CFF_FIELD_BOOL( code, name, id ) \ |
1010 | CFF_FIELD( code, name, id, cff_kind_bool ) |
1011 | |
1012 | |
1013 | #undef CFF_FIELD |
1014 | #undef CFF_FIELD_DELTA |
1015 | |
1016 | |
1017 | #ifndef FT_DEBUG_LEVEL_TRACE |
1018 | |
1019 | |
1020 | #define CFF_FIELD_CALLBACK( code, name, id ) \ |
1021 | { \ |
1022 | cff_kind_callback, \ |
1023 | code | CFFCODE, \ |
1024 | 0, 0, \ |
1025 | cff_parse_ ## name, \ |
1026 | 0, 0 \ |
1027 | }, |
1028 | |
1029 | #define CFF_FIELD_BLEND( code, id ) \ |
1030 | { \ |
1031 | cff_kind_blend, \ |
1032 | code | CFFCODE, \ |
1033 | 0, 0, \ |
1034 | cff_parse_blend, \ |
1035 | 0, 0 \ |
1036 | }, |
1037 | |
1038 | #define CFF_FIELD( code, name, id, kind ) \ |
1039 | { \ |
1040 | kind, \ |
1041 | code | CFFCODE, \ |
1042 | FT_FIELD_OFFSET( name ), \ |
1043 | FT_FIELD_SIZE( name ), \ |
1044 | 0, 0, 0 \ |
1045 | }, |
1046 | |
1047 | #define CFF_FIELD_DELTA( code, name, max, id ) \ |
1048 | { \ |
1049 | cff_kind_delta, \ |
1050 | code | CFFCODE, \ |
1051 | FT_FIELD_OFFSET( name ), \ |
1052 | FT_FIELD_SIZE_DELTA( name ), \ |
1053 | 0, \ |
1054 | max, \ |
1055 | FT_FIELD_OFFSET( num_ ## name ) \ |
1056 | }, |
1057 | |
1058 | static const CFF_Field_Handler cff_field_handlers[] = |
1059 | { |
1060 | |
1061 | #include "cfftoken.h" |
1062 | |
1063 | { 0, 0, 0, 0, 0, 0, 0 } |
1064 | }; |
1065 | |
1066 | |
1067 | #else /* FT_DEBUG_LEVEL_TRACE */ |
1068 | |
1069 | |
1070 | |
1071 | #define CFF_FIELD_CALLBACK( code, name, id ) \ |
1072 | { \ |
1073 | cff_kind_callback, \ |
1074 | code | CFFCODE, \ |
1075 | 0, 0, \ |
1076 | cff_parse_ ## name, \ |
1077 | 0, 0, \ |
1078 | id \ |
1079 | }, |
1080 | |
1081 | #define CFF_FIELD_BLEND( code, id ) \ |
1082 | { \ |
1083 | cff_kind_blend, \ |
1084 | code | CFFCODE, \ |
1085 | 0, 0, \ |
1086 | cff_parse_blend, \ |
1087 | 0, 0, \ |
1088 | id \ |
1089 | }, |
1090 | |
1091 | #define CFF_FIELD( code, name, id, kind ) \ |
1092 | { \ |
1093 | kind, \ |
1094 | code | CFFCODE, \ |
1095 | FT_FIELD_OFFSET( name ), \ |
1096 | FT_FIELD_SIZE( name ), \ |
1097 | 0, 0, 0, \ |
1098 | id \ |
1099 | }, |
1100 | |
1101 | #define CFF_FIELD_DELTA( code, name, max, id ) \ |
1102 | { \ |
1103 | cff_kind_delta, \ |
1104 | code | CFFCODE, \ |
1105 | FT_FIELD_OFFSET( name ), \ |
1106 | FT_FIELD_SIZE_DELTA( name ), \ |
1107 | 0, \ |
1108 | max, \ |
1109 | FT_FIELD_OFFSET( num_ ## name ), \ |
1110 | id \ |
1111 | }, |
1112 | |
1113 | static const CFF_Field_Handler cff_field_handlers[] = |
1114 | { |
1115 | |
1116 | #include "cfftoken.h" |
1117 | |
1118 | { 0, 0, 0, 0, 0, 0, 0, 0 } |
1119 | }; |
1120 | |
1121 | |
1122 | #endif /* FT_DEBUG_LEVEL_TRACE */ |
1123 | |
1124 | |
1125 | #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1126 | static void |
1127 | destruct_t2s_item( FT_Memory memory, |
1128 | void* data, |
1129 | void* user ) |
1130 | { |
1131 | FT_UNUSED( user ); |
1132 | memory->free( memory, data ); |
1133 | } |
1134 | #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ |
1135 | |
1136 | |
1137 | FT_LOCAL_DEF( FT_Error ) |
1138 | cff_parser_run( CFF_Parser parser, |
1139 | FT_Byte* start, |
1140 | FT_Byte* limit ) |
1141 | { |
1142 | FT_Byte* p = start; |
1143 | FT_Error error = FT_Err_Ok; |
1144 | |
1145 | #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1146 | PSAux_Service psaux; |
1147 | |
1148 | FT_Library library = parser->library; |
1149 | FT_Memory memory = library->memory; |
1150 | |
1151 | FT_ListRec t2s; |
1152 | |
1153 | |
1154 | FT_ZERO( &t2s ); |
1155 | #endif |
1156 | |
1157 | parser->top = parser->stack; |
1158 | parser->start = start; |
1159 | parser->limit = limit; |
1160 | parser->cursor = start; |
1161 | |
1162 | while ( p < limit ) |
1163 | { |
1164 | FT_UInt v = *p; |
1165 | |
1166 | |
1167 | /* Opcode 31 is legacy MM T2 operator, not a number. */ |
1168 | /* Opcode 255 is reserved and should not appear in fonts; */ |
1169 | /* it is used internally for CFF2 blends. */ |
1170 | if ( v >= 27 && v != 31 && v != 255 ) |
1171 | { |
1172 | /* it's a number; we will push its position on the stack */ |
1173 | if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) |
1174 | goto Stack_Overflow; |
1175 | |
1176 | *parser->top++ = p; |
1177 | |
1178 | /* now, skip it */ |
1179 | if ( v == 30 ) |
1180 | { |
1181 | /* skip real number */ |
1182 | p++; |
1183 | for (;;) |
1184 | { |
1185 | /* An unterminated floating point number at the */ |
1186 | /* end of a dictionary is invalid but harmless. */ |
1187 | if ( p >= limit ) |
1188 | goto Exit; |
1189 | v = p[0] >> 4; |
1190 | if ( v == 15 ) |
1191 | break; |
1192 | v = p[0] & 0xF; |
1193 | if ( v == 15 ) |
1194 | break; |
1195 | p++; |
1196 | } |
1197 | } |
1198 | else if ( v == 28 ) |
1199 | p += 2; |
1200 | else if ( v == 29 ) |
1201 | p += 4; |
1202 | else if ( v > 246 ) |
1203 | p += 1; |
1204 | } |
1205 | #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1206 | else if ( v == 31 ) |
1207 | { |
1208 | /* a Type 2 charstring */ |
1209 | |
1210 | CFF_Decoder decoder; |
1211 | CFF_FontRec cff_rec; |
1212 | FT_Byte* charstring_base; |
1213 | FT_ULong charstring_len; |
1214 | |
1215 | FT_Fixed* stack; |
1216 | FT_ListNode node; |
1217 | FT_Byte* q; |
1218 | |
1219 | |
1220 | charstring_base = ++p; |
1221 | |
1222 | /* search `endchar' operator */ |
1223 | for (;;) |
1224 | { |
1225 | if ( p >= limit ) |
1226 | goto Exit; |
1227 | if ( *p == 14 ) |
1228 | break; |
1229 | p++; |
1230 | } |
1231 | |
1232 | charstring_len = (FT_ULong)( p - charstring_base ) + 1; |
1233 | |
1234 | /* construct CFF_Decoder object */ |
1235 | FT_ZERO( &decoder ); |
1236 | FT_ZERO( &cff_rec ); |
1237 | |
1238 | cff_rec.top_font.font_dict.num_designs = parser->num_designs; |
1239 | cff_rec.top_font.font_dict.num_axes = parser->num_axes; |
1240 | decoder.cff = &cff_rec; |
1241 | |
1242 | psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" ); |
1243 | if ( !psaux ) |
1244 | { |
1245 | FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" )); |
1246 | error = FT_THROW( Missing_Module ); |
1247 | goto Exit; |
1248 | } |
1249 | |
1250 | error = psaux->cff_decoder_funcs->parse_charstrings_old( |
1251 | &decoder, charstring_base, charstring_len, 1 ); |
1252 | if ( error ) |
1253 | goto Exit; |
1254 | |
1255 | /* Now copy the stack data in the temporary decoder object, */ |
1256 | /* converting it back to charstring number representations */ |
1257 | /* (this is ugly, I know). */ |
1258 | |
1259 | node = (FT_ListNode)memory->alloc( memory, |
1260 | sizeof ( FT_ListNodeRec ) ); |
1261 | if ( !node ) |
1262 | goto Out_Of_Memory_Error; |
1263 | |
1264 | /* `5' is the conservative upper bound of required bytes per stack */ |
1265 | /* element. */ |
1266 | q = (FT_Byte*)memory->alloc( memory, |
1267 | 5 * ( decoder.top - decoder.stack ) ); |
1268 | if ( !q ) |
1269 | goto Out_Of_Memory_Error; |
1270 | |
1271 | node->data = q; |
1272 | |
1273 | FT_List_Add( &t2s, node ); |
1274 | |
1275 | stack = decoder.stack; |
1276 | |
1277 | while ( stack < decoder.top ) |
1278 | { |
1279 | FT_ULong num; |
1280 | FT_Bool neg; |
1281 | |
1282 | |
1283 | if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) |
1284 | goto Stack_Overflow; |
1285 | |
1286 | *parser->top++ = q; |
1287 | |
1288 | if ( *stack < 0 ) |
1289 | { |
1290 | num = (FT_ULong)NEG_LONG( *stack ); |
1291 | neg = 1; |
1292 | } |
1293 | else |
1294 | { |
1295 | num = (FT_ULong)*stack; |
1296 | neg = 0; |
1297 | } |
1298 | |
1299 | if ( num & 0xFFFFU ) |
1300 | { |
1301 | if ( neg ) |
1302 | num = (FT_ULong)-num; |
1303 | |
1304 | *q++ = 255; |
1305 | *q++ = ( num & 0xFF000000U ) >> 24; |
1306 | *q++ = ( num & 0x00FF0000U ) >> 16; |
1307 | *q++ = ( num & 0x0000FF00U ) >> 8; |
1308 | *q++ = num & 0x000000FFU; |
1309 | } |
1310 | else |
1311 | { |
1312 | num >>= 16; |
1313 | |
1314 | if ( neg ) |
1315 | { |
1316 | if ( num <= 107 ) |
1317 | *q++ = (FT_Byte)( 139 - num ); |
1318 | else if ( num <= 1131 ) |
1319 | { |
1320 | *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); |
1321 | *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); |
1322 | } |
1323 | else |
1324 | { |
1325 | num = (FT_ULong)-num; |
1326 | |
1327 | *q++ = 28; |
1328 | *q++ = (FT_Byte)( num >> 8 ); |
1329 | *q++ = (FT_Byte)( num & 0xFF ); |
1330 | } |
1331 | } |
1332 | else |
1333 | { |
1334 | if ( num <= 107 ) |
1335 | *q++ = (FT_Byte)( num + 139 ); |
1336 | else if ( num <= 1131 ) |
1337 | { |
1338 | *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); |
1339 | *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); |
1340 | } |
1341 | else |
1342 | { |
1343 | *q++ = 28; |
1344 | *q++ = (FT_Byte)( num >> 8 ); |
1345 | *q++ = (FT_Byte)( num & 0xFF ); |
1346 | } |
1347 | } |
1348 | } |
1349 | |
1350 | stack++; |
1351 | } |
1352 | } |
1353 | #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ |
1354 | else |
1355 | { |
1356 | /* This is not a number, hence it's an operator. Compute its code */ |
1357 | /* and look for it in our current list. */ |
1358 | |
1359 | FT_UInt code; |
1360 | FT_UInt num_args; |
1361 | const CFF_Field_Handler* field; |
1362 | |
1363 | |
1364 | if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) |
1365 | goto Stack_Overflow; |
1366 | |
1367 | num_args = (FT_UInt)( parser->top - parser->stack ); |
1368 | *parser->top = p; |
1369 | code = v; |
1370 | |
1371 | if ( v == 12 ) |
1372 | { |
1373 | /* two byte operator */ |
1374 | p++; |
1375 | if ( p >= limit ) |
1376 | goto Syntax_Error; |
1377 | |
1378 | code = 0x100 | p[0]; |
1379 | } |
1380 | code = code | parser->object_code; |
1381 | |
1382 | for ( field = cff_field_handlers; field->kind; field++ ) |
1383 | { |
1384 | if ( field->code == (FT_Int)code ) |
1385 | { |
1386 | /* we found our field's handler; read it */ |
1387 | FT_Long val; |
1388 | FT_Byte* q = (FT_Byte*)parser->object + field->offset; |
1389 | |
1390 | |
1391 | #ifdef FT_DEBUG_LEVEL_TRACE |
1392 | FT_TRACE4(( " %s" , field->id )); |
1393 | #endif |
1394 | |
1395 | /* check that we have enough arguments -- except for */ |
1396 | /* delta encoded arrays, which can be empty */ |
1397 | if ( field->kind != cff_kind_delta && num_args < 1 ) |
1398 | goto Stack_Underflow; |
1399 | |
1400 | switch ( field->kind ) |
1401 | { |
1402 | case cff_kind_bool: |
1403 | case cff_kind_string: |
1404 | case cff_kind_num: |
1405 | val = cff_parse_num( parser, parser->stack ); |
1406 | goto Store_Number; |
1407 | |
1408 | case cff_kind_fixed: |
1409 | val = cff_parse_fixed( parser, parser->stack ); |
1410 | goto Store_Number; |
1411 | |
1412 | case cff_kind_fixed_thousand: |
1413 | val = cff_parse_fixed_scaled( parser, parser->stack, 3 ); |
1414 | |
1415 | Store_Number: |
1416 | switch ( field->size ) |
1417 | { |
1418 | case (8 / FT_CHAR_BIT): |
1419 | *(FT_Byte*)q = (FT_Byte)val; |
1420 | break; |
1421 | |
1422 | case (16 / FT_CHAR_BIT): |
1423 | *(FT_Short*)q = (FT_Short)val; |
1424 | break; |
1425 | |
1426 | case (32 / FT_CHAR_BIT): |
1427 | *(FT_Int32*)q = (FT_Int)val; |
1428 | break; |
1429 | |
1430 | default: /* for 64-bit systems */ |
1431 | *(FT_Long*)q = val; |
1432 | } |
1433 | |
1434 | #ifdef FT_DEBUG_LEVEL_TRACE |
1435 | switch ( field->kind ) |
1436 | { |
1437 | case cff_kind_bool: |
1438 | FT_TRACE4(( " %s\n" , val ? "true" : "false" )); |
1439 | break; |
1440 | |
1441 | case cff_kind_string: |
1442 | FT_TRACE4(( " %ld (SID)\n" , val )); |
1443 | break; |
1444 | |
1445 | case cff_kind_num: |
1446 | FT_TRACE4(( " %ld\n" , val )); |
1447 | break; |
1448 | |
1449 | case cff_kind_fixed: |
1450 | FT_TRACE4(( " %f\n" , (double)val / 65536 )); |
1451 | break; |
1452 | |
1453 | case cff_kind_fixed_thousand: |
1454 | FT_TRACE4(( " %f\n" , (double)val / 65536 / 1000 )); |
1455 | |
1456 | default: |
1457 | ; /* never reached */ |
1458 | } |
1459 | #endif |
1460 | |
1461 | break; |
1462 | |
1463 | case cff_kind_delta: |
1464 | { |
1465 | FT_Byte* qcount = (FT_Byte*)parser->object + |
1466 | field->count_offset; |
1467 | |
1468 | FT_Byte** data = parser->stack; |
1469 | |
1470 | |
1471 | if ( num_args > field->array_max ) |
1472 | num_args = field->array_max; |
1473 | |
1474 | FT_TRACE4(( " [" )); |
1475 | |
1476 | /* store count */ |
1477 | *qcount = (FT_Byte)num_args; |
1478 | |
1479 | val = 0; |
1480 | while ( num_args > 0 ) |
1481 | { |
1482 | val = ADD_LONG( val, cff_parse_num( parser, data++ ) ); |
1483 | switch ( field->size ) |
1484 | { |
1485 | case (8 / FT_CHAR_BIT): |
1486 | *(FT_Byte*)q = (FT_Byte)val; |
1487 | break; |
1488 | |
1489 | case (16 / FT_CHAR_BIT): |
1490 | *(FT_Short*)q = (FT_Short)val; |
1491 | break; |
1492 | |
1493 | case (32 / FT_CHAR_BIT): |
1494 | *(FT_Int32*)q = (FT_Int)val; |
1495 | break; |
1496 | |
1497 | default: /* for 64-bit systems */ |
1498 | *(FT_Long*)q = val; |
1499 | } |
1500 | |
1501 | FT_TRACE4(( " %ld" , val )); |
1502 | |
1503 | q += field->size; |
1504 | num_args--; |
1505 | } |
1506 | |
1507 | FT_TRACE4(( "]\n" )); |
1508 | } |
1509 | break; |
1510 | |
1511 | default: /* callback or blend */ |
1512 | error = field->reader( parser ); |
1513 | if ( error ) |
1514 | goto Exit; |
1515 | } |
1516 | goto Found; |
1517 | } |
1518 | } |
1519 | |
1520 | /* this is an unknown operator, or it is unsupported; */ |
1521 | /* we will ignore it for now. */ |
1522 | |
1523 | Found: |
1524 | /* clear stack */ |
1525 | /* TODO: could clear blend stack here, */ |
1526 | /* but we don't have access to subFont */ |
1527 | if ( field->kind != cff_kind_blend ) |
1528 | parser->top = parser->stack; |
1529 | } |
1530 | p++; |
1531 | } /* while ( p < limit ) */ |
1532 | |
1533 | Exit: |
1534 | #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1535 | FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL ); |
1536 | #endif |
1537 | return error; |
1538 | |
1539 | #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1540 | Out_Of_Memory_Error: |
1541 | error = FT_THROW( Out_Of_Memory ); |
1542 | goto Exit; |
1543 | #endif |
1544 | |
1545 | Stack_Overflow: |
1546 | error = FT_THROW( Invalid_Argument ); |
1547 | goto Exit; |
1548 | |
1549 | Stack_Underflow: |
1550 | error = FT_THROW( Invalid_Argument ); |
1551 | goto Exit; |
1552 | |
1553 | Syntax_Error: |
1554 | error = FT_THROW( Invalid_Argument ); |
1555 | goto Exit; |
1556 | } |
1557 | |
1558 | |
1559 | /* END */ |
1560 | |