stb
stb copied to clipboard
format == 2 high-byte mapping for japanese/chinese/korean
my code function get_glyph_index2(...)
#define BYTE_( p, i ) ( ((const unsigned char*)(p))[(i)] ) #define BYTE_U16( p, i, s1 ) ( (uint16_t)( BYTE_( p, i ) ) << (s1) ) #define BYTE_U32( p, i, s1 ) ( (uint32_t)( BYTE_( p, i ) ) << (s1) ) #define PEEK_USHORT( p ) uint16_t( BYTE_U16( p, 0, 8 ) | BYTE_U16( p, 1, 0 ) ) #define NEXT_SHORT( b ) ( (short)( b += 2, PEEK_USHORT( b - 2 ) ) ) #define NEXT_USHORT( b ) ( (unsigned short)( b += 2, PEEK_USHORT( b - 2 ) ) ) unsigned char* tt_cmap2_get_subheader(unsigned char* table, unsigned int char_code) { unsigned char* result = NULL; if (char_code < 0x10000UL) { unsigned int char_lo = (unsigned int)(char_code & 0xFF); unsigned int char_hi = (unsigned int)(char_code >> 8); unsigned char* p = table + 6; /* keys table / unsigned char subs = table + 518; /* subheaders table / unsigned char sub; if (char_hi == 0) { /* an 8-bit character code -- we use subHeader 0 in this case / / to test whether the character code is in the charmap / / */ sub = subs; p += char_lo * 2; if (PEEK_USHORT(p) != 0)sub = 0; } else { p += char_hi * 2; sub = subs + (uint64_t)PEEK_USHORT(p); } result = sub; } return result; }
int tt_cmap2_char_index(unsigned char* table, unsigned int char_code)
{
unsigned int result = 0;
unsigned char* subheader;
subheader = tt_cmap2_get_subheader(table, char_code);
if (subheader)
{
unsigned char* p = subheader;
unsigned int idx = ((unsigned int)(char_code) & 0xFF);
unsigned int start, count;
int delta;
unsigned int offset;
start = NEXT_USHORT(p);
count = NEXT_USHORT(p);
delta = NEXT_SHORT(p);
offset = PEEK_USHORT(p);
idx -= start;
if (idx < count && offset != 0)
{
p += offset + 2 * idx;
idx = PEEK_USHORT(p);
if (idx != 0)
result = (unsigned int)((int)idx + delta) & 0xFFFFU;
}
}
return result;
}
int get_glyph_index2(const stbtt_fontinfo* info , const char* t)
{
int ret = 0;
uint8_t* data = info->data;
uint32_t index_map = info->index_map;
uint16_t format = ttUSHORT(data + index_map + 0);
unsigned int codepoint = 0;
if (format == 2) {
codepoint = (unsigned int)t[0] & 0xff;
if (codepoint > 127)
{
codepoint <<= 8;
codepoint |= (unsigned int)t[1] & 0xff;
}
ret = tt_cmap2_char_index(data + index_map, codepoint);
}
return ret;
}