38#define FT_COMPONENT ttcmap
41#define TT_PEEK_SHORT FT_PEEK_SHORT
42#define TT_PEEK_USHORT FT_PEEK_USHORT
43#define TT_PEEK_UINT24 FT_PEEK_UOFF3
44#define TT_PEEK_LONG FT_PEEK_LONG
45#define TT_PEEK_ULONG FT_PEEK_ULONG
47#define TT_NEXT_SHORT FT_NEXT_SHORT
48#define TT_NEXT_USHORT FT_NEXT_USHORT
49#define TT_NEXT_UINT24 FT_NEXT_UOFF3
50#define TT_NEXT_LONG FT_NEXT_LONG
51#define TT_NEXT_ULONG FT_NEXT_ULONG
61 FT_CALLBACK_DEF( FT_Error )
62 tt_cmap_init( FT_CMap cmap,
65 TT_CMap ttcmap = (TT_CMap)cmap;
66 FT_Byte* table = (FT_Byte*)table_;
96#ifdef TT_CONFIG_CMAP_FORMAT_0
98 FT_CALLBACK_DEF( FT_Error )
99 tt_cmap0_validate( FT_Byte* table,
106 if ( table + 2 + 2 > valid->limit )
107 FT_INVALID_TOO_SHORT;
110 length = TT_NEXT_USHORT( p );
112 if ( table + length > valid->limit || length < 262 )
113 FT_INVALID_TOO_SHORT;
116 if ( valid->level >= FT_VALIDATE_TIGHT )
122 for ( n = 0; n < 256; n++ )
125 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
134 FT_CALLBACK_DEF( FT_UInt )
135 tt_cmap0_char_index( FT_CMap cmap,
136 FT_UInt32 char_code )
138 TT_CMap ttcmap = (TT_CMap)cmap;
139 FT_Byte* table = ttcmap->data;
142 return char_code < 256 ? table[6 + char_code] : 0;
146 FT_CALLBACK_DEF( FT_UInt )
147 tt_cmap0_char_next( FT_CMap cmap,
148 FT_UInt32 *pchar_code )
150 TT_CMap ttcmap = (TT_CMap)cmap;
151 FT_Byte* table = ttcmap->data;
152 FT_UInt32 charcode = *pchar_code;
153 FT_UInt32 result = 0;
158 while ( ++charcode < 256 )
160 gindex = table[charcode];
168 *pchar_code = result;
173 FT_CALLBACK_DEF( FT_Error )
174 tt_cmap0_get_info( FT_CharMap cmap,
175 TT_CMapInfo *cmap_info )
177 TT_CMap ttcmap = (TT_CMap)cmap;
178 FT_Byte* p = ttcmap->data + 4;
181 cmap_info->format = 0;
182 cmap_info->language = TT_PEEK_USHORT( p );
191 sizeof ( TT_CMapRec ),
193 (FT_CMap_InitFunc) tt_cmap_init,
194 (FT_CMap_DoneFunc) NULL,
195 (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
196 (FT_CMap_CharNextFunc) tt_cmap0_char_next,
198 (FT_CMap_CharVarIndexFunc) NULL,
199 (FT_CMap_CharVarIsDefaultFunc)NULL,
200 (FT_CMap_VariantListFunc) NULL,
201 (FT_CMap_CharVariantListFunc) NULL,
202 (FT_CMap_VariantCharListFunc) NULL,
205 (TT_CMap_ValidateFunc)tt_cmap0_validate,
206 (TT_CMap_Info_GetFunc)tt_cmap0_get_info
298#ifdef TT_CONFIG_CMAP_FORMAT_2
300 FT_CALLBACK_DEF( FT_Error )
301 tt_cmap2_validate( FT_Byte* table,
313 if ( table + 2 + 2 > valid->limit )
314 FT_INVALID_TOO_SHORT;
317 length = TT_NEXT_USHORT( p );
319 if ( table + length > valid->limit || length < 6 + 512 )
320 FT_INVALID_TOO_SHORT;
327 for ( n = 0; n < 256; n++ )
329 FT_UInt idx = TT_NEXT_USHORT( p );
333 if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 )
338 if ( idx > max_subs )
342 FT_ASSERT( p == table + 518 );
345 glyph_ids = subs + ( max_subs + 1 ) * 8;
346 if ( glyph_ids > valid->limit )
347 FT_INVALID_TOO_SHORT;
350 for ( n = 0; n <= max_subs; n++ )
352 FT_UInt first_code, code_count, offset;
356 first_code = TT_NEXT_USHORT( p );
357 code_count = TT_NEXT_USHORT( p );
358 delta = TT_NEXT_SHORT( p );
359 offset = TT_NEXT_USHORT( p );
362 if ( code_count == 0 )
366 if ( valid->level >= FT_VALIDATE_PARANOID )
368 if ( first_code >= 256 || code_count > 256 - first_code )
378 ids = p - 2 + offset;
379 if ( ids < glyph_ids || ids + code_count * 2 > table + length )
383 if ( valid->level >= FT_VALIDATE_TIGHT )
385 FT_Byte* limit = p + code_count * 2;
391 idx = TT_NEXT_USHORT( p );
394 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
395 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
410 tt_cmap2_get_subheader( FT_Byte* table,
411 FT_UInt32 char_code )
413 FT_Byte* result = NULL;
416 if ( char_code < 0x10000UL )
418 FT_UInt char_lo = (FT_UInt)( char_code & 0xFF );
419 FT_UInt char_hi = (FT_UInt)( char_code >> 8 );
420 FT_Byte* p = table + 6;
421 FT_Byte* subs = table + 518;
437 if ( TT_PEEK_USHORT( p ) != 0 )
447 sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
462 FT_CALLBACK_DEF( FT_UInt )
463 tt_cmap2_char_index( FT_CMap cmap,
464 FT_UInt32 char_code )
466 TT_CMap ttcmap = (TT_CMap)cmap;
467 FT_Byte* table = ttcmap->data;
472 subheader = tt_cmap2_get_subheader( table, char_code );
475 FT_Byte* p = subheader;
476 FT_UInt idx = (FT_UInt)( char_code & 0xFF );
477 FT_UInt start, count;
482 start = TT_NEXT_USHORT( p );
483 count = TT_NEXT_USHORT( p );
484 delta = TT_NEXT_SHORT ( p );
485 offset = TT_PEEK_USHORT( p );
488 if ( idx < count && offset != 0 )
490 p += offset + 2 * idx;
491 idx = TT_PEEK_USHORT( p );
494 result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
502 FT_CALLBACK_DEF( FT_UInt )
503 tt_cmap2_char_next( FT_CMap cmap,
504 FT_UInt32 *pcharcode )
506 TT_CMap ttcmap = (TT_CMap)cmap;
507 FT_Byte* table = ttcmap->data;
509 FT_UInt32 result = 0;
510 FT_UInt32 charcode = *pcharcode + 1;
514 while ( charcode < 0x10000UL )
516 subheader = tt_cmap2_get_subheader( table, charcode );
519 FT_Byte* p = subheader;
520 FT_UInt start = TT_NEXT_USHORT( p );
521 FT_UInt count = TT_NEXT_USHORT( p );
522 FT_Int delta = TT_NEXT_SHORT ( p );
523 FT_UInt offset = TT_PEEK_USHORT( p );
524 FT_UInt char_lo = (FT_UInt)( charcode & 0xFF );
528 if ( char_lo >= start + count && charcode <= 0xFF )
537 if ( charcode == 0x100 )
542 if ( char_lo < start )
548 pos = (FT_UInt)( char_lo - start );
550 p += offset + pos * 2;
551 charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo;
553 for ( ; pos < count; pos++, charcode++ )
555 idx = TT_NEXT_USHORT( p );
559 gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
577 if ( charcode <= 0xFF )
580 charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100;
590 FT_CALLBACK_DEF( FT_Error )
591 tt_cmap2_get_info( FT_CharMap cmap,
592 TT_CMapInfo *cmap_info )
594 TT_CMap ttcmap = (TT_CMap)cmap;
595 FT_Byte* p = ttcmap->data + 4;
598 cmap_info->format = 2;
599 cmap_info->language = TT_PEEK_USHORT( p );
608 sizeof ( TT_CMapRec ),
610 (FT_CMap_InitFunc) tt_cmap_init,
611 (FT_CMap_DoneFunc) NULL,
612 (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
613 (FT_CMap_CharNextFunc) tt_cmap2_char_next,
615 (FT_CMap_CharVarIndexFunc) NULL,
616 (FT_CMap_CharVarIsDefaultFunc)NULL,
617 (FT_CMap_VariantListFunc) NULL,
618 (FT_CMap_CharVariantListFunc) NULL,
619 (FT_CMap_VariantCharListFunc) NULL,
622 (TT_CMap_ValidateFunc)tt_cmap2_validate,
623 (TT_CMap_Info_GetFunc)tt_cmap2_get_info
700#ifdef TT_CONFIG_CMAP_FORMAT_4
702 typedef struct TT_CMap4Rec_
705 FT_UInt32 cur_charcode;
715 } TT_CMap4Rec, *TT_CMap4;
718 FT_CALLBACK_DEF( FT_Error )
719 tt_cmap4_init( FT_CMap cmap,
722 TT_CMap4 ttcmap = (TT_CMap4)cmap;
723 FT_Byte* table = (FT_Byte*)table_;
727 ttcmap->cmap.data = table;
730 ttcmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
731 ttcmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
732 ttcmap->cur_gindex = 0;
739 tt_cmap4_set_range( TT_CMap4 cmap,
740 FT_UInt range_index )
742 FT_Byte* table = cmap->cmap.data;
744 FT_UInt num_ranges = cmap->num_ranges;
747 while ( range_index < num_ranges )
752 p = table + 14 + range_index * 2;
753 cmap->cur_end = FT_PEEK_USHORT( p );
755 p += 2 + num_ranges * 2;
756 cmap->cur_start = FT_PEEK_USHORT( p );
759 cmap->cur_delta = FT_PEEK_SHORT( p );
762 offset = FT_PEEK_USHORT( p );
766 if ( range_index >= num_ranges - 1 &&
767 cmap->cur_start == 0xFFFFU &&
768 cmap->cur_end == 0xFFFFU )
770 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
771 FT_Byte* limit = face->cmap_table + face->cmap_size;
774 if ( offset && p + offset + 2 > limit )
781 if ( offset != 0xFFFFU )
783 cmap->cur_values = offset ? p + offset : NULL;
784 cmap->cur_range = range_index;
801 tt_cmap4_next( TT_CMap4 cmap )
803 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
804 FT_Byte* limit = face->cmap_table + face->cmap_size;
809 charcode = (FT_UInt)cmap->cur_charcode + 1;
811 if ( charcode < cmap->cur_start )
812 charcode = cmap->cur_start;
816 FT_Byte* values = cmap->cur_values;
817 FT_UInt end = cmap->cur_end;
818 FT_Int delta = cmap->cur_delta;
821 if ( charcode <= end )
825 FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
834 FT_UInt gindex = FT_NEXT_USHORT( p );
839 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
842 cmap->cur_charcode = charcode;
843 cmap->cur_gindex = gindex;
847 }
while ( ++charcode <= end );
853 FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
856 if ( gindex >= (FT_UInt)face->root.num_glyphs )
863 if ( (FT_Int)charcode + delta < 0 &&
864 (FT_Int)end + delta >= 0 )
865 charcode = (FT_UInt)( -delta );
867 else if ( (FT_Int)charcode + delta < 0x10000L &&
868 (FT_Int)end + delta >= 0x10000L )
869 charcode = (FT_UInt)( 0x10000L - delta );
877 cmap->cur_charcode = charcode;
878 cmap->cur_gindex = gindex;
881 }
while ( ++charcode <= end );
887 if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
890 if ( charcode < cmap->cur_start )
891 charcode = cmap->cur_start;
894 cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
895 cmap->cur_gindex = 0;
899 FT_CALLBACK_DEF( FT_Error )
900 tt_cmap4_validate( FT_Byte* table,
906 FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
908 FT_Error error = FT_Err_Ok;
911 if ( table + 2 + 2 > valid->limit )
912 FT_INVALID_TOO_SHORT;
915 length = TT_NEXT_USHORT( p );
919 if ( table + length > valid->limit )
921 if ( valid->level >= FT_VALIDATE_TIGHT )
922 FT_INVALID_TOO_SHORT;
924 length = (FT_UInt)( valid->limit - table );
929 if ( length < (FT_UInt)( valid->limit - table ) )
931 if ( valid->level >= FT_VALIDATE_PARANOID )
934 length = (FT_UInt)( valid->limit - table );
938 FT_INVALID_TOO_SHORT;
941 num_segs = TT_NEXT_USHORT( p );
943 if ( valid->level >= FT_VALIDATE_PARANOID )
952 if ( length < 16 + num_segs * 2 * 4 )
953 FT_INVALID_TOO_SHORT;
957 if ( valid->level >= FT_VALIDATE_PARANOID )
960 FT_UInt search_range = TT_NEXT_USHORT( p );
961 FT_UInt entry_selector = TT_NEXT_USHORT( p );
962 FT_UInt range_shift = TT_NEXT_USHORT( p );
965 if ( ( search_range | range_shift ) & 1 )
973 if ( search_range > num_segs ||
974 search_range * 2 < num_segs ||
975 search_range + range_shift != num_segs ||
976 search_range != ( 1U << entry_selector ) )
981 starts = table + 16 + num_segs * 2;
982 deltas = starts + num_segs * 2;
983 offsets = deltas + num_segs * 2;
984 glyph_ids = offsets + num_segs * 2;
987 if ( valid->level >= FT_VALIDATE_PARANOID )
989 p = ends + ( num_segs - 1 ) * 2;
990 if ( TT_PEEK_USHORT( p ) != 0xFFFFU )
995 FT_UInt start, end, offset, n;
996 FT_UInt last_start = 0, last_end = 0;
998 FT_Byte* p_start = starts;
999 FT_Byte* p_end = ends;
1000 FT_Byte* p_delta = deltas;
1001 FT_Byte* p_offset = offsets;
1004 for ( n = 0; n < num_segs; n++ )
1007 start = TT_NEXT_USHORT( p_start );
1008 end = TT_NEXT_USHORT( p_end );
1009 delta = TT_NEXT_SHORT( p_delta );
1010 offset = TT_NEXT_USHORT( p_offset );
1019 if ( start <= last_end && n > 0 )
1021 if ( valid->level >= FT_VALIDATE_TIGHT )
1028 if ( last_start > start || last_end > end )
1029 error |= TT_CMAP_FLAG_UNSORTED;
1031 error |= TT_CMAP_FLAG_OVERLAPPING;
1035 if ( offset && offset != 0xFFFFU )
1040 if ( valid->level >= FT_VALIDATE_TIGHT )
1042 if ( p < glyph_ids ||
1043 p + ( end - start + 1 ) * 2 > table + length )
1056 else if ( n != num_segs - 1 ||
1057 !( start == 0xFFFFU && end == 0xFFFFU ) )
1059 if ( p < glyph_ids ||
1060 p + ( end - start + 1 ) * 2 > valid->limit )
1065 if ( valid->level >= FT_VALIDATE_TIGHT )
1070 for ( i = start; i < end; i++ )
1072 idx = FT_NEXT_USHORT( p );
1075 idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
1077 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
1078 FT_INVALID_GLYPH_ID;
1083 else if ( offset == 0xFFFFU )
1088 if ( valid->level >= FT_VALIDATE_PARANOID ||
1089 n != num_segs - 1 ||
1090 !( start == 0xFFFFU && end == 0xFFFFU ) )
1104 tt_cmap4_char_map_linear( TT_CMap cmap,
1105 FT_UInt32* pcharcode,
1108 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
1109 FT_Byte* limit = face->cmap_table + face->cmap_size;
1112 FT_UInt num_segs2, start, end, offset;
1114 FT_UInt i, num_segs;
1115 FT_UInt32 charcode = *pcharcode + next;
1122 num_segs = TT_PEEK_USHORT( p ) >> 1;
1127 num_segs2 = num_segs << 1;
1130 p = cmap->data + 14;
1131 q = cmap->data + 16 + num_segs2;
1133 for ( i = 0; i < num_segs; i++ )
1135 end = TT_NEXT_USHORT( p );
1136 start = TT_NEXT_USHORT( q );
1138 if ( charcode < start )
1147 if ( charcode <= end )
1152 r = q - 2 + num_segs2;
1153 delta = TT_PEEK_SHORT( r );
1155 offset = TT_PEEK_USHORT( r );
1159 if ( i >= num_segs - 1 &&
1160 start == 0xFFFFU && end == 0xFFFFU )
1162 if ( offset && r + offset + 2 > limit )
1169 if ( offset == 0xFFFFU )
1174 r += offset + ( charcode - start ) * 2;
1177 if ( next && r > limit )
1180 gindex = TT_PEEK_USHORT( r );
1183 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1184 if ( gindex >= (FT_UInt)face->root.num_glyphs )
1190 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1192 if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1199 if ( (FT_Int)charcode + delta < 0 &&
1200 (FT_Int)end + delta >= 0 )
1201 charcode = (FT_UInt)( -delta );
1203 else if ( (FT_Int)charcode + delta < 0x10000L &&
1204 (FT_Int)end + delta >= 0x10000L )
1205 charcode = (FT_UInt)( 0x10000L - delta );
1212 if ( next && !gindex )
1214 if ( charcode >= 0xFFFFU )
1226 *pcharcode = charcode;
1233 tt_cmap4_char_map_binary( TT_CMap cmap,
1234 FT_UInt32* pcharcode,
1237 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
1238 FT_Byte* limit = face->cmap_table + face->cmap_size;
1240 FT_UInt num_segs2, start, end, offset;
1242 FT_UInt max, min, mid, num_segs;
1243 FT_UInt charcode = (FT_UInt)*pcharcode + next;
1249 num_segs = TT_PEEK_USHORT( p ) >> 1;
1254 num_segs2 = num_segs << 1;
1262 mid = ( min + max ) >> 1;
1263 p = cmap->data + 14 + mid * 2;
1264 end = TT_PEEK_USHORT( p );
1266 start = TT_PEEK_USHORT( p );
1268 if ( charcode < start )
1270 else if ( charcode > end )
1275 delta = TT_PEEK_SHORT( p );
1277 offset = TT_PEEK_USHORT( p );
1281 if ( mid >= num_segs - 1 &&
1282 start == 0xFFFFU && end == 0xFFFFU )
1284 if ( offset && p + offset + 2 > limit )
1292 if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
1300 if ( offset == 0xFFFFU )
1304 for ( i = max; i > 0; i-- )
1311 p = cmap->data + 14 + ( i - 1 ) * 2;
1312 prev_end = TT_PEEK_USHORT( p );
1314 if ( charcode > prev_end )
1322 start = TT_PEEK_USHORT( p );
1324 delta = TT_PEEK_SHORT( p );
1326 offset = TT_PEEK_USHORT( p );
1328 if ( offset != 0xFFFFU )
1333 if ( mid == max + 1 )
1337 p = cmap->data + 14 + max * 2;
1338 end = TT_PEEK_USHORT( p );
1340 start = TT_PEEK_USHORT( p );
1342 delta = TT_PEEK_SHORT( p );
1344 offset = TT_PEEK_USHORT( p );
1350 for ( i = max + 1; i < num_segs; i++ )
1352 FT_UInt next_end, next_start;
1355 p = cmap->data + 14 + i * 2;
1356 next_end = TT_PEEK_USHORT( p );
1358 next_start = TT_PEEK_USHORT( p );
1360 if ( charcode < next_start )
1366 delta = TT_PEEK_SHORT( p );
1368 offset = TT_PEEK_USHORT( p );
1370 if ( offset != 0xFFFFU )
1387 p = cmap->data + 14 + mid * 2;
1388 end = TT_PEEK_USHORT( p );
1390 start = TT_PEEK_USHORT( p );
1392 delta = TT_PEEK_SHORT( p );
1394 offset = TT_PEEK_USHORT( p );
1399 if ( offset == 0xFFFFU )
1405 p += offset + ( charcode - start ) * 2;
1408 if ( next && p > limit )
1411 gindex = TT_PEEK_USHORT( p );
1414 gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
1415 if ( gindex >= (FT_UInt)face->root.num_glyphs )
1421 gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
1423 if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
1430 if ( (FT_Int)charcode + delta < 0 &&
1431 (FT_Int)end + delta >= 0 )
1432 charcode = (FT_UInt)( -delta );
1434 else if ( (FT_Int)charcode + delta < 0x10000L &&
1435 (FT_Int)end + delta >= 0x10000L )
1436 charcode = (FT_UInt)( 0x10000L - delta );
1443 while ( min < max );
1447 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1453 if ( charcode > end && ++mid == num_segs )
1456 if ( tt_cmap4_set_range( cmap4, mid ) )
1459 *pcharcode = charcode;
1463 cmap4->cur_charcode = charcode;
1466 cmap4->cur_gindex = gindex;
1469 tt_cmap4_next( cmap4 );
1470 gindex = cmap4->cur_gindex;
1474 *pcharcode = cmap4->cur_charcode;
1482 FT_CALLBACK_DEF( FT_UInt )
1483 tt_cmap4_char_index( FT_CMap cmap,
1484 FT_UInt32 char_code )
1486 TT_CMap ttcmap = (TT_CMap)cmap;
1489 if ( char_code >= 0x10000UL )
1492 if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
1493 return tt_cmap4_char_map_linear( ttcmap, &char_code, 0 );
1495 return tt_cmap4_char_map_binary( ttcmap, &char_code, 0 );
1499 FT_CALLBACK_DEF( FT_UInt )
1500 tt_cmap4_char_next( FT_CMap cmap,
1501 FT_UInt32 *pchar_code )
1503 TT_CMap ttcmap = (TT_CMap)cmap;
1507 if ( *pchar_code >= 0xFFFFU )
1510 if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
1511 gindex = tt_cmap4_char_map_linear( ttcmap, pchar_code, 1 );
1514 TT_CMap4 cmap4 = (TT_CMap4)cmap;
1518 if ( *pchar_code == cmap4->cur_charcode )
1520 tt_cmap4_next( cmap4 );
1521 gindex = cmap4->cur_gindex;
1523 *pchar_code = cmap4->cur_charcode;
1526 gindex = tt_cmap4_char_map_binary( ttcmap, pchar_code, 1 );
1533 FT_CALLBACK_DEF( FT_Error )
1534 tt_cmap4_get_info( FT_CharMap cmap,
1535 TT_CMapInfo *cmap_info )
1537 TT_CMap ttcmap = (TT_CMap)cmap;
1538 FT_Byte* p = ttcmap->data + 4;
1541 cmap_info->format = 4;
1542 cmap_info->language = TT_PEEK_USHORT( p );
1551 sizeof ( TT_CMap4Rec ),
1553 (FT_CMap_InitFunc) tt_cmap4_init,
1554 (FT_CMap_DoneFunc) NULL,
1555 (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
1556 (FT_CMap_CharNextFunc) tt_cmap4_char_next,
1558 (FT_CMap_CharVarIndexFunc) NULL,
1559 (FT_CMap_CharVarIsDefaultFunc)NULL,
1560 (FT_CMap_VariantListFunc) NULL,
1561 (FT_CMap_CharVariantListFunc) NULL,
1562 (FT_CMap_VariantCharListFunc) NULL,
1565 (TT_CMap_ValidateFunc)tt_cmap4_validate,
1566 (TT_CMap_Info_GetFunc)tt_cmap4_get_info
1598#ifdef TT_CONFIG_CMAP_FORMAT_6
1600 FT_CALLBACK_DEF( FT_Error )
1601 tt_cmap6_validate( FT_Byte* table,
1602 FT_Validator valid )
1605 FT_UInt length, count;
1608 if ( table + 10 > valid->limit )
1609 FT_INVALID_TOO_SHORT;
1612 length = TT_NEXT_USHORT( p );
1615 count = TT_NEXT_USHORT( p );
1617 if ( table + length > valid->limit || length < 10 + count * 2 )
1618 FT_INVALID_TOO_SHORT;
1621 if ( valid->level >= FT_VALIDATE_TIGHT )
1626 for ( ; count > 0; count-- )
1628 gindex = TT_NEXT_USHORT( p );
1629 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
1630 FT_INVALID_GLYPH_ID;
1638 FT_CALLBACK_DEF( FT_UInt )
1639 tt_cmap6_char_index( FT_CMap cmap,
1640 FT_UInt32 char_code )
1642 TT_CMap ttcmap = (TT_CMap)cmap;
1643 FT_Byte* table = ttcmap->data;
1645 FT_Byte* p = table + 6;
1646 FT_UInt start = TT_NEXT_USHORT( p );
1647 FT_UInt count = TT_NEXT_USHORT( p );
1648 FT_UInt idx = (FT_UInt)( char_code - start );
1654 result = TT_PEEK_USHORT( p );
1661 FT_CALLBACK_DEF( FT_UInt )
1662 tt_cmap6_char_next( FT_CMap cmap,
1663 FT_UInt32 *pchar_code )
1665 TT_CMap ttcmap = (TT_CMap)cmap;
1666 FT_Byte* table = ttcmap->data;
1667 FT_UInt32 result = 0;
1668 FT_UInt32 char_code = *pchar_code + 1;
1671 FT_Byte* p = table + 6;
1672 FT_UInt start = TT_NEXT_USHORT( p );
1673 FT_UInt count = TT_NEXT_USHORT( p );
1677 if ( char_code >= 0x10000UL )
1680 if ( char_code < start )
1683 idx = (FT_UInt)( char_code - start );
1686 for ( ; idx < count; idx++ )
1688 gindex = TT_NEXT_USHORT( p );
1695 if ( char_code >= 0xFFFFU )
1701 *pchar_code = result;
1706 FT_CALLBACK_DEF( FT_Error )
1707 tt_cmap6_get_info( FT_CharMap cmap,
1708 TT_CMapInfo *cmap_info )
1710 TT_CMap ttcmap = (TT_CMap)cmap;
1711 FT_Byte* p = ttcmap->data + 4;
1714 cmap_info->format = 6;
1715 cmap_info->language = TT_PEEK_USHORT( p );
1724 sizeof ( TT_CMapRec ),
1726 (FT_CMap_InitFunc) tt_cmap_init,
1727 (FT_CMap_DoneFunc) NULL,
1728 (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
1729 (FT_CMap_CharNextFunc) tt_cmap6_char_next,
1731 (FT_CMap_CharVarIndexFunc) NULL,
1732 (FT_CMap_CharVarIsDefaultFunc)NULL,
1733 (FT_CMap_VariantListFunc) NULL,
1734 (FT_CMap_CharVariantListFunc) NULL,
1735 (FT_CMap_VariantCharListFunc) NULL,
1738 (TT_CMap_ValidateFunc)tt_cmap6_validate,
1739 (TT_CMap_Info_GetFunc)tt_cmap6_get_info
1799#ifdef TT_CONFIG_CMAP_FORMAT_8
1801 FT_CALLBACK_DEF( FT_Error )
1802 tt_cmap8_validate( FT_Byte* table,
1803 FT_Validator valid )
1805 FT_Byte* p = table + 4;
1808 FT_UInt32 num_groups;
1811 if ( table + 16 + 8192 > valid->limit )
1812 FT_INVALID_TOO_SHORT;
1814 length = TT_NEXT_ULONG( p );
1815 if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
1816 FT_INVALID_TOO_SHORT;
1820 num_groups = TT_NEXT_ULONG( p );
1823 if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
1824 FT_INVALID_TOO_SHORT;
1828 FT_UInt32 n, start, end, start_id, count, last = 0;
1831 for ( n = 0; n < num_groups; n++ )
1836 start = TT_NEXT_ULONG( p );
1837 end = TT_NEXT_ULONG( p );
1838 start_id = TT_NEXT_ULONG( p );
1843 if ( n > 0 && start <= last )
1846 if ( valid->level >= FT_VALIDATE_TIGHT )
1848 FT_UInt32 d = end - start;
1852 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
1853 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
1854 FT_INVALID_GLYPH_ID;
1856 count = (FT_UInt32)( end - start + 1 );
1858 if ( start & ~0xFFFFU )
1862 for ( ; count > 0; count--, start++ )
1864 hi = (FT_UInt)( start >> 16 );
1865 lo = (FT_UInt)( start & 0xFFFFU );
1867 if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
1870 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
1880 if ( end & ~0xFFFFU )
1883 for ( ; count > 0; count--, start++ )
1885 lo = (FT_UInt)( start & 0xFFFFU );
1887 if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
1901 FT_CALLBACK_DEF( FT_UInt )
1902 tt_cmap8_char_index( FT_CMap cmap,
1903 FT_UInt32 char_code )
1905 TT_CMap ttcmap = (TT_CMap)cmap;
1906 FT_Byte* table = ttcmap->data;
1908 FT_Byte* p = table + 8204;
1909 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1910 FT_UInt32 start, end, start_id;
1913 for ( ; num_groups > 0; num_groups-- )
1915 start = TT_NEXT_ULONG( p );
1916 end = TT_NEXT_ULONG( p );
1917 start_id = TT_NEXT_ULONG( p );
1919 if ( char_code < start )
1922 if ( char_code <= end )
1924 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1927 result = (FT_UInt)( start_id + ( char_code - start ) );
1935 FT_CALLBACK_DEF( FT_UInt )
1936 tt_cmap8_char_next( FT_CMap cmap,
1937 FT_UInt32 *pchar_code )
1939 TT_CMap ttcmap = (TT_CMap)cmap;
1940 FT_Face face = FT_CMAP_FACE( cmap );
1941 FT_UInt32 result = 0;
1942 FT_UInt32 char_code;
1944 FT_Byte* table = ttcmap->data;
1945 FT_Byte* p = table + 8204;
1946 FT_UInt32 num_groups = TT_NEXT_ULONG( p );
1947 FT_UInt32 start, end, start_id;
1950 if ( *pchar_code >= 0xFFFFFFFFUL )
1953 char_code = *pchar_code + 1;
1957 for ( ; num_groups > 0; num_groups-- )
1959 start = TT_NEXT_ULONG( p );
1960 end = TT_NEXT_ULONG( p );
1961 start_id = TT_NEXT_ULONG( p );
1963 if ( char_code < start )
1967 if ( char_code <= end )
1970 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
1973 gindex = (FT_UInt)( start_id + ( char_code - start ) );
1978 if ( char_code >= 0xFFFFFFFFUL )
1987 if ( gindex >= (FT_UInt)face->num_glyphs )
1998 *pchar_code = result;
2003 FT_CALLBACK_DEF( FT_Error )
2004 tt_cmap8_get_info( FT_CharMap cmap,
2005 TT_CMapInfo *cmap_info )
2007 TT_CMap ttcmap = (TT_CMap)cmap;
2008 FT_Byte* p = ttcmap->data + 8;
2011 cmap_info->format = 8;
2012 cmap_info->language = TT_PEEK_ULONG( p );
2021 sizeof ( TT_CMapRec ),
2023 (FT_CMap_InitFunc) tt_cmap_init,
2024 (FT_CMap_DoneFunc) NULL,
2025 (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
2026 (FT_CMap_CharNextFunc) tt_cmap8_char_next,
2028 (FT_CMap_CharVarIndexFunc) NULL,
2029 (FT_CMap_CharVarIsDefaultFunc)NULL,
2030 (FT_CMap_VariantListFunc) NULL,
2031 (FT_CMap_CharVariantListFunc) NULL,
2032 (FT_CMap_VariantCharListFunc) NULL,
2035 (TT_CMap_ValidateFunc)tt_cmap8_validate,
2036 (TT_CMap_Info_GetFunc)tt_cmap8_get_info
2067#ifdef TT_CONFIG_CMAP_FORMAT_10
2069 FT_CALLBACK_DEF( FT_Error )
2070 tt_cmap10_validate( FT_Byte* table,
2071 FT_Validator valid )
2073 FT_Byte* p = table + 4;
2074 FT_ULong length, count;
2077 if ( table + 20 > valid->limit )
2078 FT_INVALID_TOO_SHORT;
2080 length = TT_NEXT_ULONG( p );
2082 count = TT_NEXT_ULONG( p );
2084 if ( length > (FT_ULong)( valid->limit - table ) ||
2087 ( length - 20 ) / 2 < count )
2088 FT_INVALID_TOO_SHORT;
2091 if ( valid->level >= FT_VALIDATE_TIGHT )
2096 for ( ; count > 0; count-- )
2098 gindex = TT_NEXT_USHORT( p );
2099 if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
2100 FT_INVALID_GLYPH_ID;
2108 FT_CALLBACK_DEF( FT_UInt )
2109 tt_cmap10_char_index( FT_CMap cmap,
2110 FT_UInt32 char_code )
2112 TT_CMap ttcmap = (TT_CMap)cmap;
2113 FT_Byte* table = ttcmap->data;
2115 FT_Byte* p = table + 12;
2116 FT_UInt32 start = TT_NEXT_ULONG( p );
2117 FT_UInt32 count = TT_NEXT_ULONG( p );
2121 if ( char_code < start )
2124 idx = char_code - start;
2129 result = TT_PEEK_USHORT( p );
2136 FT_CALLBACK_DEF( FT_UInt )
2137 tt_cmap10_char_next( FT_CMap cmap,
2138 FT_UInt32 *pchar_code )
2140 TT_CMap ttcmap = (TT_CMap)cmap;
2141 FT_Byte* table = ttcmap->data;
2142 FT_UInt32 char_code;
2144 FT_Byte* p = table + 12;
2145 FT_UInt32 start = TT_NEXT_ULONG( p );
2146 FT_UInt32 count = TT_NEXT_ULONG( p );
2150 if ( *pchar_code >= 0xFFFFFFFFUL )
2153 char_code = *pchar_code + 1;
2155 if ( char_code < start )
2158 idx = char_code - start;
2161 for ( ; idx < count; idx++ )
2163 gindex = TT_NEXT_USHORT( p );
2167 if ( char_code >= 0xFFFFFFFFUL )
2173 *pchar_code = char_code;
2178 FT_CALLBACK_DEF( FT_Error )
2179 tt_cmap10_get_info( FT_CharMap cmap,
2180 TT_CMapInfo *cmap_info )
2182 TT_CMap ttcmap = (TT_CMap)cmap;
2183 FT_Byte* p = ttcmap->data + 8;
2186 cmap_info->format = 10;
2187 cmap_info->language = TT_PEEK_ULONG( p );
2194 tt_cmap10_class_rec,
2196 sizeof ( TT_CMapRec ),
2198 (FT_CMap_InitFunc) tt_cmap_init,
2199 (FT_CMap_DoneFunc) NULL,
2200 (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
2201 (FT_CMap_CharNextFunc) tt_cmap10_char_next,
2203 (FT_CMap_CharVarIndexFunc) NULL,
2204 (FT_CMap_CharVarIsDefaultFunc)NULL,
2205 (FT_CMap_VariantListFunc) NULL,
2206 (FT_CMap_CharVariantListFunc) NULL,
2207 (FT_CMap_VariantCharListFunc) NULL,
2210 (TT_CMap_ValidateFunc)tt_cmap10_validate,
2211 (TT_CMap_Info_GetFunc)tt_cmap10_get_info
2246#ifdef TT_CONFIG_CMAP_FORMAT_12
2248 typedef struct TT_CMap12Rec_
2252 FT_ULong cur_charcode;
2255 FT_ULong num_groups;
2257 } TT_CMap12Rec, *TT_CMap12;
2260 FT_CALLBACK_DEF( FT_Error )
2261 tt_cmap12_init( FT_CMap cmap,
2264 TT_CMap12 ttcmap = (TT_CMap12)cmap;
2265 FT_Byte* table = (FT_Byte*)table_;
2268 ttcmap->cmap.data = table;
2271 ttcmap->num_groups = FT_PEEK_ULONG( table );
2279 FT_CALLBACK_DEF( FT_Error )
2280 tt_cmap12_validate( FT_Byte* table,
2281 FT_Validator valid )
2285 FT_ULong num_groups;
2288 if ( table + 16 > valid->limit )
2289 FT_INVALID_TOO_SHORT;
2292 length = TT_NEXT_ULONG( p );
2295 num_groups = TT_NEXT_ULONG( p );
2297 if ( length > (FT_ULong)( valid->limit - table ) ||
2300 ( length - 16 ) / 12 < num_groups )
2301 FT_INVALID_TOO_SHORT;
2305 FT_ULong n, start, end, start_id, last = 0;
2308 for ( n = 0; n < num_groups; n++ )
2310 start = TT_NEXT_ULONG( p );
2311 end = TT_NEXT_ULONG( p );
2312 start_id = TT_NEXT_ULONG( p );
2317 if ( n > 0 && start <= last )
2320 if ( valid->level >= FT_VALIDATE_TIGHT )
2322 FT_UInt32 d = end - start;
2326 if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
2327 start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
2328 FT_INVALID_GLYPH_ID;
2343 tt_cmap12_next( FT_CMap cmap )
2345 TT_CMap12 ttcmap = (TT_CMap12)cmap;
2346 FT_Face face = FT_CMAP_FACE( cmap );
2348 FT_ULong start, end, start_id, char_code;
2353 char_code = ttcmap->cur_charcode + 1;
2355 for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
2357 p = ttcmap->cmap.data + 16 + 12 * n;
2358 start = TT_NEXT_ULONG( p );
2359 end = TT_NEXT_ULONG( p );
2360 start_id = TT_PEEK_ULONG( p );
2362 if ( char_code < start )
2366 if ( char_code <= end )
2369 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2372 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2377 if ( char_code >= 0xFFFFFFFFUL )
2386 if ( gindex >= (FT_UInt)face->num_glyphs )
2389 ttcmap->cur_charcode = char_code;
2390 ttcmap->cur_gindex = gindex;
2391 ttcmap->cur_group = n;
2403 tt_cmap12_char_map_binary( TT_CMap cmap,
2404 FT_UInt32* pchar_code,
2408 FT_Byte* p = cmap->data + 12;
2409 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2410 FT_UInt32 char_code = *pchar_code + next;
2411 FT_UInt32 start, end, start_id;
2412 FT_UInt32 max, min, mid;
2424 mid = ( min + max ) >> 1;
2425 p = cmap->data + 16 + 12 * mid;
2427 start = TT_NEXT_ULONG( p );
2428 end = TT_NEXT_ULONG( p );
2430 if ( char_code < start )
2432 else if ( char_code > end )
2436 start_id = TT_PEEK_ULONG( p );
2439 if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) )
2442 gindex = (FT_UInt)( start_id + ( char_code - start ) );
2446 while ( min < max );
2450 FT_Face face = FT_CMAP_FACE( cmap );
2451 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2457 if ( char_code > end && ++mid == num_groups )
2461 cmap12->cur_charcode = char_code;
2462 cmap12->cur_group = mid;
2464 if ( gindex >= (FT_UInt)face->num_glyphs )
2469 tt_cmap12_next( FT_CMAP( cmap12 ) );
2471 if ( cmap12->valid )
2472 gindex = cmap12->cur_gindex;
2475 cmap12->cur_gindex = gindex;
2477 *pchar_code = cmap12->cur_charcode;
2484 FT_CALLBACK_DEF( FT_UInt )
2485 tt_cmap12_char_index( FT_CMap cmap,
2486 FT_UInt32 char_code )
2488 return tt_cmap12_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
2492 FT_CALLBACK_DEF( FT_UInt )
2493 tt_cmap12_char_next( FT_CMap cmap,
2494 FT_UInt32 *pchar_code )
2496 TT_CMap12 cmap12 = (TT_CMap12)cmap;
2500 if ( *pchar_code >= 0xFFFFFFFFUL )
2504 if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
2506 tt_cmap12_next( FT_CMAP( cmap12 ) );
2507 if ( cmap12->valid )
2509 gindex = cmap12->cur_gindex;
2510 *pchar_code = (FT_UInt32)cmap12->cur_charcode;
2516 gindex = tt_cmap12_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
2522 FT_CALLBACK_DEF( FT_Error )
2523 tt_cmap12_get_info( FT_CharMap cmap,
2524 TT_CMapInfo *cmap_info )
2526 TT_CMap ttcmap = (TT_CMap)cmap;
2527 FT_Byte* p = ttcmap->data + 8;
2530 cmap_info->format = 12;
2531 cmap_info->language = TT_PEEK_ULONG( p );
2538 tt_cmap12_class_rec,
2540 sizeof ( TT_CMap12Rec ),
2542 (FT_CMap_InitFunc) tt_cmap12_init,
2543 (FT_CMap_DoneFunc) NULL,
2544 (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
2545 (FT_CMap_CharNextFunc) tt_cmap12_char_next,
2547 (FT_CMap_CharVarIndexFunc) NULL,
2548 (FT_CMap_CharVarIsDefaultFunc)NULL,
2549 (FT_CMap_VariantListFunc) NULL,
2550 (FT_CMap_CharVariantListFunc) NULL,
2551 (FT_CMap_VariantCharListFunc) NULL,
2554 (TT_CMap_ValidateFunc)tt_cmap12_validate,
2555 (TT_CMap_Info_GetFunc)tt_cmap12_get_info
2590#ifdef TT_CONFIG_CMAP_FORMAT_13
2592 typedef struct TT_CMap13Rec_
2596 FT_ULong cur_charcode;
2599 FT_ULong num_groups;
2601 } TT_CMap13Rec, *TT_CMap13;
2604 FT_CALLBACK_DEF( FT_Error )
2605 tt_cmap13_init( FT_CMap cmap,
2608 TT_CMap13 ttcmap = (TT_CMap13)cmap;
2609 FT_Byte* table = (FT_Byte*)table_;
2612 ttcmap->cmap.data = table;
2615 ttcmap->num_groups = FT_PEEK_ULONG( table );
2623 FT_CALLBACK_DEF( FT_Error )
2624 tt_cmap13_validate( FT_Byte* table,
2625 FT_Validator valid )
2629 FT_ULong num_groups;
2632 if ( table + 16 > valid->limit )
2633 FT_INVALID_TOO_SHORT;
2636 length = TT_NEXT_ULONG( p );
2639 num_groups = TT_NEXT_ULONG( p );
2641 if ( length > (FT_ULong)( valid->limit - table ) ||
2644 ( length - 16 ) / 12 < num_groups )
2645 FT_INVALID_TOO_SHORT;
2649 FT_ULong n, start, end, glyph_id, last = 0;
2652 for ( n = 0; n < num_groups; n++ )
2654 start = TT_NEXT_ULONG( p );
2655 end = TT_NEXT_ULONG( p );
2656 glyph_id = TT_NEXT_ULONG( p );
2661 if ( n > 0 && start <= last )
2664 if ( valid->level >= FT_VALIDATE_TIGHT )
2666 if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
2667 FT_INVALID_GLYPH_ID;
2682 tt_cmap13_next( FT_CMap cmap )
2684 TT_CMap13 ttcmap = (TT_CMap13)cmap;
2685 FT_Face face = FT_CMAP_FACE( cmap );
2687 FT_ULong start, end, glyph_id, char_code;
2692 char_code = ttcmap->cur_charcode + 1;
2694 for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
2696 p = ttcmap->cmap.data + 16 + 12 * n;
2697 start = TT_NEXT_ULONG( p );
2698 end = TT_NEXT_ULONG( p );
2699 glyph_id = TT_PEEK_ULONG( p );
2701 if ( char_code < start )
2704 if ( char_code <= end )
2706 gindex = (FT_UInt)glyph_id;
2708 if ( gindex && gindex < (FT_UInt)face->num_glyphs )
2710 ttcmap->cur_charcode = char_code;
2711 ttcmap->cur_gindex = gindex;
2712 ttcmap->cur_group = n;
2724 tt_cmap13_char_map_binary( TT_CMap cmap,
2725 FT_UInt32* pchar_code,
2729 FT_Byte* p = cmap->data + 12;
2730 FT_UInt32 num_groups = TT_PEEK_ULONG( p );
2731 FT_UInt32 char_code = *pchar_code + next;
2732 FT_UInt32 start, end;
2733 FT_UInt32 max, min, mid;
2745 mid = ( min + max ) >> 1;
2746 p = cmap->data + 16 + 12 * mid;
2748 start = TT_NEXT_ULONG( p );
2749 end = TT_NEXT_ULONG( p );
2751 if ( char_code < start )
2753 else if ( char_code > end )
2757 gindex = (FT_UInt)TT_PEEK_ULONG( p );
2762 while ( min < max );
2766 FT_Face face = cmap->cmap.charmap.face;
2767 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2773 if ( char_code > end && ++mid == num_groups )
2777 cmap13->cur_charcode = char_code;
2778 cmap13->cur_group = mid;
2780 if ( gindex >= (FT_UInt)face->num_glyphs )
2785 tt_cmap13_next( FT_CMAP( cmap13 ) );
2787 if ( cmap13->valid )
2788 gindex = cmap13->cur_gindex;
2791 cmap13->cur_gindex = gindex;
2793 *pchar_code = cmap13->cur_charcode;
2800 FT_CALLBACK_DEF( FT_UInt )
2801 tt_cmap13_char_index( FT_CMap cmap,
2802 FT_UInt32 char_code )
2804 return tt_cmap13_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
2808 FT_CALLBACK_DEF( FT_UInt )
2809 tt_cmap13_char_next( FT_CMap cmap,
2810 FT_UInt32 *pchar_code )
2812 TT_CMap13 cmap13 = (TT_CMap13)cmap;
2816 if ( *pchar_code >= 0xFFFFFFFFUL )
2820 if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
2822 tt_cmap13_next( FT_CMAP( cmap13 ) );
2823 if ( cmap13->valid )
2825 gindex = cmap13->cur_gindex;
2826 *pchar_code = cmap13->cur_charcode;
2832 gindex = tt_cmap13_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
2838 FT_CALLBACK_DEF( FT_Error )
2839 tt_cmap13_get_info( FT_CharMap cmap,
2840 TT_CMapInfo *cmap_info )
2842 TT_CMap ttcmap = (TT_CMap)cmap;
2843 FT_Byte* p = ttcmap->data + 8;
2846 cmap_info->format = 13;
2847 cmap_info->language = TT_PEEK_ULONG( p );
2854 tt_cmap13_class_rec,
2856 sizeof ( TT_CMap13Rec ),
2858 (FT_CMap_InitFunc) tt_cmap13_init,
2859 (FT_CMap_DoneFunc) NULL,
2860 (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
2861 (FT_CMap_CharNextFunc) tt_cmap13_char_next,
2863 (FT_CMap_CharVarIndexFunc) NULL,
2864 (FT_CMap_CharVarIsDefaultFunc)NULL,
2865 (FT_CMap_VariantListFunc) NULL,
2866 (FT_CMap_CharVariantListFunc) NULL,
2867 (FT_CMap_VariantCharListFunc) NULL,
2870 (TT_CMap_ValidateFunc)tt_cmap13_validate,
2871 (TT_CMap_Info_GetFunc)tt_cmap13_get_info
2939#ifdef TT_CONFIG_CMAP_FORMAT_14
2941 typedef struct TT_CMap14Rec_
2944 FT_ULong num_selectors;
2950 FT_UInt32 max_results;
2954 } TT_CMap14Rec, *TT_CMap14;
2957 FT_CALLBACK_DEF(
void )
2958 tt_cmap14_done( FT_CMap cmap )
2960 TT_CMap14 ttcmap = (TT_CMap14)cmap;
2961 FT_Memory memory = ttcmap->memory;
2964 ttcmap->max_results = 0;
2965 if ( memory && ttcmap->results )
2966 FT_FREE( ttcmap->results );
2971 tt_cmap14_ensure( TT_CMap14 cmap,
2972 FT_UInt32 num_results,
2975 FT_UInt32 old_max = cmap->max_results;
2976 FT_Error error = FT_Err_Ok;
2979 if ( num_results > cmap->max_results )
2981 cmap->memory = memory;
2983 if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
2986 cmap->max_results = num_results;
2993 FT_CALLBACK_DEF( FT_Error )
2994 tt_cmap14_init( FT_CMap cmap,
2997 TT_CMap14 ttcmap = (TT_CMap14)cmap;
2998 FT_Byte* table = (FT_Byte*)table_;
3001 ttcmap->cmap.data = table;
3004 ttcmap->num_selectors = FT_PEEK_ULONG( table );
3005 ttcmap->max_results = 0;
3006 ttcmap->results = NULL;
3012 FT_CALLBACK_DEF( FT_Error )
3013 tt_cmap14_validate( FT_Byte* table,
3014 FT_Validator valid )
3018 FT_ULong num_selectors;
3021 if ( table + 2 + 4 + 4 > valid->limit )
3022 FT_INVALID_TOO_SHORT;
3025 length = TT_NEXT_ULONG( p );
3026 num_selectors = TT_NEXT_ULONG( p );
3028 if ( length > (FT_ULong)( valid->limit - table ) ||
3031 ( length - 10 ) / 11 < num_selectors )
3032 FT_INVALID_TOO_SHORT;
3039 FT_ULong n, lastVarSel = 1;
3042 for ( n = 0; n < num_selectors; n++ )
3044 FT_ULong varSel = TT_NEXT_UINT24( p );
3045 FT_ULong defOff = TT_NEXT_ULONG( p );
3046 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3049 if ( defOff >= length || nondefOff >= length )
3050 FT_INVALID_TOO_SHORT;
3052 if ( varSel < lastVarSel )
3055 lastVarSel = varSel + 1;
3061 FT_Byte* defp = table + defOff;
3064 FT_ULong lastBase = 0;
3067 if ( defp + 4 > valid->limit )
3068 FT_INVALID_TOO_SHORT;
3070 numRanges = TT_NEXT_ULONG( defp );
3073 if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
3074 FT_INVALID_TOO_SHORT;
3076 for ( i = 0; i < numRanges; i++ )
3078 FT_ULong base = TT_NEXT_UINT24( defp );
3079 FT_ULong cnt = FT_NEXT_BYTE( defp );
3082 if ( base + cnt >= 0x110000UL )
3085 if ( base < lastBase )
3088 lastBase = base + cnt + 1U;
3093 if ( nondefOff != 0 )
3095 FT_Byte* ndp = table + nondefOff;
3096 FT_ULong numMappings;
3097 FT_ULong i, lastUni = 0;
3100 if ( ndp + 4 > valid->limit )
3101 FT_INVALID_TOO_SHORT;
3103 numMappings = TT_NEXT_ULONG( ndp );
3106 if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
3107 FT_INVALID_TOO_SHORT;
3109 for ( i = 0; i < numMappings; i++ )
3111 FT_ULong uni = TT_NEXT_UINT24( ndp );
3112 FT_ULong gid = TT_NEXT_USHORT( ndp );
3115 if ( uni >= 0x110000UL )
3118 if ( uni < lastUni )
3123 if ( valid->level >= FT_VALIDATE_TIGHT &&
3124 gid >= TT_VALID_GLYPH_COUNT( valid ) )
3125 FT_INVALID_GLYPH_ID;
3135 FT_CALLBACK_DEF( FT_UInt )
3136 tt_cmap14_char_index( FT_CMap cmap,
3137 FT_UInt32 char_code )
3140 FT_UNUSED( char_code );
3147 FT_CALLBACK_DEF( FT_UInt )
3148 tt_cmap14_char_next( FT_CMap cmap,
3149 FT_UInt32 *pchar_code )
3159 FT_CALLBACK_DEF( FT_Error )
3160 tt_cmap14_get_info( FT_CharMap cmap,
3161 TT_CMapInfo *cmap_info )
3165 cmap_info->format = 14;
3167 cmap_info->language = 0xFFFFFFFFUL;
3174 tt_cmap14_char_map_def_binary( FT_Byte *base,
3175 FT_UInt32 char_code )
3177 FT_UInt32 numRanges = TT_PEEK_ULONG( base );
3189 FT_UInt32 mid = ( min + max ) >> 1;
3190 FT_Byte* p = base + 4 * mid;
3191 FT_ULong start = TT_NEXT_UINT24( p );
3192 FT_UInt cnt = FT_NEXT_BYTE( p );
3195 if ( char_code < start )
3197 else if ( char_code > start + cnt )
3208 tt_cmap14_char_map_nondef_binary( FT_Byte *base,
3209 FT_UInt32 char_code )
3211 FT_UInt32 numMappings = TT_PEEK_ULONG( base );
3223 FT_UInt32 mid = ( min + max ) >> 1;
3224 FT_Byte* p = base + 5 * mid;
3225 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3228 if ( char_code < uni )
3230 else if ( char_code > uni )
3233 return TT_PEEK_USHORT( p );
3241 tt_cmap14_find_variant( FT_Byte *base,
3242 FT_UInt32 variantCode )
3244 FT_UInt32 numVar = TT_PEEK_ULONG( base );
3256 FT_UInt32 mid = ( min + max ) >> 1;
3257 FT_Byte* p = base + 11 * mid;
3258 FT_ULong varSel = TT_NEXT_UINT24( p );
3261 if ( variantCode < varSel )
3263 else if ( variantCode > varSel )
3273 FT_CALLBACK_DEF( FT_UInt )
3274 tt_cmap14_char_var_index( FT_CMap cmap,
3277 FT_UInt32 variantSelector )
3279 TT_CMap ttcmap = (TT_CMap)cmap;
3280 TT_CMap ttucmap = (TT_CMap)ucmap;
3282 FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6,
3291 defOff = TT_NEXT_ULONG( p );
3292 nondefOff = TT_PEEK_ULONG( p );
3295 tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
3299 return ttucmap->cmap.clazz->char_index( &ttucmap->cmap, charcode );
3302 if ( nondefOff != 0 )
3303 return tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
3310 FT_CALLBACK_DEF( FT_Int )
3311 tt_cmap14_char_var_isdefault( FT_CMap cmap,
3313 FT_UInt32 variantSelector )
3315 TT_CMap ttcmap = (TT_CMap)cmap;
3316 FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6,
3325 defOff = TT_NEXT_ULONG( p );
3326 nondefOff = TT_NEXT_ULONG( p );
3329 tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
3332 if ( nondefOff != 0 &&
3333 tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
3341 FT_CALLBACK_DEF( FT_UInt32* )
3342 tt_cmap14_variants( FT_CMap cmap,
3345 TT_CMap ttcmap = (TT_CMap)cmap;
3346 TT_CMap14 cmap14 = (TT_CMap14)cmap;
3347 FT_UInt32 count = cmap14->num_selectors;
3348 FT_Byte* p = ttcmap->data + 10;
3353 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3356 result = cmap14->results;
3357 for ( i = 0; i < count; i++ )
3359 result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3368 FT_CALLBACK_DEF( FT_UInt32 * )
3369 tt_cmap14_char_variants( FT_CMap cmap,
3371 FT_UInt32 charCode )
3373 TT_CMap ttcmap = (TT_CMap)cmap;
3374 TT_CMap14 cmap14 = (TT_CMap14)cmap;
3375 FT_UInt32 count = cmap14->num_selectors;
3376 FT_Byte* p = ttcmap->data + 10;
3380 if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
3383 for ( q = cmap14->results; count > 0; count-- )
3385 FT_UInt32 varSel = TT_NEXT_UINT24( p );
3386 FT_ULong defOff = TT_NEXT_ULONG( p );
3387 FT_ULong nondefOff = TT_NEXT_ULONG( p );
3390 if ( ( defOff != 0 &&
3391 tt_cmap14_char_map_def_binary( ttcmap->data + defOff,
3394 tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
3403 return cmap14->results;
3408 tt_cmap14_def_char_count( FT_Byte *p )
3410 FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3415 for ( ; numRanges > 0; numRanges-- )
3426 tt_cmap14_get_def_chars( TT_CMap cmap,
3430 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3431 FT_UInt32 numRanges;
3436 cnt = tt_cmap14_def_char_count( p );
3437 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
3439 if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
3442 for ( q = cmap14->results; numRanges > 0; numRanges-- )
3444 FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
3447 cnt = FT_NEXT_BYTE( p ) + 1;
3454 }
while ( --cnt != 0 );
3458 return cmap14->results;
3463 tt_cmap14_get_nondef_chars( TT_CMap cmap,
3467 TT_CMap14 cmap14 = (TT_CMap14) cmap;
3468 FT_UInt32 numMappings;
3473 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3475 if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
3478 ret = cmap14->results;
3479 for ( i = 0; i < numMappings; i++ )
3481 ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
3490 FT_CALLBACK_DEF( FT_UInt32 * )
3491 tt_cmap14_variant_chars( FT_CMap cmap,
3493 FT_UInt32 variantSelector )
3495 TT_CMap ttcmap = (TT_CMap)cmap;
3496 FT_Byte *p = tt_cmap14_find_variant( ttcmap->data + 6,
3506 defOff = TT_NEXT_ULONG( p );
3507 nondefOff = TT_NEXT_ULONG( p );
3509 if ( defOff == 0 && nondefOff == 0 )
3513 return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
3515 else if ( nondefOff == 0 )
3516 return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
3522 TT_CMap14 cmap14 = (TT_CMap14)cmap;
3523 FT_UInt32 numRanges;
3524 FT_UInt32 numMappings;
3534 p = ttcmap->data + nondefOff;
3535 dp = ttcmap->data + defOff;
3537 numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
3538 dcnt = tt_cmap14_def_char_count( dp );
3539 numRanges = (FT_UInt32)TT_NEXT_ULONG( dp );
3541 if ( numMappings == 0 )
3542 return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
3545 return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
3548 if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
3551 ret = cmap14->results;
3552 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3553 dcnt = FT_NEXT_BYTE( dp );
3555 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3562 if ( nuni > duni + dcnt )
3564 for ( k = 0; k <= dcnt; k++ )
3565 ret[i++] = duni + k;
3569 if ( di > numRanges )
3572 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3573 dcnt = FT_NEXT_BYTE( dp );
3582 if ( ni > numMappings )
3585 nuni = (FT_UInt32)TT_NEXT_UINT24( p );
3590 if ( ni <= numMappings )
3596 while ( ni < numMappings )
3598 ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
3603 else if ( di <= numRanges )
3608 for ( k = 0; k <= dcnt; k++ )
3609 ret[i++] = duni + k;
3611 while ( di < numRanges )
3613 duni = (FT_UInt32)TT_NEXT_UINT24( dp );
3614 dcnt = FT_NEXT_BYTE( dp );
3616 for ( k = 0; k <= dcnt; k++ )
3617 ret[i++] = duni + k;
3630 tt_cmap14_class_rec,
3632 sizeof ( TT_CMap14Rec ),
3634 (FT_CMap_InitFunc) tt_cmap14_init,
3635 (FT_CMap_DoneFunc) tt_cmap14_done,
3636 (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
3637 (FT_CMap_CharNextFunc) tt_cmap14_char_next,
3640 (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
3641 (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
3642 (FT_CMap_VariantListFunc) tt_cmap14_variants,
3643 (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
3644 (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
3647 (TT_CMap_ValidateFunc)tt_cmap14_validate,
3648 (TT_CMap_Info_GetFunc)tt_cmap14_get_info
3664#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
3666 FT_CALLBACK_DEF(
const char * )
3667 tt_get_glyph_name(
void* face_,
3670 TT_Face face = (TT_Face)face_;
3671 FT_String* PSname = NULL;
3674 tt_face_get_ps_name( face, idx, &PSname );
3680 FT_CALLBACK_DEF( FT_Error )
3681 tt_cmap_unicode_init( FT_CMap cmap,
3682 FT_Pointer pointer )
3684 PS_Unicodes unicodes = (PS_Unicodes)cmap;
3685 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
3686 FT_Memory memory = FT_FACE_MEMORY( face );
3687 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3689 FT_UNUSED( pointer );
3692 if ( !psnames->unicodes_init )
3693 return FT_THROW( Unimplemented_Feature );
3695 return psnames->unicodes_init( memory,
3697 face->root.num_glyphs,
3699 (PS_FreeGlyphNameFunc)NULL,
3704 FT_CALLBACK_DEF(
void )
3705 tt_cmap_unicode_done( FT_CMap cmap )
3707 PS_Unicodes unicodes = (PS_Unicodes)cmap;
3708 FT_Face face = FT_CMAP_FACE( cmap );
3709 FT_Memory memory = FT_FACE_MEMORY( face );
3712 FT_FREE( unicodes->maps );
3713 unicodes->num_maps = 0;
3717 FT_CALLBACK_DEF( FT_UInt )
3718 tt_cmap_unicode_char_index( FT_CMap cmap,
3719 FT_UInt32 char_code )
3721 PS_Unicodes unicodes = (PS_Unicodes)cmap;
3722 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
3723 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3726 return psnames->unicodes_char_index( unicodes, char_code );
3730 FT_CALLBACK_DEF( FT_UInt )
3731 tt_cmap_unicode_char_next( FT_CMap cmap,
3732 FT_UInt32 *pchar_code )
3734 PS_Unicodes unicodes = (PS_Unicodes)cmap;
3735 TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
3736 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
3739 return psnames->unicodes_char_next( unicodes, pchar_code );
3744 tt_cmap_unicode_class_rec,
3746 sizeof ( PS_UnicodesRec ),
3748 (FT_CMap_InitFunc) tt_cmap_unicode_init,
3749 (FT_CMap_DoneFunc) tt_cmap_unicode_done,
3750 (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index,
3751 (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next,
3753 (FT_CMap_CharVarIndexFunc) NULL,
3754 (FT_CMap_CharVarIsDefaultFunc)NULL,
3755 (FT_CMap_VariantListFunc) NULL,
3756 (FT_CMap_CharVariantListFunc) NULL,
3757 (FT_CMap_VariantCharListFunc) NULL,
3760 (TT_CMap_ValidateFunc)NULL,
3761 (TT_CMap_Info_GetFunc)NULL
3767 static const TT_CMap_Class tt_cmap_classes[] =
3770#define TTCMAPCITEM( a ) &a,
3779 FT_LOCAL_DEF( FT_Error )
3780 tt_face_build_cmaps( TT_Face face )
3782 FT_Byte*
const table = face->cmap_table;
3784 FT_UInt
volatile num_cmaps;
3785 FT_Byte*
volatile p = table;
3786 FT_Library library = FT_FACE_LIBRARY( face );
3788 FT_UNUSED( library );
3791 if ( !p || face->cmap_size < 4 )
3792 return FT_THROW( Invalid_Table );
3805 num_cmaps = TT_NEXT_USHORT( p );
3806 FT_TRACE4((
"tt_face_build_cmaps: %u cmaps\n", num_cmaps ));
3808 limit = table + face->cmap_size;
3809 for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
3811 FT_CharMapRec charmap;
3815 charmap.platform_id = TT_NEXT_USHORT( p );
3816 charmap.encoding_id = TT_NEXT_USHORT( p );
3817 charmap.face = FT_FACE( face );
3818 charmap.encoding = FT_ENCODING_NONE;
3819 offset = TT_NEXT_ULONG( p );
3821 if ( offset && offset <= face->cmap_size - 2 )
3823 FT_Byte*
volatile cmap = table + offset;
3824 volatile FT_UInt format = TT_PEEK_USHORT( cmap );
3825 const TT_CMap_Class*
volatile pclazz = tt_cmap_classes;
3826 TT_CMap_Class
volatile clazz;
3829 for ( ; *pclazz; pclazz++ )
3832 if ( clazz->format == format )
3834 volatile TT_ValidatorRec valid;
3835 volatile FT_Error error = FT_Err_Ok;
3838 ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
3839 FT_VALIDATE_DEFAULT );
3841 valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
3843 if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
3846 error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
3849 if ( !valid.validator.error )
3858 if ( !FT_CMap_New( (FT_CMap_Class)clazz,
3859 cmap, &charmap, &ttcmap ) )
3863 ((TT_CMap)ttcmap)->flags = (FT_Int)error;
3868 FT_TRACE0((
"tt_face_build_cmaps:"
3869 " broken cmap sub-table ignored\n" ));
3877 FT_TRACE0((
"tt_face_build_cmaps:"
3878 " unsupported cmap sub-table ignored\n" ));
3887 FT_LOCAL_DEF( FT_Error )
3888 tt_get_cmap_info( FT_CharMap charmap,
3889 TT_CMapInfo *cmap_info )
3891 FT_CMap cmap = FT_CMAP( charmap );
3892 TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
3895 if ( clazz->get_cmap_info )
3896 return clazz->get_cmap_info( charmap, cmap_info );
3898 return FT_THROW( Invalid_CharMap_Format );