1 /***************************************************************************/
5 /* CFF token stream parser (body) */
7 /* Copyright 1996-2016 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
21 #include FT_INTERNAL_STREAM_H
22 #include FT_INTERNAL_DEBUG_H
29 /*************************************************************************/
31 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
32 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
33 /* messages during execution. */
36 #define FT_COMPONENT trace_cffparse
40 cff_parser_init( CFF_Parser parser,
44 FT_UShort num_designs,
47 FT_MEM_ZERO( parser, sizeof ( *parser ) );
49 parser->top = parser->stack;
50 parser->object_code = code;
51 parser->object = object;
52 parser->library = library;
53 parser->num_designs = num_designs;
54 parser->num_axes = num_axes;
60 cff_parse_integer( FT_Byte* start,
73 val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
80 val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
81 ( (FT_ULong)p[1] << 16 ) |
82 ( (FT_ULong)p[2] << 8 ) |
94 val = ( v - 247 ) * 256 + p[0] + 108;
101 val = -( v - 251 ) * 256 - p[0] - 108;
109 FT_TRACE4(( "!!!END OF DATA:!!!" ));
114 static const FT_Long power_tens[] =
131 cff_parse_real( FT_Byte* start,
140 FT_Long result, number, exponent;
141 FT_Int sign = 0, exponent_sign = 0, have_overflow = 0;
142 FT_Long exponent_add, integer_length, fraction_length;
157 /* First of all, read the integer part. */
162 /* If we entered this iteration with phase == 4, we need to */
163 /* read a new byte. This also skips past the initial 0x1E. */
168 /* Make sure we don't read past the end. */
173 /* Get the nibble. */
174 nib = (FT_Int)( p[0] >> phase ) & 0xF;
183 /* Increase exponent if we can't add the digit. */
184 if ( number >= 0xCCCCCCCL )
186 /* Skip leading zeros. */
187 else if ( nib || number )
190 number = number * 10 + nib;
195 /* Read fraction part, if any. */
199 /* If we entered this iteration with phase == 4, we need */
200 /* to read a new byte. */
205 /* Make sure we don't read past the end. */
210 /* Get the nibble. */
211 nib = ( p[0] >> phase ) & 0xF;
216 /* Skip leading zeros if possible. */
217 if ( !nib && !number )
219 /* Only add digit if we don't overflow. */
220 else if ( number < 0xCCCCCCCL && fraction_length < 9 )
223 number = number * 10 + nib;
227 /* Read exponent, if any. */
238 /* If we entered this iteration with phase == 4, */
239 /* we need to read a new byte. */
244 /* Make sure we don't read past the end. */
249 /* Get the nibble. */
250 nib = ( p[0] >> phase ) & 0xF;
255 /* Arbitrarily limit exponent. */
256 if ( exponent > 1000 )
259 exponent = exponent * 10 + nib;
263 exponent = -exponent;
277 /* We don't check `power_ten' and `exponent_add'. */
278 exponent += power_ten + exponent_add;
282 /* Only use `fraction_length'. */
283 fraction_length += integer_length;
284 exponent += integer_length;
286 if ( fraction_length <= 5 )
288 if ( number > 0x7FFFL )
290 result = FT_DivFix( number, 10 );
291 *scaling = exponent - fraction_length + 1;
297 FT_Long new_fraction_length, shift;
300 /* Make `scaling' as small as possible. */
301 new_fraction_length = FT_MIN( exponent, 5 );
302 shift = new_fraction_length - fraction_length;
306 exponent -= new_fraction_length;
307 number *= power_tens[shift];
308 if ( number > 0x7FFFL )
315 exponent -= fraction_length;
318 exponent -= fraction_length;
320 result = (FT_Long)( (FT_ULong)number << 16 );
326 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
328 result = FT_DivFix( number, power_tens[fraction_length - 4] );
329 *scaling = exponent - 4;
333 result = FT_DivFix( number, power_tens[fraction_length - 5] );
334 *scaling = exponent - 5;
340 integer_length += exponent;
341 fraction_length -= exponent;
343 if ( integer_length > 5 )
345 if ( integer_length < -5 )
348 /* Remove non-significant digits. */
349 if ( integer_length < 0 )
351 number /= power_tens[-integer_length];
352 fraction_length += integer_length;
355 /* this can only happen if exponent was non-zero */
356 if ( fraction_length == 10 )
359 fraction_length -= 1;
362 /* Convert into 16.16 format. */
363 if ( fraction_length > 0 )
365 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
368 result = FT_DivFix( number, power_tens[fraction_length] );
372 number *= power_tens[-fraction_length];
374 if ( number > 0x7FFFL )
377 result = (FT_Long)( (FT_ULong)number << 16 );
388 result = 0x7FFFFFFFL;
389 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
394 FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
399 FT_TRACE4(( "!!!END OF DATA:!!!" ));
404 /* read a number, either integer or real */
406 cff_parse_num( FT_Byte** d )
408 return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
409 : cff_parse_integer( d[0], d[1] );
413 /* read a floating point number, either integer or real */
415 do_fixed( FT_Byte** d,
419 return cff_parse_real( d[0], d[1], scaling, NULL );
422 FT_Long val = cff_parse_integer( d[0], d[1] );
426 val *= power_tens[scaling];
433 else if ( val < -0x7FFF )
439 return (FT_Long)( (FT_ULong)val << 16 );
442 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
448 /* read a floating point number, either integer or real */
450 cff_parse_fixed( FT_Byte** d )
452 return do_fixed( d, 0 );
456 /* read a floating point number, either integer or real, */
457 /* but return `10^scaling' times the number read in */
459 cff_parse_fixed_scaled( FT_Byte** d,
462 return do_fixed( d, scaling );
466 /* read a floating point number, either integer or real, */
467 /* and return it as precise as possible -- `scaling' returns */
468 /* the scaling factor (as a power of 10) */
470 cff_parse_fixed_dynamic( FT_Byte** d,
473 FT_ASSERT( scaling );
476 return cff_parse_real( d[0], d[1], 0, scaling );
480 FT_Int integer_length;
483 number = cff_parse_integer( d[0], d[1] );
485 if ( number > 0x7FFFL )
487 for ( integer_length = 5; integer_length < 10; integer_length++ )
488 if ( number < power_tens[integer_length] )
491 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
493 *scaling = integer_length - 4;
494 return FT_DivFix( number, power_tens[integer_length - 4] );
498 *scaling = integer_length - 5;
499 return FT_DivFix( number, power_tens[integer_length - 5] );
505 return (FT_Long)( (FT_ULong)number << 16 );
512 cff_parse_font_matrix( CFF_Parser parser )
514 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
515 FT_Matrix* matrix = &dict->font_matrix;
516 FT_Vector* offset = &dict->font_offset;
517 FT_ULong* upm = &dict->units_per_em;
518 FT_Byte** data = parser->stack;
519 FT_Error error = FT_ERR( Stack_Underflow );
522 if ( parser->top >= parser->stack + 6 )
527 FT_Long min_scaling, max_scaling;
533 dict->has_font_matrix = TRUE;
535 /* We expect a well-formed font matrix, this is, the matrix elements */
536 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
537 /* loss of precision, we use the magnitude of the largest matrix */
538 /* element to scale all other elements. The scaling factor is then */
539 /* contained in the `units_per_em' value. */
541 max_scaling = FT_LONG_MIN;
542 min_scaling = FT_LONG_MAX;
544 for ( i = 0; i < 6; i++ )
546 values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] );
549 if ( scalings[i] > max_scaling )
550 max_scaling = scalings[i];
551 if ( scalings[i] < min_scaling )
552 min_scaling = scalings[i];
556 if ( max_scaling < -9 ||
558 ( max_scaling - min_scaling ) < 0 ||
559 ( max_scaling - min_scaling ) > 9 )
561 /* Return default matrix in case of unlikely values. */
563 FT_TRACE1(( "cff_parse_font_matrix:"
564 " strange scaling values (minimum %d, maximum %d),\n"
566 " using default matrix\n", min_scaling, max_scaling ));
568 matrix->xx = 0x10000L;
571 matrix->yy = 0x10000L;
579 for ( i = 0; i < 6; i++ )
581 FT_Fixed value = values[i];
582 FT_Long divisor, half_divisor;
588 divisor = power_tens[max_scaling - scalings[i]];
589 half_divisor = divisor >> 1;
593 if ( FT_LONG_MIN + half_divisor < value )
594 values[i] = ( value - half_divisor ) / divisor;
596 values[i] = FT_LONG_MIN / divisor;
600 if ( FT_LONG_MAX - half_divisor > value )
601 values[i] = ( value + half_divisor ) / divisor;
603 values[i] = FT_LONG_MAX / divisor;
607 matrix->xx = values[0];
608 matrix->yx = values[1];
609 matrix->xy = values[2];
610 matrix->yy = values[3];
611 offset->x = values[4];
612 offset->y = values[5];
614 *upm = (FT_ULong)power_tens[-max_scaling];
616 FT_TRACE4(( " [%f %f %f %f %f %f]\n",
617 (double)matrix->xx / *upm / 65536,
618 (double)matrix->xy / *upm / 65536,
619 (double)matrix->yx / *upm / 65536,
620 (double)matrix->yy / *upm / 65536,
621 (double)offset->x / *upm / 65536,
622 (double)offset->y / *upm / 65536 ));
631 cff_parse_font_bbox( CFF_Parser parser )
633 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
634 FT_BBox* bbox = &dict->font_bbox;
635 FT_Byte** data = parser->stack;
639 error = FT_ERR( Stack_Underflow );
641 if ( parser->top >= parser->stack + 4 )
643 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
644 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
645 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
646 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
649 FT_TRACE4(( " [%d %d %d %d]\n",
653 bbox->yMax / 65536 ));
661 cff_parse_private_dict( CFF_Parser parser )
663 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
664 FT_Byte** data = parser->stack;
668 error = FT_ERR( Stack_Underflow );
670 if ( parser->top >= parser->stack + 2 )
675 tmp = cff_parse_num( data++ );
678 FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
679 error = FT_THROW( Invalid_File_Format );
682 dict->private_size = (FT_ULong)tmp;
684 tmp = cff_parse_num( data );
687 FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
688 error = FT_THROW( Invalid_File_Format );
691 dict->private_offset = (FT_ULong)tmp;
693 FT_TRACE4(( " %lu %lu\n",
694 dict->private_size, dict->private_offset ));
704 /* The `MultipleMaster' operator comes before any */
705 /* top DICT operators that contain T2 charstrings. */
708 cff_parse_multiple_master( CFF_Parser parser )
710 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
714 #ifdef FT_DEBUG_LEVEL_TRACE
715 /* beautify tracing message */
716 if ( ft_trace_levels[FT_COMPONENT] < 4 )
717 FT_TRACE1(( "Multiple Master CFFs not supported yet,"
718 " handling first master design only\n" ));
720 FT_TRACE1(( " (not supported yet,"
721 " handling first master design only)\n" ));
724 error = FT_ERR( Stack_Underflow );
726 /* currently, we handle only the first argument */
727 if ( parser->top >= parser->stack + 5 )
729 FT_Long num_designs = cff_parse_num( parser->stack );
732 if ( num_designs > 16 || num_designs < 2 )
734 FT_ERROR(( "cff_parse_multiple_master:"
735 " Invalid number of designs\n" ));
736 error = FT_THROW( Invalid_File_Format );
740 dict->num_designs = (FT_UShort)num_designs;
741 dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 );
743 parser->num_designs = dict->num_designs;
744 parser->num_axes = dict->num_axes;
755 cff_parse_cid_ros( CFF_Parser parser )
757 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
758 FT_Byte** data = parser->stack;
762 error = FT_ERR( Stack_Underflow );
764 if ( parser->top >= parser->stack + 3 )
766 dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
767 dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
769 FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
770 dict->cid_supplement = cff_parse_num( data );
771 if ( dict->cid_supplement < 0 )
772 FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
773 dict->cid_supplement ));
776 FT_TRACE4(( " %d %d %d\n",
779 dict->cid_supplement ));
786 #define CFF_FIELD_NUM( code, name, id ) \
787 CFF_FIELD( code, name, id, cff_kind_num )
788 #define CFF_FIELD_FIXED( code, name, id ) \
789 CFF_FIELD( code, name, id, cff_kind_fixed )
790 #define CFF_FIELD_FIXED_1000( code, name, id ) \
791 CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
792 #define CFF_FIELD_STRING( code, name, id ) \
793 CFF_FIELD( code, name, id, cff_kind_string )
794 #define CFF_FIELD_BOOL( code, name, id ) \
795 CFF_FIELD( code, name, id, cff_kind_bool )
797 #define CFFCODE_TOPDICT 0x1000
798 #define CFFCODE_PRIVATE 0x2000
801 #ifndef FT_CONFIG_OPTION_PIC
805 #undef CFF_FIELD_DELTA
808 #ifndef FT_DEBUG_LEVEL_TRACE
811 #define CFF_FIELD_CALLBACK( code, name, id ) \
816 cff_parse_ ## name, \
820 #define CFF_FIELD( code, name, id, kind ) \
824 FT_FIELD_OFFSET( name ), \
825 FT_FIELD_SIZE( name ), \
829 #define CFF_FIELD_DELTA( code, name, max, id ) \
833 FT_FIELD_OFFSET( name ), \
834 FT_FIELD_SIZE_DELTA( name ), \
837 FT_FIELD_OFFSET( num_ ## name ) \
840 static const CFF_Field_Handler cff_field_handlers[] =
843 #include "cfftoken.h"
845 { 0, 0, 0, 0, 0, 0, 0 }
849 #else /* FT_DEBUG_LEVEL_TRACE */
853 #define CFF_FIELD_CALLBACK( code, name, id ) \
858 cff_parse_ ## name, \
863 #define CFF_FIELD( code, name, id, kind ) \
867 FT_FIELD_OFFSET( name ), \
868 FT_FIELD_SIZE( name ), \
873 #define CFF_FIELD_DELTA( code, name, max, id ) \
877 FT_FIELD_OFFSET( name ), \
878 FT_FIELD_SIZE_DELTA( name ), \
881 FT_FIELD_OFFSET( num_ ## name ), \
885 static const CFF_Field_Handler cff_field_handlers[] =
888 #include "cfftoken.h"
890 { 0, 0, 0, 0, 0, 0, 0, 0 }
894 #endif /* FT_DEBUG_LEVEL_TRACE */
897 #else /* FT_CONFIG_OPTION_PIC */
901 FT_Destroy_Class_cff_field_handlers( FT_Library library,
902 CFF_Field_Handler* clazz )
904 FT_Memory memory = library->memory;
913 FT_Create_Class_cff_field_handlers( FT_Library library,
914 CFF_Field_Handler** output_class )
916 CFF_Field_Handler* clazz = NULL;
918 FT_Memory memory = library->memory;
924 #define CFF_FIELD( code, name, id, kind ) i++;
925 #undef CFF_FIELD_DELTA
926 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
927 #undef CFF_FIELD_CALLBACK
928 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
930 #include "cfftoken.h"
932 i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
934 if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
940 #ifndef FT_DEBUG_LEVEL_TRACE
943 #undef CFF_FIELD_CALLBACK
944 #define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
945 clazz[i].kind = cff_kind_callback; \
946 clazz[i].code = code_ | CFFCODE; \
947 clazz[i].offset = 0; \
949 clazz[i].reader = cff_parse_ ## name_; \
950 clazz[i].array_max = 0; \
951 clazz[i].count_offset = 0; \
955 #define CFF_FIELD( code_, name_, id_, kind_ ) \
956 clazz[i].kind = kind_; \
957 clazz[i].code = code_ | CFFCODE; \
958 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
959 clazz[i].size = FT_FIELD_SIZE( name_ ); \
960 clazz[i].reader = 0; \
961 clazz[i].array_max = 0; \
962 clazz[i].count_offset = 0; \
965 #undef CFF_FIELD_DELTA
966 #define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
967 clazz[i].kind = cff_kind_delta; \
968 clazz[i].code = code_ | CFFCODE; \
969 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
970 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
971 clazz[i].reader = 0; \
972 clazz[i].array_max = max_; \
973 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
976 #include "cfftoken.h"
983 clazz[i].array_max = 0;
984 clazz[i].count_offset = 0;
987 #else /* FT_DEBUG_LEVEL_TRACE */
990 #undef CFF_FIELD_CALLBACK
991 #define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
992 clazz[i].kind = cff_kind_callback; \
993 clazz[i].code = code_ | CFFCODE; \
994 clazz[i].offset = 0; \
996 clazz[i].reader = cff_parse_ ## name_; \
997 clazz[i].array_max = 0; \
998 clazz[i].count_offset = 0; \
1003 #define CFF_FIELD( code_, name_, id_, kind_ ) \
1004 clazz[i].kind = kind_; \
1005 clazz[i].code = code_ | CFFCODE; \
1006 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1007 clazz[i].size = FT_FIELD_SIZE( name_ ); \
1008 clazz[i].reader = 0; \
1009 clazz[i].array_max = 0; \
1010 clazz[i].count_offset = 0; \
1011 clazz[i].id = id_; \
1014 #undef CFF_FIELD_DELTA
1015 #define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
1016 clazz[i].kind = cff_kind_delta; \
1017 clazz[i].code = code_ | CFFCODE; \
1018 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
1019 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
1020 clazz[i].reader = 0; \
1021 clazz[i].array_max = max_; \
1022 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
1023 clazz[i].id = id_; \
1026 #include "cfftoken.h"
1030 clazz[i].offset = 0;
1032 clazz[i].reader = 0;
1033 clazz[i].array_max = 0;
1034 clazz[i].count_offset = 0;
1038 #endif /* FT_DEBUG_LEVEL_TRACE */
1041 *output_class = clazz;
1047 #endif /* FT_CONFIG_OPTION_PIC */
1050 FT_LOCAL_DEF( FT_Error )
1051 cff_parser_run( CFF_Parser parser,
1056 FT_Error error = FT_Err_Ok;
1057 FT_Library library = parser->library;
1058 FT_UNUSED( library );
1061 parser->top = parser->stack;
1062 parser->start = start;
1063 parser->limit = limit;
1064 parser->cursor = start;
1071 if ( v >= 27 && v != 31 )
1073 /* it's a number; we will push its position on the stack */
1074 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
1075 goto Stack_Overflow;
1082 /* skip real number */
1086 /* An unterminated floating point number at the */
1087 /* end of a dictionary is invalid but harmless. */
1106 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1109 /* a Type 2 charstring */
1111 CFF_Decoder decoder;
1112 CFF_FontRec cff_rec;
1113 FT_Byte* charstring_base;
1114 FT_ULong charstring_len;
1120 charstring_base = ++p;
1122 /* search `endchar' operator */
1132 charstring_len = (FT_ULong)( p - charstring_base ) + 1;
1134 /* construct CFF_Decoder object */
1135 FT_MEM_ZERO( &decoder, sizeof ( decoder ) );
1136 FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) );
1138 cff_rec.top_font.font_dict.num_designs = parser->num_designs;
1139 cff_rec.top_font.font_dict.num_axes = parser->num_axes;
1140 decoder.cff = &cff_rec;
1142 error = cff_decoder_parse_charstrings( &decoder,
1147 /* Now copy the stack data in the temporary decoder object, */
1148 /* converting it back to charstring number representations */
1149 /* (this is ugly, I know). */
1151 /* We overwrite the original top DICT charstring under the */
1152 /* assumption that the charstring representation of the result */
1153 /* of `cff_decoder_parse_charstrings' is shorter, which should */
1154 /* be always true. */
1156 q = charstring_base - 1;
1157 stack = decoder.stack;
1159 while ( stack < decoder.top )
1165 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
1166 goto Stack_Overflow;
1172 num = (FT_ULong)-*stack;
1177 num = (FT_ULong)*stack;
1181 if ( num & 0xFFFFU )
1184 num = (FT_ULong)-num;
1187 *q++ = ( num & 0xFF000000U ) >> 24;
1188 *q++ = ( num & 0x00FF0000U ) >> 16;
1189 *q++ = ( num & 0x0000FF00U ) >> 8;
1190 *q++ = num & 0x000000FFU;
1199 *q++ = (FT_Byte)( 139 - num );
1200 else if ( num <= 1131 )
1202 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
1203 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1207 num = (FT_ULong)-num;
1210 *q++ = (FT_Byte)( num >> 8 );
1211 *q++ = (FT_Byte)( num & 0xFF );
1217 *q++ = (FT_Byte)( num + 139 );
1218 else if ( num <= 1131 )
1220 *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
1221 *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
1226 *q++ = (FT_Byte)( num >> 8 );
1227 *q++ = (FT_Byte)( num & 0xFF );
1235 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
1238 /* This is not a number, hence it's an operator. Compute its code */
1239 /* and look for it in our current list. */
1242 FT_UInt num_args = (FT_UInt)
1243 ( parser->top - parser->stack );
1244 const CFF_Field_Handler* field;
1251 /* two byte operator */
1256 code = 0x100 | p[0];
1258 code = code | parser->object_code;
1260 for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
1262 if ( field->code == (FT_Int)code )
1264 /* we found our field's handler; read it */
1266 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
1269 #ifdef FT_DEBUG_LEVEL_TRACE
1270 FT_TRACE4(( " %s", field->id ));
1273 /* check that we have enough arguments -- except for */
1274 /* delta encoded arrays, which can be empty */
1275 if ( field->kind != cff_kind_delta && num_args < 1 )
1276 goto Stack_Underflow;
1278 switch ( field->kind )
1281 case cff_kind_string:
1283 val = cff_parse_num( parser->stack );
1286 case cff_kind_fixed:
1287 val = cff_parse_fixed( parser->stack );
1290 case cff_kind_fixed_thousand:
1291 val = cff_parse_fixed_scaled( parser->stack, 3 );
1294 switch ( field->size )
1296 case (8 / FT_CHAR_BIT):
1297 *(FT_Byte*)q = (FT_Byte)val;
1300 case (16 / FT_CHAR_BIT):
1301 *(FT_Short*)q = (FT_Short)val;
1304 case (32 / FT_CHAR_BIT):
1305 *(FT_Int32*)q = (FT_Int)val;
1308 default: /* for 64-bit systems */
1312 #ifdef FT_DEBUG_LEVEL_TRACE
1313 switch ( field->kind )
1316 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1319 case cff_kind_string:
1320 FT_TRACE4(( " %ld (SID)\n", val ));
1324 FT_TRACE4(( " %ld\n", val ));
1327 case cff_kind_fixed:
1328 FT_TRACE4(( " %f\n", (double)val / 65536 ));
1331 case cff_kind_fixed_thousand:
1332 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1335 ; /* never reached */
1341 case cff_kind_delta:
1343 FT_Byte* qcount = (FT_Byte*)parser->object +
1344 field->count_offset;
1346 FT_Byte** data = parser->stack;
1349 if ( num_args > field->array_max )
1350 num_args = field->array_max;
1352 FT_TRACE4(( " [" ));
1355 *qcount = (FT_Byte)num_args;
1358 while ( num_args > 0 )
1360 val += cff_parse_num( data++ );
1361 switch ( field->size )
1363 case (8 / FT_CHAR_BIT):
1364 *(FT_Byte*)q = (FT_Byte)val;
1367 case (16 / FT_CHAR_BIT):
1368 *(FT_Short*)q = (FT_Short)val;
1371 case (32 / FT_CHAR_BIT):
1372 *(FT_Int32*)q = (FT_Int)val;
1375 default: /* for 64-bit systems */
1379 FT_TRACE4(( " %ld", val ));
1385 FT_TRACE4(( "]\n" ));
1389 default: /* callback */
1390 error = field->reader( parser );
1398 /* this is an unknown operator, or it is unsupported; */
1399 /* we will ignore it for now. */
1403 parser->top = parser->stack;
1412 error = FT_THROW( Invalid_Argument );
1416 error = FT_THROW( Invalid_Argument );
1420 error = FT_THROW( Invalid_Argument );