Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: third_party/freetype/src/sfnt/ttcmap.c

Issue 1413673003: Update bundled freetype to 2.6.1 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: DEPS for corpus Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/freetype/src/sfnt/ttcmap.h ('k') | third_party/freetype/src/sfnt/ttcmapc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 */
OLDNEW
« no previous file with comments | « third_party/freetype/src/sfnt/ttcmap.h ('k') | third_party/freetype/src/sfnt/ttcmapc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698