OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ttcmap.c */ | 3 /* ttcmap.c */ |
4 /* */ | 4 /* */ |
5 /* TrueType character mapping table (cmap) support (body). */ | 5 /* TrueType character mapping table (cmap) support (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2002-2010, 2012-2014 by */ | 7 /* Copyright 2002-2015 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 26 matching lines...) Expand all Loading... |
44 #define TT_PEEK_LONG FT_PEEK_LONG | 44 #define TT_PEEK_LONG FT_PEEK_LONG |
45 #define TT_PEEK_ULONG FT_PEEK_ULONG | 45 #define TT_PEEK_ULONG FT_PEEK_ULONG |
46 | 46 |
47 #define TT_NEXT_SHORT FT_NEXT_SHORT | 47 #define TT_NEXT_SHORT FT_NEXT_SHORT |
48 #define TT_NEXT_USHORT FT_NEXT_USHORT | 48 #define TT_NEXT_USHORT FT_NEXT_USHORT |
49 #define TT_NEXT_UINT24 FT_NEXT_UOFF3 | 49 #define TT_NEXT_UINT24 FT_NEXT_UOFF3 |
50 #define TT_NEXT_LONG FT_NEXT_LONG | 50 #define TT_NEXT_LONG FT_NEXT_LONG |
51 #define TT_NEXT_ULONG FT_NEXT_ULONG | 51 #define TT_NEXT_ULONG FT_NEXT_ULONG |
52 | 52 |
53 | 53 |
| 54 /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ |
| 55 /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ |
| 56 /* again in this case). To mark character code return values as invalid */ |
| 57 /* it is sufficient to set the corresponding glyph index return value to */ |
| 58 /* zero. */ |
| 59 |
| 60 |
54 FT_CALLBACK_DEF( FT_Error ) | 61 FT_CALLBACK_DEF( FT_Error ) |
55 tt_cmap_init( TT_CMap cmap, | 62 tt_cmap_init( TT_CMap cmap, |
56 FT_Byte* table ) | 63 FT_Byte* table ) |
57 { | 64 { |
58 cmap->data = table; | 65 cmap->data = table; |
59 return FT_Err_Ok; | 66 return FT_Err_Ok; |
60 } | 67 } |
61 | 68 |
62 | 69 |
63 /*************************************************************************/ | 70 /*************************************************************************/ |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 199 |
193 #endif /* TT_CONFIG_CMAP_FORMAT_0 */ | 200 #endif /* TT_CONFIG_CMAP_FORMAT_0 */ |
194 | 201 |
195 | 202 |
196 /*************************************************************************/ | 203 /*************************************************************************/ |
197 /*************************************************************************/ | 204 /*************************************************************************/ |
198 /***** *****/ | 205 /***** *****/ |
199 /***** FORMAT 2 *****/ | 206 /***** FORMAT 2 *****/ |
200 /***** *****/ | 207 /***** *****/ |
201 /***** This is used for certain CJK encodings that encode text in a *****/ | 208 /***** This is used for certain CJK encodings that encode text in a *****/ |
202 /***** mixed 8/16 bits encoding along the following lines: *****/ | 209 /***** mixed 8/16 bits encoding along the following lines. *****/ |
203 /***** *****/ | 210 /***** *****/ |
204 /***** * Certain byte values correspond to an 8-bit character code *****/ | 211 /***** * Certain byte values correspond to an 8-bit character code *****/ |
205 /***** (typically in the range 0..127 for ASCII compatibility). *****/ | 212 /***** (typically in the range 0..127 for ASCII compatibility). *****/ |
206 /***** *****/ | 213 /***** *****/ |
207 /***** * Certain byte values signal the first byte of a 2-byte *****/ | 214 /***** * Certain byte values signal the first byte of a 2-byte *****/ |
208 /***** character code (but these values are also valid as the *****/ | 215 /***** character code (but these values are also valid as the *****/ |
209 /***** second byte of a 2-byte character). *****/ | 216 /***** second byte of a 2-byte character). *****/ |
210 /***** *****/ | 217 /***** *****/ |
211 /***** The following charmap lookup and iteration functions all *****/ | 218 /***** The following charmap lookup and iteration functions all *****/ |
212 /***** assume that the value "charcode" correspond to following: *****/ | 219 /***** assume that the value `charcode' fulfills the following. *****/ |
213 /***** *****/ | 220 /***** *****/ |
214 /***** - For one byte characters, "charcode" is simply the *****/ | 221 /***** - For one byte characters, `charcode' is simply the *****/ |
215 /***** character code. *****/ | 222 /***** character code. *****/ |
216 /***** *****/ | 223 /***** *****/ |
217 /***** - For two byte characters, "charcode" is the 2-byte *****/ | 224 /***** - For two byte characters, `charcode' is the 2-byte *****/ |
218 /***** character code in big endian format. More exactly: *****/ | 225 /***** character code in big endian format. More precisely: *****/ |
219 /***** *****/ | 226 /***** *****/ |
220 /***** (charcode >> 8) is the first byte value *****/ | 227 /***** (charcode >> 8) is the first byte value *****/ |
221 /***** (charcode & 0xFF) is the second byte value *****/ | 228 /***** (charcode & 0xFF) is the second byte value *****/ |
222 /***** *****/ | 229 /***** *****/ |
223 /***** Note that not all values of "charcode" are valid according *****/ | 230 /***** Note that not all values of `charcode' are valid according *****/ |
224 /***** to these rules, and the function moderately check the *****/ | 231 /***** to these rules, and the function moderately checks the *****/ |
225 /***** arguments. *****/ | 232 /***** arguments. *****/ |
226 /***** *****/ | 233 /***** *****/ |
227 /*************************************************************************/ | 234 /*************************************************************************/ |
228 /*************************************************************************/ | 235 /*************************************************************************/ |
229 | 236 |
230 /*************************************************************************/ | 237 /*************************************************************************/ |
231 /* */ | 238 /* */ |
232 /* TABLE OVERVIEW */ | 239 /* TABLE OVERVIEW */ |
233 /* -------------- */ | 240 /* -------------- */ |
234 /* */ | 241 /* */ |
235 /* NAME OFFSET TYPE DESCRIPTION */ | 242 /* NAME OFFSET TYPE DESCRIPTION */ |
236 /* */ | 243 /* */ |
237 /* format 0 USHORT must be 2 */ | 244 /* format 0 USHORT must be 2 */ |
238 /* length 2 USHORT table length in bytes */ | 245 /* length 2 USHORT table length in bytes */ |
239 /* language 4 USHORT Mac language code */ | 246 /* language 4 USHORT Mac language code */ |
240 /* keys 6 USHORT[256] sub-header keys */ | 247 /* keys 6 USHORT[256] sub-header keys */ |
241 /* subs 518 SUBHEAD[NSUBS] sub-headers array */ | 248 /* subs 518 SUBHEAD[NSUBS] sub-headers array */ |
242 /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ | 249 /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ |
243 /* */ | 250 /* */ |
244 /* The `keys' table is used to map charcode high-bytes to sub-headers. */ | 251 /* The `keys' table is used to map charcode high-bytes to sub-headers. */ |
245 /* The value of `NSUBS' is the number of sub-headers defined in the */ | 252 /* The value of `NSUBS' is the number of sub-headers defined in the */ |
246 /* table and is computed by finding the maximum of the `keys' table. */ | 253 /* table and is computed by finding the maximum of the `keys' table. */ |
247 /* */ | 254 /* */ |
248 /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ | 255 /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ |
249 /* table, i.e., it is the corresponding sub-header index multiplied */ | 256 /* table, i.e., it is the corresponding sub-header index multiplied */ |
250 /* by 8. */ | 257 /* by 8. */ |
251 /* */ | 258 /* */ |
252 /* Each sub-header has the following format: */ | 259 /* Each sub-header has the following format. */ |
253 /* */ | 260 /* */ |
254 /* NAME OFFSET TYPE DESCRIPTION */ | 261 /* NAME OFFSET TYPE DESCRIPTION */ |
255 /* */ | 262 /* */ |
256 /* first 0 USHORT first valid low-byte */ | 263 /* first 0 USHORT first valid low-byte */ |
257 /* count 2 USHORT number of valid low-bytes */ | 264 /* count 2 USHORT number of valid low-bytes */ |
258 /* delta 4 SHORT see below */ | 265 /* delta 4 SHORT see below */ |
259 /* offset 6 USHORT see below */ | 266 /* offset 6 USHORT see below */ |
260 /* */ | 267 /* */ |
261 /* A sub-header defines, for each high-byte, the range of valid */ | 268 /* A sub-header defines, for each high-byte, the range of valid */ |
262 /* low-bytes within the charmap. Note that the range defined by `first' */ | 269 /* low-bytes within the charmap. Note that the range defined by `first' */ |
263 /* and `count' must be completely included in the interval [0..255] */ | 270 /* and `count' must be completely included in the interval [0..255] */ |
264 /* according to the specification. */ | 271 /* according to the specification. */ |
265 /* */ | 272 /* */ |
266 /* If a character code is contained within a given sub-header, then */ | 273 /* If a character code is contained within a given sub-header, then */ |
267 /* mapping it to a glyph index is done as follows: */ | 274 /* mapping it to a glyph index is done as follows. */ |
268 /* */ | 275 /* */ |
269 /* * The value of `offset' is read. This is a _byte_ distance from the */ | 276 /* * The value of `offset' is read. This is a _byte_ distance from the */ |
270 /* location of the `offset' field itself into a slice of the */ | 277 /* location of the `offset' field itself into a slice of the */ |
271 /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ | 278 /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ |
272 /* */ | 279 /* */ |
273 /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ | 280 /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ |
274 /* no glyph for the charcode. Otherwise, the value of `delta' is */ | 281 /* no glyph for the charcode. Otherwise, the value of `delta' is */ |
275 /* added to it (modulo 65536) to form a new glyph index. */ | 282 /* added to it (modulo 65536) to form a new glyph index. */ |
276 /* */ | 283 /* */ |
277 /* It is up to the validation routine to check that all offsets fall */ | 284 /* It is up to the validation routine to check that all offsets fall */ |
278 /* within the glyph IDs table (and not within the `subs' table itself or */ | 285 /* within the glyph IDs table (and not within the `subs' table itself or */ |
279 /* outside of the CMap). */ | 286 /* outside of the CMap). */ |
280 /* */ | 287 /* */ |
281 | 288 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 326 |
320 idx >>= 3; | 327 idx >>= 3; |
321 | 328 |
322 if ( idx > max_subs ) | 329 if ( idx > max_subs ) |
323 max_subs = idx; | 330 max_subs = idx; |
324 } | 331 } |
325 | 332 |
326 FT_ASSERT( p == table + 518 ); | 333 FT_ASSERT( p == table + 518 ); |
327 | 334 |
328 subs = p; | 335 subs = p; |
329 glyph_ids = subs + (max_subs + 1) * 8; | 336 glyph_ids = subs + ( max_subs + 1 ) * 8; |
330 if ( glyph_ids > valid->limit ) | 337 if ( glyph_ids > valid->limit ) |
331 FT_INVALID_TOO_SHORT; | 338 FT_INVALID_TOO_SHORT; |
332 | 339 |
333 /* parse sub-headers */ | 340 /* parse sub-headers */ |
334 for ( n = 0; n <= max_subs; n++ ) | 341 for ( n = 0; n <= max_subs; n++ ) |
335 { | 342 { |
336 FT_UInt first_code, code_count, offset; | 343 FT_UInt first_code, code_count, offset; |
337 FT_Int delta; | 344 FT_Int delta; |
338 | 345 |
339 | 346 |
(...skipping 13 matching lines...) Expand all Loading... |
353 FT_INVALID_DATA; | 360 FT_INVALID_DATA; |
354 } | 361 } |
355 | 362 |
356 /* check offset */ | 363 /* check offset */ |
357 if ( offset != 0 ) | 364 if ( offset != 0 ) |
358 { | 365 { |
359 FT_Byte* ids; | 366 FT_Byte* ids; |
360 | 367 |
361 | 368 |
362 ids = p - 2 + offset; | 369 ids = p - 2 + offset; |
363 if ( ids < glyph_ids || ids + code_count*2 > table + length ) | 370 if ( ids < glyph_ids || ids + code_count * 2 > table + length ) |
364 FT_INVALID_OFFSET; | 371 FT_INVALID_OFFSET; |
365 | 372 |
366 /* check glyph IDs */ | 373 /* check glyph IDs */ |
367 if ( valid->level >= FT_VALIDATE_TIGHT ) | 374 if ( valid->level >= FT_VALIDATE_TIGHT ) |
368 { | 375 { |
369 FT_Byte* limit = p + code_count * 2; | 376 FT_Byte* limit = p + code_count * 2; |
370 FT_UInt idx; | 377 FT_UInt idx; |
371 | 378 |
372 | 379 |
373 for ( ; p < limit; ) | 380 for ( ; p < limit; ) |
374 { | 381 { |
375 idx = TT_NEXT_USHORT( p ); | 382 idx = TT_NEXT_USHORT( p ); |
376 if ( idx != 0 ) | 383 if ( idx != 0 ) |
377 { | 384 { |
378 idx = ( idx + delta ) & 0xFFFFU; | 385 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
379 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) | 386 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) |
380 FT_INVALID_GLYPH_ID; | 387 FT_INVALID_GLYPH_ID; |
381 } | 388 } |
382 } | 389 } |
383 } | 390 } |
384 } | 391 } |
385 } | 392 } |
386 | 393 |
387 return FT_Err_Ok; | 394 return FT_Err_Ok; |
388 } | 395 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 p += char_hi * 2; | 436 p += char_hi * 2; |
430 /* jump to sub-header */ | 437 /* jump to sub-header */ |
431 sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); | 438 sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); |
432 | 439 |
433 /* check that the high byte isn't a valid one-byte value */ | 440 /* check that the high byte isn't a valid one-byte value */ |
434 if ( sub == subs ) | 441 if ( sub == subs ) |
435 goto Exit; | 442 goto Exit; |
436 } | 443 } |
437 result = sub; | 444 result = sub; |
438 } | 445 } |
| 446 |
439 Exit: | 447 Exit: |
440 return result; | 448 return result; |
441 } | 449 } |
442 | 450 |
443 | 451 |
444 FT_CALLBACK_DEF( FT_UInt ) | 452 FT_CALLBACK_DEF( FT_UInt ) |
445 tt_cmap2_char_index( TT_CMap cmap, | 453 tt_cmap2_char_index( TT_CMap cmap, |
446 FT_UInt32 char_code ) | 454 FT_UInt32 char_code ) |
447 { | 455 { |
448 FT_Byte* table = cmap->data; | 456 FT_Byte* table = cmap->data; |
(...skipping 16 matching lines...) Expand all Loading... |
465 delta = TT_NEXT_SHORT ( p ); | 473 delta = TT_NEXT_SHORT ( p ); |
466 offset = TT_PEEK_USHORT( p ); | 474 offset = TT_PEEK_USHORT( p ); |
467 | 475 |
468 idx -= start; | 476 idx -= start; |
469 if ( idx < count && offset != 0 ) | 477 if ( idx < count && offset != 0 ) |
470 { | 478 { |
471 p += offset + 2 * idx; | 479 p += offset + 2 * idx; |
472 idx = TT_PEEK_USHORT( p ); | 480 idx = TT_PEEK_USHORT( p ); |
473 | 481 |
474 if ( idx != 0 ) | 482 if ( idx != 0 ) |
475 result = (FT_UInt)( idx + delta ) & 0xFFFFU; | 483 result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
476 } | 484 } |
477 } | 485 } |
| 486 |
478 return result; | 487 return result; |
479 } | 488 } |
480 | 489 |
481 | 490 |
482 FT_CALLBACK_DEF( FT_UInt32 ) | 491 FT_CALLBACK_DEF( FT_UInt32 ) |
483 tt_cmap2_char_next( TT_CMap cmap, | 492 tt_cmap2_char_next( TT_CMap cmap, |
484 FT_UInt32 *pcharcode ) | 493 FT_UInt32 *pcharcode ) |
485 { | 494 { |
486 FT_Byte* table = cmap->data; | 495 FT_Byte* table = cmap->data; |
487 FT_UInt gindex = 0; | 496 FT_UInt gindex = 0; |
(...skipping 29 matching lines...) Expand all Loading... |
517 | 526 |
518 p += offset + pos * 2; | 527 p += offset + pos * 2; |
519 charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; | 528 charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; |
520 | 529 |
521 for ( ; pos < count; pos++, charcode++ ) | 530 for ( ; pos < count; pos++, charcode++ ) |
522 { | 531 { |
523 idx = TT_NEXT_USHORT( p ); | 532 idx = TT_NEXT_USHORT( p ); |
524 | 533 |
525 if ( idx != 0 ) | 534 if ( idx != 0 ) |
526 { | 535 { |
527 gindex = ( idx + delta ) & 0xFFFFU; | 536 gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
528 if ( gindex != 0 ) | 537 if ( gindex != 0 ) |
529 { | 538 { |
530 result = charcode; | 539 result = charcode; |
531 goto Exit; | 540 goto Exit; |
532 } | 541 } |
533 } | 542 } |
534 } | 543 } |
535 } | 544 } |
536 | 545 |
537 /* jump to next sub-header, i.e. higher byte value */ | 546 /* jump to next sub-header, i.e. higher byte value */ |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); | 788 FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); |
780 | 789 |
781 | 790 |
782 do | 791 do |
783 { | 792 { |
784 FT_UInt gindex = FT_NEXT_USHORT( p ); | 793 FT_UInt gindex = FT_NEXT_USHORT( p ); |
785 | 794 |
786 | 795 |
787 if ( gindex != 0 ) | 796 if ( gindex != 0 ) |
788 { | 797 { |
789 gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); | 798 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
790 if ( gindex != 0 ) | 799 if ( gindex != 0 ) |
791 { | 800 { |
792 cmap->cur_charcode = charcode; | 801 cmap->cur_charcode = charcode; |
793 cmap->cur_gindex = gindex; | 802 cmap->cur_gindex = gindex; |
794 return; | 803 return; |
795 } | 804 } |
796 } | 805 } |
797 } while ( ++charcode <= end ); | 806 } while ( ++charcode <= end ); |
798 } | 807 } |
799 else | 808 else |
800 { | 809 { |
801 do | 810 do |
802 { | 811 { |
803 FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); | 812 FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
804 | 813 |
805 | 814 |
806 if ( gindex != 0 ) | 815 if ( gindex != 0 ) |
807 { | 816 { |
808 cmap->cur_charcode = charcode; | 817 cmap->cur_charcode = charcode; |
809 cmap->cur_gindex = gindex; | 818 cmap->cur_gindex = gindex; |
810 return; | 819 return; |
811 } | 820 } |
812 } while ( ++charcode <= end ); | 821 } while ( ++charcode <= end ); |
813 } | 822 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 } | 975 } |
967 /* Some fonts handle the last segment incorrectly. In */ | 976 /* Some fonts handle the last segment incorrectly. In */ |
968 /* theory, 0xFFFF might point to an ordinary glyph -- */ | 977 /* theory, 0xFFFF might point to an ordinary glyph -- */ |
969 /* a cmap 4 is versatile and could be used for any */ | 978 /* a cmap 4 is versatile and could be used for any */ |
970 /* encoding, not only Unicode. However, reality shows */ | 979 /* encoding, not only Unicode. However, reality shows */ |
971 /* that far too many fonts are sloppy and incorrectly */ | 980 /* that far too many fonts are sloppy and incorrectly */ |
972 /* set all fields but `start' and `end' for the last */ | 981 /* set all fields but `start' and `end' for the last */ |
973 /* segment if it contains only a single character. */ | 982 /* segment if it contains only a single character. */ |
974 /* */ | 983 /* */ |
975 /* We thus omit the test here, delaying it to the */ | 984 /* We thus omit the test here, delaying it to the */ |
976 /* routines which actually access the cmap. */ | 985 /* routines that actually access the cmap. */ |
977 else if ( n != num_segs - 1 || | 986 else if ( n != num_segs - 1 || |
978 !( start == 0xFFFFU && end == 0xFFFFU ) ) | 987 !( start == 0xFFFFU && end == 0xFFFFU ) ) |
979 { | 988 { |
980 if ( p < glyph_ids || | 989 if ( p < glyph_ids || |
981 p + ( end - start + 1 ) * 2 > valid->limit ) | 990 p + ( end - start + 1 ) * 2 > valid->limit ) |
982 FT_INVALID_DATA; | 991 FT_INVALID_DATA; |
983 } | 992 } |
984 | 993 |
985 /* check glyph indices within the segment range */ | 994 /* check glyph indices within the segment range */ |
986 if ( valid->level >= FT_VALIDATE_TIGHT ) | 995 if ( valid->level >= FT_VALIDATE_TIGHT ) |
987 { | 996 { |
988 FT_UInt i, idx; | 997 FT_UInt i, idx; |
989 | 998 |
990 | 999 |
991 for ( i = start; i < end; i++ ) | 1000 for ( i = start; i < end; i++ ) |
992 { | 1001 { |
993 idx = FT_NEXT_USHORT( p ); | 1002 idx = FT_NEXT_USHORT( p ); |
994 if ( idx != 0 ) | 1003 if ( idx != 0 ) |
995 { | 1004 { |
996 idx = (FT_UInt)( idx + delta ) & 0xFFFFU; | 1005 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
997 | 1006 |
998 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) | 1007 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) |
999 FT_INVALID_GLYPH_ID; | 1008 FT_INVALID_GLYPH_ID; |
1000 } | 1009 } |
1001 } | 1010 } |
1002 } | 1011 } |
1003 } | 1012 } |
1004 else if ( offset == 0xFFFFU ) | 1013 else if ( offset == 0xFFFFU ) |
1005 { | 1014 { |
1006 /* some fonts (erroneously?) use a range offset of 0xFFFF */ | 1015 /* some fonts (erroneously?) use a range offset of 0xFFFF */ |
(...skipping 12 matching lines...) Expand all Loading... |
1019 | 1028 |
1020 return error; | 1029 return error; |
1021 } | 1030 } |
1022 | 1031 |
1023 | 1032 |
1024 static FT_UInt | 1033 static FT_UInt |
1025 tt_cmap4_char_map_linear( TT_CMap cmap, | 1034 tt_cmap4_char_map_linear( TT_CMap cmap, |
1026 FT_UInt32* pcharcode, | 1035 FT_UInt32* pcharcode, |
1027 FT_Bool next ) | 1036 FT_Bool next ) |
1028 { | 1037 { |
| 1038 TT_Face face = (TT_Face)cmap->cmap.charmap.face; |
| 1039 FT_Byte* limit = face->cmap_table + face->cmap_size; |
| 1040 |
| 1041 |
1029 FT_UInt num_segs2, start, end, offset; | 1042 FT_UInt num_segs2, start, end, offset; |
1030 FT_Int delta; | 1043 FT_Int delta; |
1031 FT_UInt i, num_segs; | 1044 FT_UInt i, num_segs; |
1032 FT_UInt32 charcode = *pcharcode; | 1045 FT_UInt32 charcode = *pcharcode; |
1033 FT_UInt gindex = 0; | 1046 FT_UInt gindex = 0; |
1034 FT_Byte* p; | 1047 FT_Byte* p; |
| 1048 FT_Byte* q; |
1035 | 1049 |
1036 | 1050 |
1037 p = cmap->data + 6; | 1051 p = cmap->data + 6; |
1038 num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); | 1052 num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); |
1039 | 1053 |
1040 num_segs = num_segs2 >> 1; | 1054 num_segs = num_segs2 >> 1; |
1041 | 1055 |
1042 if ( !num_segs ) | 1056 if ( !num_segs ) |
1043 return 0; | 1057 return 0; |
1044 | 1058 |
1045 if ( next ) | 1059 if ( next ) |
1046 charcode++; | 1060 charcode++; |
1047 | 1061 |
| 1062 if ( charcode > 0xFFFFU ) |
| 1063 return 0; |
| 1064 |
1048 /* linear search */ | 1065 /* linear search */ |
1049 for ( ; charcode <= 0xFFFFU; charcode++ ) | 1066 p = cmap->data + 14; /* ends table */ |
| 1067 q = cmap->data + 16 + num_segs2; /* starts table */ |
| 1068 |
| 1069 for ( i = 0; i < num_segs; i++ ) |
1050 { | 1070 { |
1051 FT_Byte* q; | 1071 end = TT_NEXT_USHORT( p ); |
| 1072 start = TT_NEXT_USHORT( q ); |
| 1073 |
| 1074 if ( charcode < start ) |
| 1075 { |
| 1076 if ( next ) |
| 1077 charcode = start; |
| 1078 else |
| 1079 break; |
| 1080 } |
| 1081 |
| 1082 Again: |
| 1083 if ( charcode <= end ) |
| 1084 { |
| 1085 FT_Byte* r; |
1052 | 1086 |
1053 | 1087 |
1054 p = cmap->data + 14; /* ends table */ | 1088 r = q - 2 + num_segs2; |
1055 q = cmap->data + 16 + num_segs2; /* starts table */ | 1089 delta = TT_PEEK_SHORT( r ); |
| 1090 r += num_segs2; |
| 1091 offset = TT_PEEK_USHORT( r ); |
1056 | 1092 |
1057 for ( i = 0; i < num_segs; i++ ) | 1093 /* some fonts have an incorrect last segment; */ |
1058 { | 1094 /* we have to catch it */ |
1059 end = TT_NEXT_USHORT( p ); | 1095 if ( i >= num_segs - 1 && |
1060 start = TT_NEXT_USHORT( q ); | 1096 start == 0xFFFFU && end == 0xFFFFU ) |
| 1097 { |
| 1098 if ( offset && r + offset + 2 > limit ) |
| 1099 { |
| 1100 delta = 1; |
| 1101 offset = 0; |
| 1102 } |
| 1103 } |
1061 | 1104 |
1062 if ( charcode >= start && charcode <= end ) | 1105 if ( offset == 0xFFFFU ) |
| 1106 continue; |
| 1107 |
| 1108 if ( offset ) |
1063 { | 1109 { |
1064 p = q - 2 + num_segs2; | 1110 r += offset + ( charcode - start ) * 2; |
1065 delta = TT_PEEK_SHORT( p ); | |
1066 p += num_segs2; | |
1067 offset = TT_PEEK_USHORT( p ); | |
1068 | 1111 |
1069 /* some fonts have an incorrect last segment; */ | 1112 /* if r > limit, the whole segment is invalid */ |
1070 /* we have to catch it */ | 1113 if ( next && r > limit ) |
1071 if ( i >= num_segs - 1 && | |
1072 start == 0xFFFFU && end == 0xFFFFU ) | |
1073 { | |
1074 TT_Face face = (TT_Face)cmap->cmap.charmap.face; | |
1075 FT_Byte* limit = face->cmap_table + face->cmap_size; | |
1076 | |
1077 | |
1078 if ( offset && p + offset + 2 > limit ) | |
1079 { | |
1080 delta = 1; | |
1081 offset = 0; | |
1082 } | |
1083 } | |
1084 | |
1085 if ( offset == 0xFFFFU ) | |
1086 continue; | 1114 continue; |
1087 | 1115 |
1088 if ( offset ) | 1116 gindex = TT_PEEK_USHORT( r ); |
| 1117 if ( gindex ) |
1089 { | 1118 { |
1090 p += offset + ( charcode - start ) * 2; | 1119 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
1091 gindex = TT_PEEK_USHORT( p ); | 1120 if ( gindex >= (FT_UInt)face->root.num_glyphs ) |
1092 if ( gindex != 0 ) | 1121 gindex = 0; |
1093 gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; | |
1094 } | 1122 } |
1095 else | 1123 } |
1096 gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; | 1124 else |
| 1125 { |
| 1126 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
1097 | 1127 |
1098 break; | 1128 if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) |
| 1129 { |
| 1130 /* we have an invalid glyph index; if there is an overflow, */ |
| 1131 /* we can adjust `charcode', otherwise the whole segment is */ |
| 1132 /* invalid */ |
| 1133 gindex = 0; |
| 1134 |
| 1135 if ( (FT_Int)charcode + delta < 0 && |
| 1136 (FT_Int)end + delta >= 0 ) |
| 1137 charcode = (FT_UInt)( -delta ); |
| 1138 |
| 1139 else if ( (FT_Int)charcode + delta < 0x10000L && |
| 1140 (FT_Int)end + delta >= 0x10000L ) |
| 1141 charcode = (FT_UInt)( 0x10000L - delta ); |
| 1142 |
| 1143 else |
| 1144 continue; |
| 1145 } |
1099 } | 1146 } |
| 1147 |
| 1148 if ( next && !gindex ) |
| 1149 { |
| 1150 if ( charcode >= 0xFFFFU ) |
| 1151 break; |
| 1152 |
| 1153 charcode++; |
| 1154 goto Again; |
| 1155 } |
| 1156 |
| 1157 break; |
1100 } | 1158 } |
1101 | |
1102 if ( !next || gindex ) | |
1103 break; | |
1104 } | 1159 } |
1105 | 1160 |
1106 if ( next && gindex ) | 1161 if ( next ) |
1107 *pcharcode = charcode; | 1162 *pcharcode = charcode; |
1108 | 1163 |
1109 return gindex; | 1164 return gindex; |
1110 } | 1165 } |
1111 | 1166 |
1112 | 1167 |
1113 static FT_UInt | 1168 static FT_UInt |
1114 tt_cmap4_char_map_binary( TT_CMap cmap, | 1169 tt_cmap4_char_map_binary( TT_CMap cmap, |
1115 FT_UInt32* pcharcode, | 1170 FT_UInt32* pcharcode, |
1116 FT_Bool next ) | 1171 FT_Bool next ) |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 { | 1342 { |
1288 if ( offset == 0xFFFFU ) | 1343 if ( offset == 0xFFFFU ) |
1289 break; | 1344 break; |
1290 } | 1345 } |
1291 | 1346 |
1292 if ( offset ) | 1347 if ( offset ) |
1293 { | 1348 { |
1294 p += offset + ( charcode - start ) * 2; | 1349 p += offset + ( charcode - start ) * 2; |
1295 gindex = TT_PEEK_USHORT( p ); | 1350 gindex = TT_PEEK_USHORT( p ); |
1296 if ( gindex != 0 ) | 1351 if ( gindex != 0 ) |
1297 gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; | 1352 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
1298 } | 1353 } |
1299 else | 1354 else |
1300 gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; | 1355 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
1301 | 1356 |
1302 break; | 1357 break; |
1303 } | 1358 } |
1304 } | 1359 } |
1305 | 1360 |
1306 if ( next ) | 1361 if ( next ) |
1307 { | 1362 { |
1308 TT_CMap4 cmap4 = (TT_CMap4)cmap; | 1363 TT_CMap4 cmap4 = (TT_CMap4)cmap; |
1309 | 1364 |
1310 | 1365 |
1311 /* if `charcode' is not in any segment, then `mid' is */ | 1366 /* if `charcode' is not in any segment, then `mid' is */ |
1312 /* the segment nearest to `charcode' */ | 1367 /* the segment nearest to `charcode' */ |
1313 /* */ | |
1314 | 1368 |
1315 if ( charcode > end ) | 1369 if ( charcode > end ) |
1316 { | 1370 { |
1317 mid++; | 1371 mid++; |
1318 if ( mid == num_segs ) | 1372 if ( mid == num_segs ) |
1319 return 0; | 1373 return 0; |
1320 } | 1374 } |
1321 | 1375 |
1322 if ( tt_cmap4_set_range( cmap4, mid ) ) | 1376 if ( tt_cmap4_set_range( cmap4, mid ) ) |
1323 { | 1377 { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 /*************************************************************************/ | 1490 /*************************************************************************/ |
1437 /*************************************************************************/ | 1491 /*************************************************************************/ |
1438 | 1492 |
1439 /*************************************************************************/ | 1493 /*************************************************************************/ |
1440 /* */ | 1494 /* */ |
1441 /* TABLE OVERVIEW */ | 1495 /* TABLE OVERVIEW */ |
1442 /* -------------- */ | 1496 /* -------------- */ |
1443 /* */ | 1497 /* */ |
1444 /* NAME OFFSET TYPE DESCRIPTION */ | 1498 /* NAME OFFSET TYPE DESCRIPTION */ |
1445 /* */ | 1499 /* */ |
1446 /* format 0 USHORT must be 4 */ | 1500 /* format 0 USHORT must be 6 */ |
1447 /* length 2 USHORT table length in bytes */ | 1501 /* length 2 USHORT table length in bytes */ |
1448 /* language 4 USHORT Mac language code */ | 1502 /* language 4 USHORT Mac language code */ |
1449 /* */ | 1503 /* */ |
1450 /* first 6 USHORT first segment code */ | 1504 /* first 6 USHORT first segment code */ |
1451 /* count 8 USHORT segment size in chars */ | 1505 /* count 8 USHORT segment size in chars */ |
1452 /* glyphIds 10 USHORT[count] glyph IDs */ | 1506 /* glyphIds 10 USHORT[count] glyph IDs */ |
1453 /* */ | 1507 /* */ |
1454 /* A very simplified segment mapping. */ | 1508 /* A very simplified segment mapping. */ |
1455 /* */ | 1509 /* */ |
1456 | 1510 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1504 FT_UInt start = TT_NEXT_USHORT( p ); | 1558 FT_UInt start = TT_NEXT_USHORT( p ); |
1505 FT_UInt count = TT_NEXT_USHORT( p ); | 1559 FT_UInt count = TT_NEXT_USHORT( p ); |
1506 FT_UInt idx = (FT_UInt)( char_code - start ); | 1560 FT_UInt idx = (FT_UInt)( char_code - start ); |
1507 | 1561 |
1508 | 1562 |
1509 if ( idx < count ) | 1563 if ( idx < count ) |
1510 { | 1564 { |
1511 p += 2 * idx; | 1565 p += 2 * idx; |
1512 result = TT_PEEK_USHORT( p ); | 1566 result = TT_PEEK_USHORT( p ); |
1513 } | 1567 } |
| 1568 |
1514 return result; | 1569 return result; |
1515 } | 1570 } |
1516 | 1571 |
1517 | 1572 |
1518 FT_CALLBACK_DEF( FT_UInt32 ) | 1573 FT_CALLBACK_DEF( FT_UInt32 ) |
1519 tt_cmap6_char_next( TT_CMap cmap, | 1574 tt_cmap6_char_next( TT_CMap cmap, |
1520 FT_UInt32 *pchar_code ) | 1575 FT_UInt32 *pchar_code ) |
1521 { | 1576 { |
1522 FT_Byte* table = cmap->data; | 1577 FT_Byte* table = cmap->data; |
1523 FT_UInt32 result = 0; | 1578 FT_UInt32 result = 0; |
1524 FT_UInt32 char_code = *pchar_code + 1; | 1579 FT_UInt32 char_code = *pchar_code + 1; |
1525 FT_UInt gindex = 0; | 1580 FT_UInt gindex = 0; |
1526 | 1581 |
1527 FT_Byte* p = table + 6; | 1582 FT_Byte* p = table + 6; |
1528 FT_UInt start = TT_NEXT_USHORT( p ); | 1583 FT_UInt start = TT_NEXT_USHORT( p ); |
1529 FT_UInt count = TT_NEXT_USHORT( p ); | 1584 FT_UInt count = TT_NEXT_USHORT( p ); |
1530 FT_UInt idx; | 1585 FT_UInt idx; |
1531 | 1586 |
1532 | 1587 |
1533 if ( char_code >= 0x10000UL ) | 1588 if ( char_code >= 0x10000UL ) |
1534 goto Exit; | 1589 return 0; |
1535 | 1590 |
1536 if ( char_code < start ) | 1591 if ( char_code < start ) |
1537 char_code = start; | 1592 char_code = start; |
1538 | 1593 |
1539 idx = (FT_UInt)( char_code - start ); | 1594 idx = (FT_UInt)( char_code - start ); |
1540 p += 2 * idx; | 1595 p += 2 * idx; |
1541 | 1596 |
1542 for ( ; idx < count; idx++ ) | 1597 for ( ; idx < count; idx++ ) |
1543 { | 1598 { |
1544 gindex = TT_NEXT_USHORT( p ); | 1599 gindex = TT_NEXT_USHORT( p ); |
1545 if ( gindex != 0 ) | 1600 if ( gindex != 0 ) |
1546 { | 1601 { |
1547 result = char_code; | 1602 result = char_code; |
1548 break; | 1603 break; |
1549 } | 1604 } |
| 1605 |
| 1606 if ( char_code >= 0xFFFFU ) |
| 1607 return 0; |
| 1608 |
1550 char_code++; | 1609 char_code++; |
1551 } | 1610 } |
1552 | 1611 |
1553 Exit: | |
1554 *pchar_code = result; | 1612 *pchar_code = result; |
1555 return gindex; | 1613 return gindex; |
1556 } | 1614 } |
1557 | 1615 |
1558 | 1616 |
1559 FT_CALLBACK_DEF( FT_Error ) | 1617 FT_CALLBACK_DEF( FT_Error ) |
1560 tt_cmap6_get_info( TT_CMap cmap, | 1618 tt_cmap6_get_info( TT_CMap cmap, |
1561 TT_CMapInfo *cmap_info ) | 1619 TT_CMapInfo *cmap_info ) |
1562 { | 1620 { |
1563 FT_Byte* p = cmap->data + 4; | 1621 FT_Byte* p = cmap->data + 4; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 /*************************************************************************/ | 1653 /*************************************************************************/ |
1596 /*************************************************************************/ | 1654 /*************************************************************************/ |
1597 /***** *****/ | 1655 /***** *****/ |
1598 /***** FORMAT 8 *****/ | 1656 /***** FORMAT 8 *****/ |
1599 /***** *****/ | 1657 /***** *****/ |
1600 /***** It is hard to completely understand what the OpenType spec *****/ | 1658 /***** It is hard to completely understand what the OpenType spec *****/ |
1601 /***** says about this format, but here is my conclusion. *****/ | 1659 /***** says about this format, but here is my conclusion. *****/ |
1602 /***** *****/ | 1660 /***** *****/ |
1603 /***** The purpose of this format is to easily map UTF-16 text to *****/ | 1661 /***** The purpose of this format is to easily map UTF-16 text to *****/ |
1604 /***** glyph indices. Basically, the `char_code' must be in one of *****/ | 1662 /***** glyph indices. Basically, the `char_code' must be in one of *****/ |
1605 /***** the following formats: *****/ | 1663 /***** the following formats. *****/ |
1606 /***** *****/ | 1664 /***** *****/ |
1607 /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ | 1665 /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ |
1608 /***** Area (i.e. U+D800-U+DFFF). *****/ | 1666 /***** Area (i.e. U+D800-U+DFFF). *****/ |
1609 /***** *****/ | 1667 /***** *****/ |
1610 /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ | 1668 /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ |
1611 /***** `char_code = (char_hi << 16) | char_lo', then both *****/ | 1669 /***** `char_code = (char_hi << 16) | char_lo', then both *****/ |
1612 /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ | 1670 /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ |
1613 /***** Area. *****/ | 1671 /***** Area. *****/ |
1614 /***** *****/ | 1672 /***** *****/ |
1615 /***** The `is32' table embedded in the charmap indicates whether a *****/ | 1673 /***** The `is32' table embedded in the charmap indicates whether a *****/ |
1616 /***** given 16-bit value is in the surrogates area or not. *****/ | 1674 /***** given 16-bit value is in the surrogates area or not. *****/ |
1617 /***** *****/ | 1675 /***** *****/ |
1618 /***** So, for any given `char_code', we can assert the following: *****/ | 1676 /***** So, for any given `char_code', we can assert the following. *****/ |
1619 /***** *****/ | 1677 /***** *****/ |
1620 /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ | 1678 /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ |
1621 /***** *****/ | 1679 /***** *****/ |
1622 /***** If `char_hi != 0' then we must have both *****/ | 1680 /***** If `char_hi != 0' then we must have both *****/ |
1623 /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ | 1681 /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ |
1624 /***** *****/ | 1682 /***** *****/ |
1625 /*************************************************************************/ | 1683 /*************************************************************************/ |
1626 /*************************************************************************/ | 1684 /*************************************************************************/ |
1627 | 1685 |
1628 /*************************************************************************/ | 1686 /*************************************************************************/ |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1763 { | 1821 { |
1764 start = TT_NEXT_ULONG( p ); | 1822 start = TT_NEXT_ULONG( p ); |
1765 end = TT_NEXT_ULONG( p ); | 1823 end = TT_NEXT_ULONG( p ); |
1766 start_id = TT_NEXT_ULONG( p ); | 1824 start_id = TT_NEXT_ULONG( p ); |
1767 | 1825 |
1768 if ( char_code < start ) | 1826 if ( char_code < start ) |
1769 break; | 1827 break; |
1770 | 1828 |
1771 if ( char_code <= end ) | 1829 if ( char_code <= end ) |
1772 { | 1830 { |
1773 result = (FT_UInt)( start_id + char_code - start ); | 1831 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
| 1832 return 0; |
| 1833 |
| 1834 result = (FT_UInt)( start_id + ( char_code - start ) ); |
1774 break; | 1835 break; |
1775 } | 1836 } |
1776 } | 1837 } |
1777 return result; | 1838 return result; |
1778 } | 1839 } |
1779 | 1840 |
1780 | 1841 |
1781 FT_CALLBACK_DEF( FT_UInt32 ) | 1842 FT_CALLBACK_DEF( FT_UInt32 ) |
1782 tt_cmap8_char_next( TT_CMap cmap, | 1843 tt_cmap8_char_next( TT_CMap cmap, |
1783 FT_UInt32 *pchar_code ) | 1844 FT_UInt32 *pchar_code ) |
1784 { | 1845 { |
| 1846 FT_Face face = cmap->cmap.charmap.face; |
1785 FT_UInt32 result = 0; | 1847 FT_UInt32 result = 0; |
1786 FT_UInt32 char_code = *pchar_code + 1; | 1848 FT_UInt32 char_code; |
1787 FT_UInt gindex = 0; | 1849 FT_UInt gindex = 0; |
1788 FT_Byte* table = cmap->data; | 1850 FT_Byte* table = cmap->data; |
1789 FT_Byte* p = table + 8204; | 1851 FT_Byte* p = table + 8204; |
1790 FT_UInt32 num_groups = TT_NEXT_ULONG( p ); | 1852 FT_UInt32 num_groups = TT_NEXT_ULONG( p ); |
1791 FT_UInt32 start, end, start_id; | 1853 FT_UInt32 start, end, start_id; |
1792 | 1854 |
1793 | 1855 |
| 1856 if ( *pchar_code >= 0xFFFFFFFFUL ) |
| 1857 return 0; |
| 1858 |
| 1859 char_code = *pchar_code + 1; |
| 1860 |
1794 p = table + 8208; | 1861 p = table + 8208; |
1795 | 1862 |
1796 for ( ; num_groups > 0; num_groups-- ) | 1863 for ( ; num_groups > 0; num_groups-- ) |
1797 { | 1864 { |
1798 start = TT_NEXT_ULONG( p ); | 1865 start = TT_NEXT_ULONG( p ); |
1799 end = TT_NEXT_ULONG( p ); | 1866 end = TT_NEXT_ULONG( p ); |
1800 start_id = TT_NEXT_ULONG( p ); | 1867 start_id = TT_NEXT_ULONG( p ); |
1801 | 1868 |
1802 if ( char_code < start ) | 1869 if ( char_code < start ) |
1803 char_code = start; | 1870 char_code = start; |
1804 | 1871 |
| 1872 Again: |
1805 if ( char_code <= end ) | 1873 if ( char_code <= end ) |
1806 { | 1874 { |
1807 gindex = (FT_UInt)( char_code - start + start_id ); | 1875 /* ignore invalid group */ |
1808 if ( gindex != 0 ) | 1876 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
| 1877 continue; |
| 1878 |
| 1879 gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
| 1880 |
| 1881 /* does first element of group point to `.notdef' glyph? */ |
| 1882 if ( gindex == 0 ) |
1809 { | 1883 { |
1810 result = char_code; | 1884 if ( char_code >= 0xFFFFFFFFUL ) |
1811 goto Exit; | 1885 break; |
| 1886 |
| 1887 char_code++; |
| 1888 goto Again; |
1812 } | 1889 } |
| 1890 |
| 1891 /* if `gindex' is invalid, the remaining values */ |
| 1892 /* in this group are invalid, too */ |
| 1893 if ( gindex >= (FT_UInt)face->num_glyphs ) |
| 1894 continue; |
| 1895 |
| 1896 result = char_code; |
| 1897 break; |
1813 } | 1898 } |
1814 } | 1899 } |
1815 | 1900 |
1816 Exit: | |
1817 *pchar_code = result; | 1901 *pchar_code = result; |
1818 return gindex; | 1902 return gindex; |
1819 } | 1903 } |
1820 | 1904 |
1821 | 1905 |
1822 FT_CALLBACK_DEF( FT_Error ) | 1906 FT_CALLBACK_DEF( FT_Error ) |
1823 tt_cmap8_get_info( TT_CMap cmap, | 1907 tt_cmap8_get_info( TT_CMap cmap, |
1824 TT_CMapInfo *cmap_info ) | 1908 TT_CMapInfo *cmap_info ) |
1825 { | 1909 { |
1826 FT_Byte* p = cmap->data + 8; | 1910 FT_Byte* p = cmap->data + 8; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1923 | 2007 |
1924 FT_CALLBACK_DEF( FT_UInt ) | 2008 FT_CALLBACK_DEF( FT_UInt ) |
1925 tt_cmap10_char_index( TT_CMap cmap, | 2009 tt_cmap10_char_index( TT_CMap cmap, |
1926 FT_UInt32 char_code ) | 2010 FT_UInt32 char_code ) |
1927 { | 2011 { |
1928 FT_Byte* table = cmap->data; | 2012 FT_Byte* table = cmap->data; |
1929 FT_UInt result = 0; | 2013 FT_UInt result = 0; |
1930 FT_Byte* p = table + 12; | 2014 FT_Byte* p = table + 12; |
1931 FT_UInt32 start = TT_NEXT_ULONG( p ); | 2015 FT_UInt32 start = TT_NEXT_ULONG( p ); |
1932 FT_UInt32 count = TT_NEXT_ULONG( p ); | 2016 FT_UInt32 count = TT_NEXT_ULONG( p ); |
1933 FT_UInt32 idx = (FT_ULong)( char_code - start ); | 2017 FT_UInt32 idx; |
1934 | 2018 |
1935 | 2019 |
| 2020 if ( char_code < start ) |
| 2021 return 0; |
| 2022 |
| 2023 idx = char_code - start; |
| 2024 |
1936 if ( idx < count ) | 2025 if ( idx < count ) |
1937 { | 2026 { |
1938 p += 2 * idx; | 2027 p += 2 * idx; |
1939 result = TT_PEEK_USHORT( p ); | 2028 result = TT_PEEK_USHORT( p ); |
1940 } | 2029 } |
| 2030 |
1941 return result; | 2031 return result; |
1942 } | 2032 } |
1943 | 2033 |
1944 | 2034 |
1945 FT_CALLBACK_DEF( FT_UInt32 ) | 2035 FT_CALLBACK_DEF( FT_UInt32 ) |
1946 tt_cmap10_char_next( TT_CMap cmap, | 2036 tt_cmap10_char_next( TT_CMap cmap, |
1947 FT_UInt32 *pchar_code ) | 2037 FT_UInt32 *pchar_code ) |
1948 { | 2038 { |
1949 FT_Byte* table = cmap->data; | 2039 FT_Byte* table = cmap->data; |
1950 FT_UInt32 char_code = *pchar_code + 1; | 2040 FT_UInt32 char_code; |
1951 FT_UInt gindex = 0; | 2041 FT_UInt gindex = 0; |
1952 FT_Byte* p = table + 12; | 2042 FT_Byte* p = table + 12; |
1953 FT_UInt32 start = TT_NEXT_ULONG( p ); | 2043 FT_UInt32 start = TT_NEXT_ULONG( p ); |
1954 FT_UInt32 count = TT_NEXT_ULONG( p ); | 2044 FT_UInt32 count = TT_NEXT_ULONG( p ); |
1955 FT_UInt32 idx; | 2045 FT_UInt32 idx; |
1956 | 2046 |
1957 | 2047 |
| 2048 if ( *pchar_code >= 0xFFFFFFFFUL ) |
| 2049 return 0; |
| 2050 |
| 2051 char_code = *pchar_code + 1; |
| 2052 |
1958 if ( char_code < start ) | 2053 if ( char_code < start ) |
1959 char_code = start; | 2054 char_code = start; |
1960 | 2055 |
1961 idx = (FT_UInt32)( char_code - start ); | 2056 idx = char_code - start; |
1962 p += 2 * idx; | 2057 p += 2 * idx; |
1963 | 2058 |
1964 for ( ; idx < count; idx++ ) | 2059 for ( ; idx < count; idx++ ) |
1965 { | 2060 { |
1966 gindex = TT_NEXT_USHORT( p ); | 2061 gindex = TT_NEXT_USHORT( p ); |
1967 if ( gindex != 0 ) | 2062 if ( gindex != 0 ) |
1968 break; | 2063 break; |
| 2064 |
| 2065 if ( char_code >= 0xFFFFFFFFUL ) |
| 2066 return 0; |
| 2067 |
1969 char_code++; | 2068 char_code++; |
1970 } | 2069 } |
1971 | 2070 |
1972 *pchar_code = char_code; | 2071 *pchar_code = char_code; |
1973 return gindex; | 2072 return gindex; |
1974 } | 2073 } |
1975 | 2074 |
1976 | 2075 |
1977 FT_CALLBACK_DEF( FT_Error ) | 2076 FT_CALLBACK_DEF( FT_Error ) |
1978 tt_cmap10_get_info( TT_CMap cmap, | 2077 tt_cmap10_get_info( TT_CMap cmap, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2127 return FT_Err_Ok; | 2226 return FT_Err_Ok; |
2128 } | 2227 } |
2129 | 2228 |
2130 | 2229 |
2131 /* search the index of the charcode next to cmap->cur_charcode */ | 2230 /* search the index of the charcode next to cmap->cur_charcode */ |
2132 /* cmap->cur_group should be set up properly by caller */ | 2231 /* cmap->cur_group should be set up properly by caller */ |
2133 /* */ | 2232 /* */ |
2134 static void | 2233 static void |
2135 tt_cmap12_next( TT_CMap12 cmap ) | 2234 tt_cmap12_next( TT_CMap12 cmap ) |
2136 { | 2235 { |
| 2236 FT_Face face = cmap->cmap.cmap.charmap.face; |
2137 FT_Byte* p; | 2237 FT_Byte* p; |
2138 FT_ULong start, end, start_id, char_code; | 2238 FT_ULong start, end, start_id, char_code; |
2139 FT_ULong n; | 2239 FT_ULong n; |
2140 FT_UInt gindex; | 2240 FT_UInt gindex; |
2141 | 2241 |
2142 | 2242 |
2143 if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) | 2243 if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) |
2144 goto Fail; | 2244 goto Fail; |
2145 | 2245 |
2146 char_code = cmap->cur_charcode + 1; | 2246 char_code = cmap->cur_charcode + 1; |
2147 | 2247 |
2148 for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) | 2248 for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) |
2149 { | 2249 { |
2150 p = cmap->cmap.data + 16 + 12 * n; | 2250 p = cmap->cmap.data + 16 + 12 * n; |
2151 start = TT_NEXT_ULONG( p ); | 2251 start = TT_NEXT_ULONG( p ); |
2152 end = TT_NEXT_ULONG( p ); | 2252 end = TT_NEXT_ULONG( p ); |
2153 start_id = TT_PEEK_ULONG( p ); | 2253 start_id = TT_PEEK_ULONG( p ); |
2154 | 2254 |
2155 if ( char_code < start ) | 2255 if ( char_code < start ) |
2156 char_code = start; | 2256 char_code = start; |
2157 | 2257 |
2158 for ( ; char_code <= end; char_code++ ) | 2258 Again: |
| 2259 if ( char_code <= end ) |
2159 { | 2260 { |
2160 gindex = (FT_UInt)( start_id + char_code - start ); | 2261 /* ignore invalid group */ |
| 2262 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
| 2263 continue; |
2161 | 2264 |
2162 if ( gindex ) | 2265 gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
| 2266 |
| 2267 /* does first element of group point to `.notdef' glyph? */ |
| 2268 if ( gindex == 0 ) |
2163 { | 2269 { |
2164 cmap->cur_charcode = char_code;; | 2270 if ( char_code >= 0xFFFFFFFFUL ) |
2165 cmap->cur_gindex = gindex; | 2271 goto Fail; |
2166 cmap->cur_group = n; | |
2167 | 2272 |
2168 return; | 2273 char_code++; |
| 2274 goto Again; |
2169 } | 2275 } |
| 2276 |
| 2277 /* if `gindex' is invalid, the remaining values */ |
| 2278 /* in this group are invalid, too */ |
| 2279 if ( gindex >= (FT_UInt)face->num_glyphs ) |
| 2280 continue; |
| 2281 |
| 2282 cmap->cur_charcode = char_code; |
| 2283 cmap->cur_gindex = gindex; |
| 2284 cmap->cur_group = n; |
| 2285 |
| 2286 return; |
2170 } | 2287 } |
2171 } | 2288 } |
2172 | 2289 |
2173 Fail: | 2290 Fail: |
2174 cmap->valid = 0; | 2291 cmap->valid = 0; |
2175 } | 2292 } |
2176 | 2293 |
2177 | 2294 |
2178 static FT_UInt | 2295 static FT_UInt |
2179 tt_cmap12_char_map_binary( TT_CMap cmap, | 2296 tt_cmap12_char_map_binary( TT_CMap cmap, |
2180 FT_UInt32* pchar_code, | 2297 FT_UInt32* pchar_code, |
2181 FT_Bool next ) | 2298 FT_Bool next ) |
2182 { | 2299 { |
2183 FT_UInt gindex = 0; | 2300 FT_UInt gindex = 0; |
2184 FT_Byte* p = cmap->data + 12; | 2301 FT_Byte* p = cmap->data + 12; |
2185 FT_UInt32 num_groups = TT_PEEK_ULONG( p ); | 2302 FT_UInt32 num_groups = TT_PEEK_ULONG( p ); |
2186 FT_UInt32 char_code = *pchar_code; | 2303 FT_UInt32 char_code = *pchar_code; |
2187 FT_UInt32 start, end, start_id; | 2304 FT_UInt32 start, end, start_id; |
2188 FT_UInt32 max, min, mid; | 2305 FT_UInt32 max, min, mid; |
2189 | 2306 |
2190 | 2307 |
2191 if ( !num_groups ) | 2308 if ( !num_groups ) |
2192 return 0; | 2309 return 0; |
2193 | 2310 |
2194 /* make compiler happy */ | 2311 /* make compiler happy */ |
2195 mid = num_groups; | 2312 mid = num_groups; |
2196 end = 0xFFFFFFFFUL; | 2313 end = 0xFFFFFFFFUL; |
2197 | 2314 |
2198 if ( next ) | 2315 if ( next ) |
| 2316 { |
| 2317 if ( char_code >= 0xFFFFFFFFUL ) |
| 2318 return 0; |
| 2319 |
2199 char_code++; | 2320 char_code++; |
| 2321 } |
2200 | 2322 |
2201 min = 0; | 2323 min = 0; |
2202 max = num_groups; | 2324 max = num_groups; |
2203 | 2325 |
2204 /* binary search */ | 2326 /* binary search */ |
2205 while ( min < max ) | 2327 while ( min < max ) |
2206 { | 2328 { |
2207 mid = ( min + max ) >> 1; | 2329 mid = ( min + max ) >> 1; |
2208 p = cmap->data + 16 + 12 * mid; | 2330 p = cmap->data + 16 + 12 * mid; |
2209 | 2331 |
2210 start = TT_NEXT_ULONG( p ); | 2332 start = TT_NEXT_ULONG( p ); |
2211 end = TT_NEXT_ULONG( p ); | 2333 end = TT_NEXT_ULONG( p ); |
2212 | 2334 |
2213 if ( char_code < start ) | 2335 if ( char_code < start ) |
2214 max = mid; | 2336 max = mid; |
2215 else if ( char_code > end ) | 2337 else if ( char_code > end ) |
2216 min = mid + 1; | 2338 min = mid + 1; |
2217 else | 2339 else |
2218 { | 2340 { |
2219 start_id = TT_PEEK_ULONG( p ); | 2341 start_id = TT_PEEK_ULONG( p ); |
2220 gindex = (FT_UInt)( start_id + char_code - start ); | |
2221 | 2342 |
| 2343 /* reject invalid glyph index */ |
| 2344 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
| 2345 gindex = 0; |
| 2346 else |
| 2347 gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
2222 break; | 2348 break; |
2223 } | 2349 } |
2224 } | 2350 } |
2225 | 2351 |
2226 if ( next ) | 2352 if ( next ) |
2227 { | 2353 { |
| 2354 FT_Face face = cmap->cmap.charmap.face; |
2228 TT_CMap12 cmap12 = (TT_CMap12)cmap; | 2355 TT_CMap12 cmap12 = (TT_CMap12)cmap; |
2229 | 2356 |
2230 | 2357 |
2231 /* if `char_code' is not in any group, then `mid' is */ | 2358 /* if `char_code' is not in any group, then `mid' is */ |
2232 /* the group nearest to `char_code' */ | 2359 /* the group nearest to `char_code' */ |
2233 /* */ | |
2234 | 2360 |
2235 if ( char_code > end ) | 2361 if ( char_code > end ) |
2236 { | 2362 { |
2237 mid++; | 2363 mid++; |
2238 if ( mid == num_groups ) | 2364 if ( mid == num_groups ) |
2239 return 0; | 2365 return 0; |
2240 } | 2366 } |
2241 | 2367 |
2242 cmap12->valid = 1; | 2368 cmap12->valid = 1; |
2243 cmap12->cur_charcode = char_code; | 2369 cmap12->cur_charcode = char_code; |
2244 cmap12->cur_group = mid; | 2370 cmap12->cur_group = mid; |
2245 | 2371 |
| 2372 if ( gindex >= (FT_UInt)face->num_glyphs ) |
| 2373 gindex = 0; |
| 2374 |
2246 if ( !gindex ) | 2375 if ( !gindex ) |
2247 { | 2376 { |
2248 tt_cmap12_next( cmap12 ); | 2377 tt_cmap12_next( cmap12 ); |
2249 | 2378 |
2250 if ( cmap12->valid ) | 2379 if ( cmap12->valid ) |
2251 gindex = cmap12->cur_gindex; | 2380 gindex = cmap12->cur_gindex; |
2252 } | 2381 } |
2253 else | 2382 else |
2254 cmap12->cur_gindex = gindex; | 2383 cmap12->cur_gindex = gindex; |
2255 | 2384 |
2256 if ( gindex ) | 2385 *pchar_code = cmap12->cur_charcode; |
2257 *pchar_code = cmap12->cur_charcode; | |
2258 } | 2386 } |
2259 | 2387 |
2260 return gindex; | 2388 return gindex; |
2261 } | 2389 } |
2262 | 2390 |
2263 | 2391 |
2264 FT_CALLBACK_DEF( FT_UInt ) | 2392 FT_CALLBACK_DEF( FT_UInt ) |
2265 tt_cmap12_char_index( TT_CMap cmap, | 2393 tt_cmap12_char_index( TT_CMap cmap, |
2266 FT_UInt32 char_code ) | 2394 FT_UInt32 char_code ) |
2267 { | 2395 { |
2268 return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); | 2396 return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); |
2269 } | 2397 } |
2270 | 2398 |
2271 | 2399 |
2272 FT_CALLBACK_DEF( FT_UInt32 ) | 2400 FT_CALLBACK_DEF( FT_UInt32 ) |
2273 tt_cmap12_char_next( TT_CMap cmap, | 2401 tt_cmap12_char_next( TT_CMap cmap, |
2274 FT_UInt32 *pchar_code ) | 2402 FT_UInt32 *pchar_code ) |
2275 { | 2403 { |
2276 TT_CMap12 cmap12 = (TT_CMap12)cmap; | 2404 TT_CMap12 cmap12 = (TT_CMap12)cmap; |
2277 FT_ULong gindex; | 2405 FT_UInt gindex; |
2278 | 2406 |
2279 | 2407 |
2280 if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) | |
2281 return 0; | |
2282 | |
2283 /* no need to search */ | 2408 /* no need to search */ |
2284 if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) | 2409 if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) |
2285 { | 2410 { |
2286 tt_cmap12_next( cmap12 ); | 2411 tt_cmap12_next( cmap12 ); |
2287 if ( cmap12->valid ) | 2412 if ( cmap12->valid ) |
2288 { | 2413 { |
2289 gindex = cmap12->cur_gindex; | 2414 gindex = cmap12->cur_gindex; |
2290 | 2415 *pchar_code = (FT_UInt32)cmap12->cur_charcode; |
2291 /* XXX: check cur_charcode overflow is expected */ | |
2292 if ( gindex ) | |
2293 *pchar_code = (FT_UInt32)cmap12->cur_charcode; | |
2294 } | 2416 } |
2295 else | 2417 else |
2296 gindex = 0; | 2418 gindex = 0; |
2297 } | 2419 } |
2298 else | 2420 else |
2299 gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); | 2421 gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); |
2300 | 2422 |
2301 /* XXX: check gindex overflow is expected */ | 2423 return gindex; |
2302 return (FT_UInt32)gindex; | |
2303 } | 2424 } |
2304 | 2425 |
2305 | 2426 |
2306 FT_CALLBACK_DEF( FT_Error ) | 2427 FT_CALLBACK_DEF( FT_Error ) |
2307 tt_cmap12_get_info( TT_CMap cmap, | 2428 tt_cmap12_get_info( TT_CMap cmap, |
2308 TT_CMapInfo *cmap_info ) | 2429 TT_CMapInfo *cmap_info ) |
2309 { | 2430 { |
2310 FT_Byte* p = cmap->data + 8; | 2431 FT_Byte* p = cmap->data + 8; |
2311 | 2432 |
2312 | 2433 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 return FT_Err_Ok; | 2572 return FT_Err_Ok; |
2452 } | 2573 } |
2453 | 2574 |
2454 | 2575 |
2455 /* search the index of the charcode next to cmap->cur_charcode */ | 2576 /* search the index of the charcode next to cmap->cur_charcode */ |
2456 /* cmap->cur_group should be set up properly by caller */ | 2577 /* cmap->cur_group should be set up properly by caller */ |
2457 /* */ | 2578 /* */ |
2458 static void | 2579 static void |
2459 tt_cmap13_next( TT_CMap13 cmap ) | 2580 tt_cmap13_next( TT_CMap13 cmap ) |
2460 { | 2581 { |
| 2582 FT_Face face = cmap->cmap.cmap.charmap.face; |
2461 FT_Byte* p; | 2583 FT_Byte* p; |
2462 FT_ULong start, end, glyph_id, char_code; | 2584 FT_ULong start, end, glyph_id, char_code; |
2463 FT_ULong n; | 2585 FT_ULong n; |
2464 FT_UInt gindex; | 2586 FT_UInt gindex; |
2465 | 2587 |
2466 | 2588 |
2467 if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) | 2589 if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) |
2468 goto Fail; | 2590 goto Fail; |
2469 | 2591 |
2470 char_code = cmap->cur_charcode + 1; | 2592 char_code = cmap->cur_charcode + 1; |
2471 | 2593 |
2472 for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) | 2594 for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) |
2473 { | 2595 { |
2474 p = cmap->cmap.data + 16 + 12 * n; | 2596 p = cmap->cmap.data + 16 + 12 * n; |
2475 start = TT_NEXT_ULONG( p ); | 2597 start = TT_NEXT_ULONG( p ); |
2476 end = TT_NEXT_ULONG( p ); | 2598 end = TT_NEXT_ULONG( p ); |
2477 glyph_id = TT_PEEK_ULONG( p ); | 2599 glyph_id = TT_PEEK_ULONG( p ); |
2478 | 2600 |
2479 if ( char_code < start ) | 2601 if ( char_code < start ) |
2480 char_code = start; | 2602 char_code = start; |
2481 | 2603 |
2482 if ( char_code <= end ) | 2604 if ( char_code <= end ) |
2483 { | 2605 { |
2484 gindex = (FT_UInt)glyph_id; | 2606 gindex = (FT_UInt)glyph_id; |
2485 | 2607 |
2486 if ( gindex ) | 2608 if ( gindex && gindex < (FT_UInt)face->num_glyphs ) |
2487 { | 2609 { |
2488 cmap->cur_charcode = char_code;; | 2610 cmap->cur_charcode = char_code; |
2489 cmap->cur_gindex = gindex; | 2611 cmap->cur_gindex = gindex; |
2490 cmap->cur_group = n; | 2612 cmap->cur_group = n; |
2491 | 2613 |
2492 return; | 2614 return; |
2493 } | 2615 } |
2494 } | 2616 } |
2495 } | 2617 } |
2496 | 2618 |
2497 Fail: | 2619 Fail: |
2498 cmap->valid = 0; | 2620 cmap->valid = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
2513 | 2635 |
2514 | 2636 |
2515 if ( !num_groups ) | 2637 if ( !num_groups ) |
2516 return 0; | 2638 return 0; |
2517 | 2639 |
2518 /* make compiler happy */ | 2640 /* make compiler happy */ |
2519 mid = num_groups; | 2641 mid = num_groups; |
2520 end = 0xFFFFFFFFUL; | 2642 end = 0xFFFFFFFFUL; |
2521 | 2643 |
2522 if ( next ) | 2644 if ( next ) |
| 2645 { |
| 2646 if ( char_code >= 0xFFFFFFFFUL ) |
| 2647 return 0; |
| 2648 |
2523 char_code++; | 2649 char_code++; |
| 2650 } |
2524 | 2651 |
2525 min = 0; | 2652 min = 0; |
2526 max = num_groups; | 2653 max = num_groups; |
2527 | 2654 |
2528 /* binary search */ | 2655 /* binary search */ |
2529 while ( min < max ) | 2656 while ( min < max ) |
2530 { | 2657 { |
2531 mid = ( min + max ) >> 1; | 2658 mid = ( min + max ) >> 1; |
2532 p = cmap->data + 16 + 12 * mid; | 2659 p = cmap->data + 16 + 12 * mid; |
2533 | 2660 |
2534 start = TT_NEXT_ULONG( p ); | 2661 start = TT_NEXT_ULONG( p ); |
2535 end = TT_NEXT_ULONG( p ); | 2662 end = TT_NEXT_ULONG( p ); |
2536 | 2663 |
2537 if ( char_code < start ) | 2664 if ( char_code < start ) |
2538 max = mid; | 2665 max = mid; |
2539 else if ( char_code > end ) | 2666 else if ( char_code > end ) |
2540 min = mid + 1; | 2667 min = mid + 1; |
2541 else | 2668 else |
2542 { | 2669 { |
2543 gindex = (FT_UInt)TT_PEEK_ULONG( p ); | 2670 gindex = (FT_UInt)TT_PEEK_ULONG( p ); |
2544 | 2671 |
2545 break; | 2672 break; |
2546 } | 2673 } |
2547 } | 2674 } |
2548 | 2675 |
2549 if ( next ) | 2676 if ( next ) |
2550 { | 2677 { |
| 2678 FT_Face face = cmap->cmap.charmap.face; |
2551 TT_CMap13 cmap13 = (TT_CMap13)cmap; | 2679 TT_CMap13 cmap13 = (TT_CMap13)cmap; |
2552 | 2680 |
2553 | 2681 |
2554 /* if `char_code' is not in any group, then `mid' is */ | 2682 /* if `char_code' is not in any group, then `mid' is */ |
2555 /* the group nearest to `char_code' */ | 2683 /* the group nearest to `char_code' */ |
2556 | 2684 |
2557 if ( char_code > end ) | 2685 if ( char_code > end ) |
2558 { | 2686 { |
2559 mid++; | 2687 mid++; |
2560 if ( mid == num_groups ) | 2688 if ( mid == num_groups ) |
2561 return 0; | 2689 return 0; |
2562 } | 2690 } |
2563 | 2691 |
2564 cmap13->valid = 1; | 2692 cmap13->valid = 1; |
2565 cmap13->cur_charcode = char_code; | 2693 cmap13->cur_charcode = char_code; |
2566 cmap13->cur_group = mid; | 2694 cmap13->cur_group = mid; |
2567 | 2695 |
| 2696 if ( gindex >= (FT_UInt)face->num_glyphs ) |
| 2697 gindex = 0; |
| 2698 |
2568 if ( !gindex ) | 2699 if ( !gindex ) |
2569 { | 2700 { |
2570 tt_cmap13_next( cmap13 ); | 2701 tt_cmap13_next( cmap13 ); |
2571 | 2702 |
2572 if ( cmap13->valid ) | 2703 if ( cmap13->valid ) |
2573 gindex = cmap13->cur_gindex; | 2704 gindex = cmap13->cur_gindex; |
2574 } | 2705 } |
2575 else | 2706 else |
2576 cmap13->cur_gindex = gindex; | 2707 cmap13->cur_gindex = gindex; |
2577 | 2708 |
2578 if ( gindex ) | 2709 *pchar_code = cmap13->cur_charcode; |
2579 *pchar_code = cmap13->cur_charcode; | |
2580 } | 2710 } |
2581 | 2711 |
2582 return gindex; | 2712 return gindex; |
2583 } | 2713 } |
2584 | 2714 |
2585 | 2715 |
2586 FT_CALLBACK_DEF( FT_UInt ) | 2716 FT_CALLBACK_DEF( FT_UInt ) |
2587 tt_cmap13_char_index( TT_CMap cmap, | 2717 tt_cmap13_char_index( TT_CMap cmap, |
2588 FT_UInt32 char_code ) | 2718 FT_UInt32 char_code ) |
2589 { | 2719 { |
2590 return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); | 2720 return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); |
2591 } | 2721 } |
2592 | 2722 |
2593 | 2723 |
2594 FT_CALLBACK_DEF( FT_UInt32 ) | 2724 FT_CALLBACK_DEF( FT_UInt32 ) |
2595 tt_cmap13_char_next( TT_CMap cmap, | 2725 tt_cmap13_char_next( TT_CMap cmap, |
2596 FT_UInt32 *pchar_code ) | 2726 FT_UInt32 *pchar_code ) |
2597 { | 2727 { |
2598 TT_CMap13 cmap13 = (TT_CMap13)cmap; | 2728 TT_CMap13 cmap13 = (TT_CMap13)cmap; |
2599 FT_UInt gindex; | 2729 FT_UInt gindex; |
2600 | 2730 |
2601 | 2731 |
2602 if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) | |
2603 return 0; | |
2604 | |
2605 /* no need to search */ | 2732 /* no need to search */ |
2606 if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) | 2733 if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) |
2607 { | 2734 { |
2608 tt_cmap13_next( cmap13 ); | 2735 tt_cmap13_next( cmap13 ); |
2609 if ( cmap13->valid ) | 2736 if ( cmap13->valid ) |
2610 { | 2737 { |
2611 gindex = cmap13->cur_gindex; | 2738 gindex = cmap13->cur_gindex; |
2612 if ( gindex ) | 2739 *pchar_code = cmap13->cur_charcode; |
2613 *pchar_code = cmap13->cur_charcode; | |
2614 } | 2740 } |
2615 else | 2741 else |
2616 gindex = 0; | 2742 gindex = 0; |
2617 } | 2743 } |
2618 else | 2744 else |
2619 gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); | 2745 gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); |
2620 | 2746 |
2621 return gindex; | 2747 return gindex; |
2622 } | 2748 } |
2623 | 2749 |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 | 3615 |
3490 | 3616 |
3491 if ( !p || p + 4 > limit ) | 3617 if ( !p || p + 4 > limit ) |
3492 return FT_THROW( Invalid_Table ); | 3618 return FT_THROW( Invalid_Table ); |
3493 | 3619 |
3494 /* only recognize format 0 */ | 3620 /* only recognize format 0 */ |
3495 if ( TT_NEXT_USHORT( p ) != 0 ) | 3621 if ( TT_NEXT_USHORT( p ) != 0 ) |
3496 { | 3622 { |
3497 FT_ERROR(( "tt_face_build_cmaps:" | 3623 FT_ERROR(( "tt_face_build_cmaps:" |
3498 " unsupported `cmap' table format = %d\n", | 3624 " unsupported `cmap' table format = %d\n", |
3499 TT_PEEK_USHORT( p - 2) )); | 3625 TT_PEEK_USHORT( p - 2 ) )); |
3500 return FT_THROW( Invalid_Table ); | 3626 return FT_THROW( Invalid_Table ); |
3501 } | 3627 } |
3502 | 3628 |
3503 num_cmaps = TT_NEXT_USHORT( p ); | 3629 num_cmaps = TT_NEXT_USHORT( p ); |
3504 | 3630 |
3505 for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) | 3631 for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) |
3506 { | 3632 { |
3507 FT_CharMapRec charmap; | 3633 FT_CharMapRec charmap; |
3508 FT_UInt32 offset; | 3634 FT_UInt32 offset; |
3509 | 3635 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3586 { | 3712 { |
3587 FT_CMap cmap = (FT_CMap)charmap; | 3713 FT_CMap cmap = (FT_CMap)charmap; |
3588 TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; | 3714 TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; |
3589 | 3715 |
3590 | 3716 |
3591 return clazz->get_cmap_info( charmap, cmap_info ); | 3717 return clazz->get_cmap_info( charmap, cmap_info ); |
3592 } | 3718 } |
3593 | 3719 |
3594 | 3720 |
3595 /* END */ | 3721 /* END */ |
OLD | NEW |