1 /***************************************************************************/ |
1 /**************************************************************************** |
2 /* */ |
2 * |
3 /* cffparse.c */ |
3 * cffparse.c |
4 /* */ |
4 * |
5 /* CFF token stream parser (body) */ |
5 * CFF token stream parser (body) |
6 /* */ |
6 * |
7 /* Copyright 1996-2018 by */ |
7 * Copyright (C) 1996-2019 by |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
8 * David Turner, Robert Wilhelm, and Werner Lemberg. |
9 /* */ |
9 * |
10 /* This file is part of the FreeType project, and may only be used, */ |
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 */ |
11 * modified, and distributed under the terms of the FreeType project |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute |
13 /* this file you indicate that you have read the license and */ |
13 * this file you indicate that you have read the license and |
14 /* understand and accept it fully. */ |
14 * understand and accept it fully. |
15 /* */ |
15 * |
16 /***************************************************************************/ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <ft2build.h> |
19 #include <ft2build.h> |
20 #include "cffparse.h" |
20 #include "cffparse.h" |
21 #include FT_INTERNAL_STREAM_H |
21 #include FT_INTERNAL_STREAM_H |
22 #include FT_INTERNAL_DEBUG_H |
22 #include FT_INTERNAL_DEBUG_H |
23 #include FT_INTERNAL_CALC_H |
23 #include FT_INTERNAL_CALC_H |
24 #include FT_INTERNAL_POSTSCRIPT_AUX_H |
24 #include FT_INTERNAL_POSTSCRIPT_AUX_H |
|
25 #include FT_LIST_H |
25 |
26 |
26 #include "cfferrs.h" |
27 #include "cfferrs.h" |
27 #include "cffpic.h" |
|
28 #include "cffload.h" |
28 #include "cffload.h" |
29 |
29 |
30 |
30 |
31 /*************************************************************************/ |
31 /************************************************************************** |
32 /* */ |
32 * |
33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
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 */ |
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
35 /* messages during execution. */ |
35 * messages during execution. |
36 /* */ |
36 */ |
37 #undef FT_COMPONENT |
37 #undef FT_COMPONENT |
38 #define FT_COMPONENT trace_cffparse |
38 #define FT_COMPONENT cffparse |
39 |
39 |
40 |
40 |
41 FT_LOCAL_DEF( FT_Error ) |
41 FT_LOCAL_DEF( FT_Error ) |
42 cff_parser_init( CFF_Parser parser, |
42 cff_parser_init( CFF_Parser parser, |
43 FT_UInt code, |
43 FT_UInt code, |
1116 |
1120 |
1117 |
1121 |
1118 #endif /* FT_DEBUG_LEVEL_TRACE */ |
1122 #endif /* FT_DEBUG_LEVEL_TRACE */ |
1119 |
1123 |
1120 |
1124 |
1121 #else /* FT_CONFIG_OPTION_PIC */ |
1125 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1122 |
1126 static void |
1123 |
1127 destruct_t2s_item( FT_Memory memory, |
1124 void |
1128 void* data, |
1125 FT_Destroy_Class_cff_field_handlers( FT_Library library, |
1129 void* user ) |
1126 CFF_Field_Handler* clazz ) |
1130 { |
1127 { |
1131 FT_UNUSED( user ); |
1128 FT_Memory memory = library->memory; |
1132 memory->free( memory, data ); |
1129 |
1133 } |
1130 |
1134 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ |
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 |
1135 |
1298 |
1136 |
1299 FT_LOCAL_DEF( FT_Error ) |
1137 FT_LOCAL_DEF( FT_Error ) |
1300 cff_parser_run( CFF_Parser parser, |
1138 cff_parser_run( CFF_Parser parser, |
1301 FT_Byte* start, |
1139 FT_Byte* start, |
1302 FT_Byte* limit ) |
1140 FT_Byte* limit ) |
1303 { |
1141 { |
|
1142 FT_Byte* p = start; |
|
1143 FT_Error error = FT_Err_Ok; |
|
1144 |
1304 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1145 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
1305 PSAux_Service psaux; |
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 ); |
1306 #endif |
1155 #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 |
1156 |
1315 parser->top = parser->stack; |
1157 parser->top = parser->stack; |
1316 parser->start = start; |
1158 parser->start = start; |
1317 parser->limit = limit; |
1159 parser->limit = limit; |
1318 parser->cursor = start; |
1160 parser->cursor = start; |
1319 |
1161 |
1320 while ( p < limit ) |
1162 while ( p < limit ) |
1321 { |
1163 { |
1322 FT_UInt v = *p; |
1164 FT_UInt v = *p; |
|
1165 |
1323 |
1166 |
1324 /* Opcode 31 is legacy MM T2 operator, not a number. */ |
1167 /* Opcode 31 is legacy MM T2 operator, not a number. */ |
1325 /* Opcode 255 is reserved and should not appear in fonts; */ |
1168 /* Opcode 255 is reserved and should not appear in fonts; */ |
1326 /* it is used internally for CFF2 blends. */ |
1169 /* it is used internally for CFF2 blends. */ |
1327 if ( v >= 27 && v != 31 && v != 255 ) |
1170 if ( v >= 27 && v != 31 && v != 255 ) |
1403 goto Exit; |
1247 goto Exit; |
1404 } |
1248 } |
1405 |
1249 |
1406 error = psaux->cff_decoder_funcs->parse_charstrings_old( |
1250 error = psaux->cff_decoder_funcs->parse_charstrings_old( |
1407 &decoder, charstring_base, charstring_len, 1 ); |
1251 &decoder, charstring_base, charstring_len, 1 ); |
|
1252 if ( error ) |
|
1253 goto Exit; |
1408 |
1254 |
1409 /* Now copy the stack data in the temporary decoder object, */ |
1255 /* Now copy the stack data in the temporary decoder object, */ |
1410 /* converting it back to charstring number representations */ |
1256 /* converting it back to charstring number representations */ |
1411 /* (this is ugly, I know). */ |
1257 /* (this is ugly, I know). */ |
1412 /* */ |
1258 |
1413 /* We overwrite the original top DICT charstring under the */ |
1259 node = (FT_ListNode)memory->alloc( memory, |
1414 /* assumption that the charstring representation of the result */ |
1260 sizeof ( FT_ListNodeRec ) ); |
1415 /* of `cff_decoder_parse_charstrings' is shorter, which should */ |
1261 if ( !node ) |
1416 /* be always true. */ |
1262 goto Out_Of_Memory_Error; |
1417 |
1263 |
1418 q = charstring_base - 1; |
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 |
1419 stack = decoder.stack; |
1275 stack = decoder.stack; |
1420 |
1276 |
1421 while ( stack < decoder.top ) |
1277 while ( stack < decoder.top ) |
1422 { |
1278 { |
1423 FT_ULong num; |
1279 FT_ULong num; |