OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* t1load.c */ | 3 /* t1load.c */ |
4 /* */ | 4 /* */ |
5 /* Type 1 font loader (body). */ | 5 /* Type 1 font loader (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2013 by */ | 7 /* Copyright 1996-2014 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 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 /* This is by far the fastest way one can find to parse and read all */ | 53 /* This is by far the fastest way one can find to parse and read all */ |
54 /* data. */ | 54 /* data. */ |
55 /* */ | 55 /* */ |
56 /* This led to tremendous code size reduction. Note that later, the */ | 56 /* This led to tremendous code size reduction. Note that later, the */ |
57 /* glyph loader will also be _greatly_ simplified, and the automatic */ | 57 /* glyph loader will also be _greatly_ simplified, and the automatic */ |
58 /* hinter will replace the clumsy `t1hinter'. */ | 58 /* hinter will replace the clumsy `t1hinter'. */ |
59 /* */ | 59 /* */ |
60 /*************************************************************************/ | 60 /*************************************************************************/ |
61 | 61 |
62 | 62 |
63 #include "../../include/ft2build.h" | 63 #include <ft2build.h> |
64 #include "../../include/freetype/internal/ftdebug.h" | 64 #include FT_INTERNAL_DEBUG_H |
65 #include "../../include/freetype/config/ftconfig.h" | 65 #include FT_CONFIG_CONFIG_H |
66 #include "../../include/freetype/ftmm.h" | 66 #include FT_MULTIPLE_MASTERS_H |
67 #include "../../include/freetype/internal/t1types.h" | 67 #include FT_INTERNAL_TYPE1_TYPES_H |
68 #include "../../include/freetype/internal/ftcalc.h" | 68 #include FT_INTERNAL_CALC_H |
69 | 69 |
70 #include "t1load.h" | 70 #include "t1load.h" |
71 #include "t1errors.h" | 71 #include "t1errors.h" |
72 | 72 |
73 | 73 |
74 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 74 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
75 #define IS_INCREMENTAL (FT_Bool)( face->root.internal->incremental_interface !=
0 ) | 75 #define IS_INCREMENTAL (FT_Bool)( face->root.internal->incremental_interface !=
0 ) |
76 #else | 76 #else |
77 #define IS_INCREMENTAL 0 | 77 #define IS_INCREMENTAL 0 |
78 #endif | 78 #endif |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 PS_Blend blend = face->blend; | 370 PS_Blend blend = face->blend; |
371 FT_Error error; | 371 FT_Error error; |
372 FT_UInt n, m; | 372 FT_UInt n, m; |
373 | 373 |
374 | 374 |
375 error = FT_ERR( Invalid_Argument ); | 375 error = FT_ERR( Invalid_Argument ); |
376 | 376 |
377 if ( blend && blend->num_axis == num_coords ) | 377 if ( blend && blend->num_axis == num_coords ) |
378 { | 378 { |
379 /* recompute the weight vector from the blend coordinates */ | 379 /* recompute the weight vector from the blend coordinates */ |
380 error = FT_Err_Ok; | |
381 | |
382 for ( n = 0; n < blend->num_designs; n++ ) | 380 for ( n = 0; n < blend->num_designs; n++ ) |
383 { | 381 { |
384 FT_Fixed result = 0x10000L; /* 1.0 fixed */ | 382 FT_Fixed result = 0x10000L; /* 1.0 fixed */ |
385 | 383 |
386 | 384 |
387 for ( m = 0; m < blend->num_axis; m++ ) | 385 for ( m = 0; m < blend->num_axis; m++ ) |
388 { | 386 { |
389 FT_Fixed factor; | 387 FT_Fixed factor; |
390 | 388 |
391 | 389 |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 /* and `/CharStrings' dictionaries. */ | 1091 /* and `/CharStrings' dictionaries. */ |
1094 | 1092 |
1095 static void | 1093 static void |
1096 t1_parse_font_matrix( T1_Face face, | 1094 t1_parse_font_matrix( T1_Face face, |
1097 T1_Loader loader ) | 1095 T1_Loader loader ) |
1098 { | 1096 { |
1099 T1_Parser parser = &loader->parser; | 1097 T1_Parser parser = &loader->parser; |
1100 FT_Matrix* matrix = &face->type1.font_matrix; | 1098 FT_Matrix* matrix = &face->type1.font_matrix; |
1101 FT_Vector* offset = &face->type1.font_offset; | 1099 FT_Vector* offset = &face->type1.font_offset; |
1102 FT_Face root = (FT_Face)&face->root; | 1100 FT_Face root = (FT_Face)&face->root; |
1103 FT_Fixed temp[6] = {0, 0, 0, 0, 0, 0}; | 1101 FT_Fixed temp[6]; |
1104 FT_Fixed temp_scale = 0; | 1102 FT_Fixed temp_scale; |
1105 FT_Int result; | 1103 FT_Int result; |
1106 | 1104 |
1107 | 1105 |
1108 result = T1_ToFixedArray( parser, 6, temp, 3 ); | 1106 result = T1_ToFixedArray( parser, 6, temp, 3 ); |
1109 | 1107 |
1110 if ( result < 0 ) | 1108 if ( result < 6 ) |
1111 { | 1109 { |
1112 parser->root.error = FT_THROW( Invalid_File_Format ); | 1110 parser->root.error = FT_THROW( Invalid_File_Format ); |
1113 return; | 1111 return; |
1114 } | 1112 } |
1115 | 1113 |
1116 temp_scale = FT_ABS( temp[3] ); | 1114 temp_scale = FT_ABS( temp[3] ); |
1117 | 1115 |
1118 if ( temp_scale == 0 ) | 1116 if ( temp_scale == 0 ) |
1119 { | 1117 { |
1120 FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); | 1118 FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 parser->root.error = error; | 1204 parser->root.error = error; |
1207 return; | 1205 return; |
1208 } | 1206 } |
1209 | 1207 |
1210 /* We need to `zero' out encoding_table.elements */ | 1208 /* We need to `zero' out encoding_table.elements */ |
1211 for ( n = 0; n < count; n++ ) | 1209 for ( n = 0; n < count; n++ ) |
1212 { | 1210 { |
1213 char* notdef = (char *)".notdef"; | 1211 char* notdef = (char *)".notdef"; |
1214 | 1212 |
1215 | 1213 |
1216 T1_Add_Table( char_table, n, notdef, 8 ); | 1214 (void)T1_Add_Table( char_table, n, notdef, 8 ); |
1217 } | 1215 } |
1218 | 1216 |
1219 /* Now we need to read records of the form */ | 1217 /* Now we need to read records of the form */ |
1220 /* */ | 1218 /* */ |
1221 /* ... charcode /charname ... */ | 1219 /* ... charcode /charname ... */ |
1222 /* */ | 1220 /* */ |
1223 /* for each entry in our table. */ | 1221 /* for each entry in our table. */ |
1224 /* */ | 1222 /* */ |
1225 /* We simply look for a number followed by an immediate */ | 1223 /* We simply look for a number followed by an immediate */ |
1226 /* name. Note that this ignores correctly the sequence */ | 1224 /* name. Note that this ignores correctly the sequence */ |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 { | 1265 { |
1268 FT_Int charcode; | 1266 FT_Int charcode; |
1269 | 1267 |
1270 | 1268 |
1271 if ( only_immediates ) | 1269 if ( only_immediates ) |
1272 charcode = n; | 1270 charcode = n; |
1273 else | 1271 else |
1274 { | 1272 { |
1275 charcode = (FT_Int)T1_ToInt( parser ); | 1273 charcode = (FT_Int)T1_ToInt( parser ); |
1276 T1_Skip_Spaces( parser ); | 1274 T1_Skip_Spaces( parser ); |
| 1275 |
| 1276 /* protect against invalid charcode */ |
| 1277 if ( cur == parser->root.cursor ) |
| 1278 { |
| 1279 parser->root.error = FT_THROW( Unknown_File_Format ); |
| 1280 return; |
| 1281 } |
1277 } | 1282 } |
1278 | 1283 |
1279 cur = parser->root.cursor; | 1284 cur = parser->root.cursor; |
1280 | 1285 |
1281 if ( cur + 2 < limit && *cur == '/' && n < count ) | 1286 if ( cur + 2 < limit && *cur == '/' && n < count ) |
1282 { | 1287 { |
1283 FT_PtrDist len; | 1288 FT_PtrDist len; |
1284 | 1289 |
1285 | 1290 |
1286 cur++; | 1291 cur++; |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 break; | 1589 break; |
1585 } | 1590 } |
1586 | 1591 |
1587 if ( cur[0] == 'e' && | 1592 if ( cur[0] == 'e' && |
1588 cur[1] == 'n' && | 1593 cur[1] == 'n' && |
1589 cur[2] == 'd' ) | 1594 cur[2] == 'd' ) |
1590 break; | 1595 break; |
1591 } | 1596 } |
1592 | 1597 |
1593 T1_Skip_PS_Token( parser ); | 1598 T1_Skip_PS_Token( parser ); |
| 1599 if ( parser->root.cursor >= limit ) |
| 1600 { |
| 1601 error = FT_THROW( Invalid_File_Format ); |
| 1602 goto Fail; |
| 1603 } |
1594 if ( parser->root.error ) | 1604 if ( parser->root.error ) |
1595 return; | 1605 return; |
1596 | 1606 |
1597 if ( *cur == '/' ) | 1607 if ( *cur == '/' ) |
1598 { | 1608 { |
1599 FT_PtrDist len; | 1609 FT_PtrDist len; |
1600 | 1610 |
1601 | 1611 |
1602 if ( cur + 1 >= limit ) | 1612 if ( cur + 2 >= limit ) |
1603 { | 1613 { |
1604 error = FT_THROW( Invalid_File_Format ); | 1614 error = FT_THROW( Invalid_File_Format ); |
1605 goto Fail; | 1615 goto Fail; |
1606 } | 1616 } |
1607 | 1617 |
1608 cur++; /* skip `/' */ | 1618 cur++; /* skip `/' */ |
1609 len = parser->root.cursor - cur; | 1619 len = parser->root.cursor - cur; |
1610 | 1620 |
1611 if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) | 1621 if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) |
1612 return; | 1622 return; |
1613 » » /* xhl: Add boundary check here. Fix the bug reported by ifilter
. */ | 1623 |
1614 » » /* TESTDOC: bug# 0018509, 45.pdf. */ | |
1615 » » if (base + size >= limit) { | |
1616 » » » error = T1_Err_Invalid_File_Format; | |
1617 » » » goto Fail; | |
1618 » » } | |
1619 /* for some non-standard fonts like `Optima' which provides */ | 1624 /* for some non-standard fonts like `Optima' which provides */ |
1620 /* different outlines depending on the resolution it is */ | 1625 /* different outlines depending on the resolution it is */ |
1621 /* possible to get here twice */ | 1626 /* possible to get here twice */ |
1622 if ( loader->num_glyphs ) | 1627 if ( loader->num_glyphs ) |
1623 continue; | 1628 continue; |
1624 | 1629 |
1625 error = T1_Add_Table( name_table, n, cur, len + 1 ); | 1630 error = T1_Add_Table( name_table, n, cur, len + 1 ); |
1626 if ( error ) | 1631 if ( error ) |
1627 goto Fail; | 1632 goto Fail; |
1628 | 1633 |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 /* the `lengths' field must be released later */ | 2212 /* the `lengths' field must be released later */ |
2208 type1->glyph_names_block = loader.glyph_names.block; | 2213 type1->glyph_names_block = loader.glyph_names.block; |
2209 type1->glyph_names = (FT_String**)loader.glyph_names.elements; | 2214 type1->glyph_names = (FT_String**)loader.glyph_names.elements; |
2210 loader.glyph_names.block = 0; | 2215 loader.glyph_names.block = 0; |
2211 loader.glyph_names.elements = 0; | 2216 loader.glyph_names.elements = 0; |
2212 | 2217 |
2213 /* we must now build type1.encoding when we have a custom array */ | 2218 /* we must now build type1.encoding when we have a custom array */ |
2214 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) | 2219 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) |
2215 { | 2220 { |
2216 FT_Int charcode, idx, min_char, max_char; | 2221 FT_Int charcode, idx, min_char, max_char; |
2217 FT_Byte* char_name; | |
2218 FT_Byte* glyph_name; | 2222 FT_Byte* glyph_name; |
2219 | 2223 |
2220 | 2224 |
2221 /* OK, we do the following: for each element in the encoding */ | 2225 /* OK, we do the following: for each element in the encoding */ |
2222 /* table, look up the index of the glyph having the same name */ | 2226 /* table, look up the index of the glyph having the same name */ |
2223 /* the index is then stored in type1.encoding.char_index, and */ | 2227 /* the index is then stored in type1.encoding.char_index, and */ |
2224 /* the name to type1.encoding.char_name */ | 2228 /* the name to type1.encoding.char_name */ |
2225 | 2229 |
2226 min_char = 0; | 2230 min_char = 0; |
2227 max_char = 0; | 2231 max_char = 0; |
2228 | 2232 |
2229 charcode = 0; | 2233 charcode = 0; |
2230 for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) | 2234 for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) |
2231 { | 2235 { |
| 2236 FT_Byte* char_name; |
| 2237 |
| 2238 |
2232 type1->encoding.char_index[charcode] = 0; | 2239 type1->encoding.char_index[charcode] = 0; |
2233 type1->encoding.char_name [charcode] = (char *)".notdef"; | 2240 type1->encoding.char_name [charcode] = (char *)".notdef"; |
2234 | 2241 |
2235 char_name = loader.encoding_table.elements[charcode]; | 2242 char_name = loader.encoding_table.elements[charcode]; |
2236 if ( char_name ) | 2243 if ( char_name ) |
2237 for ( idx = 0; idx < type1->num_glyphs; idx++ ) | 2244 for ( idx = 0; idx < type1->num_glyphs; idx++ ) |
2238 { | 2245 { |
2239 glyph_name = (FT_Byte*)type1->glyph_names[idx]; | 2246 glyph_name = (FT_Byte*)type1->glyph_names[idx]; |
2240 if ( ft_strcmp( (const char*)char_name, | 2247 if ( ft_strcmp( (const char*)char_name, |
2241 (const char*)glyph_name ) == 0 ) | 2248 (const char*)glyph_name ) == 0 ) |
(...skipping 21 matching lines...) Expand all Loading... |
2263 type1->encoding.num_chars = loader.num_chars; | 2270 type1->encoding.num_chars = loader.num_chars; |
2264 } | 2271 } |
2265 | 2272 |
2266 Exit: | 2273 Exit: |
2267 t1_done_loader( &loader ); | 2274 t1_done_loader( &loader ); |
2268 return error; | 2275 return error; |
2269 } | 2276 } |
2270 | 2277 |
2271 | 2278 |
2272 /* END */ | 2279 /* END */ |
OLD | NEW |