| 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 |