4 |
/* */ |
/* */ |
5 |
/* TrueType character mapping table (cmap) support (body). */ |
/* TrueType character mapping table (cmap) support (body). */ |
6 |
/* */ |
/* */ |
7 |
/* Copyright 2002, 2003, 2004 by */ |
/* Copyright 2002, 2003, 2004, 2005 by */ |
8 |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 |
/* */ |
/* */ |
10 |
/* This file is part of the FreeType project, and may only be used, */ |
/* This file is part of the FreeType project, and may only be used, */ |
627 |
|
|
628 |
typedef struct TT_CMap4Rec_ |
typedef struct TT_CMap4Rec_ |
629 |
{ |
{ |
630 |
TT_CMapRec cmap; |
TT_CMapRec cmap; |
631 |
FT_UInt32 old_charcode; /* old charcode */ |
FT_UInt32 old_charcode; /* old charcode */ |
632 |
FT_UInt32 cur_charcode; /* current charcode */ |
FT_UInt32 cur_charcode; /* current charcode */ |
633 |
FT_UInt cur_gindex; /* current glyph index */ |
FT_UInt cur_gindex; /* current glyph index */ |
634 |
|
|
635 |
FT_UInt table_length; |
FT_UInt table_length; |
636 |
FT_UInt num_ranges; |
FT_UInt num_ranges; |
637 |
FT_UInt cur_range; |
FT_UInt cur_range; |
638 |
FT_UInt cur_start; |
FT_UInt cur_start; |
639 |
FT_UInt cur_end; |
FT_UInt cur_end; |
640 |
FT_Int cur_delta; |
FT_Int cur_delta; |
641 |
FT_Byte* cur_values; |
FT_Byte* cur_values; |
642 |
|
|
643 |
} TT_CMap4Rec, *TT_CMap4; |
} TT_CMap4Rec, *TT_CMap4; |
644 |
|
|
647 |
tt_cmap4_init( TT_CMap4 cmap, |
tt_cmap4_init( TT_CMap4 cmap, |
648 |
FT_Byte* table ) |
FT_Byte* table ) |
649 |
{ |
{ |
650 |
FT_Byte* p; |
FT_Byte* p; |
651 |
|
|
652 |
|
|
653 |
cmap->cmap.data = table; |
cmap->cmap.data = table; |
654 |
|
|
655 |
p = table + 2; |
p = table + 2; |
656 |
cmap->table_length = FT_PEEK_USHORT(p); |
cmap->table_length = FT_PEEK_USHORT( p ); |
657 |
|
|
658 |
p = table + 6; |
p = table + 6; |
659 |
cmap->num_ranges = FT_PEEK_USHORT(p) >> 1; |
cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; |
660 |
cmap->cur_range = cmap->num_ranges; |
cmap->cur_range = cmap->num_ranges; |
661 |
cmap->old_charcode = 0xFFFFFFFFUL; |
cmap->old_charcode = 0xFFFFFFFFUL; |
662 |
cmap->cur_charcode = 0; |
cmap->cur_charcode = 0; |
666 |
} |
} |
667 |
|
|
668 |
|
|
|
|
|
669 |
static FT_Int |
static FT_Int |
670 |
tt_cmap4_set_range( TT_CMap4 cmap, |
tt_cmap4_set_range( TT_CMap4 cmap, |
671 |
FT_UInt range_index ) |
FT_UInt range_index ) |
674 |
FT_Byte* p; |
FT_Byte* p; |
675 |
FT_UInt num_ranges = cmap->num_ranges; |
FT_UInt num_ranges = cmap->num_ranges; |
676 |
|
|
677 |
|
|
678 |
while ( range_index < num_ranges ) |
while ( range_index < num_ranges ) |
679 |
{ |
{ |
680 |
FT_UInt offset; |
FT_UInt offset; |
681 |
|
|
|
p = table + 14 + range_index*2; |
|
|
cmap->cur_end = FT_PEEK_USHORT(p); |
|
682 |
|
|
683 |
p += 2 + num_ranges*2; |
p = table + 14 + range_index * 2; |
684 |
cmap->cur_start = FT_PEEK_USHORT(p); |
cmap->cur_end = FT_PEEK_USHORT( p ); |
685 |
|
|
686 |
|
p += 2 + num_ranges * 2; |
687 |
|
cmap->cur_start = FT_PEEK_USHORT( p ); |
688 |
|
|
689 |
p += num_ranges*2; |
p += num_ranges * 2; |
690 |
cmap->cur_delta = FT_PEEK_SHORT(p); |
cmap->cur_delta = FT_PEEK_SHORT( p ); |
691 |
|
|
692 |
p += num_ranges*2; |
p += num_ranges * 2; |
693 |
offset = FT_PEEK_SHORT(p); |
offset = FT_PEEK_SHORT( p ); |
694 |
|
|
695 |
if ( offset != 0xFFFF ) |
if ( offset != 0xFFFFU ) |
696 |
{ |
{ |
697 |
cmap->cur_values = offset ? p + offset : NULL; |
cmap->cur_values = offset ? p + offset : NULL; |
698 |
cmap->cur_range = range_index; |
cmap->cur_range = range_index; |
714 |
static void |
static void |
715 |
tt_cmap4_next( TT_CMap4 cmap ) |
tt_cmap4_next( TT_CMap4 cmap ) |
716 |
{ |
{ |
|
FT_UInt num_ranges = cmap->num_ranges; |
|
717 |
FT_UInt charcode = cmap->cur_charcode + 1; |
FT_UInt charcode = cmap->cur_charcode + 1; |
718 |
|
|
719 |
|
|
720 |
cmap->old_charcode = cmap->cur_charcode; |
cmap->old_charcode = cmap->cur_charcode; |
721 |
|
|
722 |
for ( ;; ) |
for ( ;; ) |
723 |
{ |
{ |
724 |
FT_Byte* values = cmap->cur_values; |
FT_Byte* values = cmap->cur_values; |
725 |
FT_UInt end = cmap->cur_end; |
FT_UInt end = cmap->cur_end; |
726 |
FT_Int delta = cmap->cur_delta; |
FT_Int delta = cmap->cur_delta; |
727 |
|
|
728 |
|
|
729 |
if ( charcode <= end ) |
if ( charcode <= end ) |
730 |
{ |
{ |
731 |
if ( values ) |
if ( values ) |
732 |
{ |
{ |
733 |
FT_Byte* p = values + 2*(charcode-cmap->cur_start); |
FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); |
734 |
|
|
735 |
|
|
736 |
do |
do |
737 |
{ |
{ |
738 |
FT_UInt gindex = FT_NEXT_USHORT(p); |
FT_UInt gindex = FT_NEXT_USHORT( p ); |
739 |
|
|
740 |
|
|
741 |
if ( gindex != 0 ) |
if ( gindex != 0 ) |
742 |
{ |
{ |
743 |
gindex = (FT_UInt)((gindex + delta) & 0xFFFF); |
gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); |
744 |
if ( gindex != 0 ) |
if ( gindex != 0 ) |
745 |
{ |
{ |
746 |
cmap->cur_charcode = charcode; |
cmap->cur_charcode = charcode; |
748 |
return; |
return; |
749 |
} |
} |
750 |
} |
} |
751 |
} |
} while ( ++charcode <= end ); |
|
while ( ++charcode <= end ); |
|
752 |
} |
} |
753 |
else |
else |
754 |
{ |
{ |
755 |
do |
do |
756 |
{ |
{ |
757 |
FT_UInt gindex = (FT_UInt)((charcode + delta) & 0xFFFFU); |
FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); |
758 |
|
|
759 |
|
|
760 |
if ( gindex != 0 ) |
if ( gindex != 0 ) |
761 |
{ |
{ |
763 |
cmap->cur_gindex = gindex; |
cmap->cur_gindex = gindex; |
764 |
return; |
return; |
765 |
} |
} |
766 |
} |
} while ( ++charcode <= end ); |
|
while ( ++charcode <= end ); |
|
767 |
} |
} |
768 |
} |
} |
769 |
|
|
770 |
/* we need to find another range |
/* we need to find another range */ |
771 |
*/ |
if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) |
|
if ( tt_cmap4_set_range( cmap, cmap->cur_range+1 ) < 0 ) |
|
772 |
break; |
break; |
773 |
|
|
774 |
charcode = cmap->cur_start; |
charcode = cmap->cur_start; |
1095 |
{ |
{ |
1096 |
TT_CMap4 cmap4 = (TT_CMap4)cmap; |
TT_CMap4 cmap4 = (TT_CMap4)cmap; |
1097 |
|
|
1098 |
|
|
1099 |
if ( char_code == cmap4->old_charcode ) |
if ( char_code == cmap4->old_charcode ) |
1100 |
{ |
{ |
1101 |
result = cmap4->cur_charcode; |
result = cmap4->cur_charcode; |