summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--minuitwrp/truetype.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/minuitwrp/truetype.c b/minuitwrp/truetype.c
index 8e0df42ea..afe5d4c28 100644
--- a/minuitwrp/truetype.c
+++ b/minuitwrp/truetype.c
@@ -118,6 +118,42 @@ static inline uint32_t fnv_hash_add(uint32_t cur_hash, uint32_t word)
return cur_hash;
}
+int utf8_to_unicode(unsigned char* pIn, unsigned int *pOut)
+{
+ if(pIn == NULL || pOut == NULL)
+ return 0;
+
+ int utf_bytes = 1;
+ unsigned int unicode = 0;
+ unsigned char tmp;
+ tmp = *pIn++;
+ if (tmp < 0x80)
+ {
+ *pOut = tmp;
+ }
+ else
+ {
+ unsigned int high_bit_mask = 0x3F;
+ unsigned int high_bit_shift = 0;
+ int total_bits = 0;
+ while((tmp & 0xC0) == 0xC0)
+ {
+ utf_bytes ++;
+ if(utf_bytes > 6) return 0;
+ tmp = 0xFF & (tmp << 1);
+ total_bits += 6;
+ high_bit_mask >>= 1;
+ high_bit_shift++;
+ unicode <<= 6;
+ unicode |= (*pIn++) & 0x3F;
+ }
+ unicode |= ((tmp >> high_bit_shift) & high_bit_mask) << total_bits;
+ *pOut = unicode;
+ }
+
+ return utf_bytes;
+}
+
static bool gr_ttf_string_cache_equals(void *keyA, void *keyB)
{
StringCacheKey *a = keyA;
@@ -347,16 +383,22 @@ static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const cha
TrueTypeFont *f = font;
TrueTypeCacheEntry *ent;
int max_len = 0, total_w = 0;
- char c;
+ int utf_bytes = 0;
+ unsigned int unicode = 0;
int i, x, diff, char_idx, prev_idx = 0;
int height, base;
FT_Vector delta;
uint8_t *data = NULL;
const char *text_itr = text;
+ int *char_idxs;
- while((c = *text_itr++))
+ char_idxs = (int*)malloc(strlen(text) * sizeof(int));
+ while(*text_itr)
{
- char_idx = FT_Get_Char_Index(f->face, c);
+ utf_bytes = utf8_to_unicode(text_itr, &unicode);
+ text_itr += (utf_bytes == 0)? 1: utf_bytes;
+ char_idx = FT_Get_Char_Index(f->face, unicode);
+ char_idxs[max_len] = char_idx;
ent = gr_ttf_glyph_cache_get(f, char_idx);
if(ent)
{
@@ -381,7 +423,10 @@ static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const cha
gr_ttf_getMaxFontHeight(font);
if(font->max_height == -1)
+ {
+ free(char_idxs);
return -1;
+ }
height = font->max_height;
@@ -399,7 +444,7 @@ static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const cha
for(i = 0; i < max_len; ++i)
{
- char_idx = FT_Get_Char_Index(f->face, text[i]);
+ char_idx = char_idxs[i];
if(FT_HAS_KERNING(f->face) && prev_idx && char_idx)
{
FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta);
@@ -416,6 +461,7 @@ static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const cha
prev_idx = char_idx;
}
+ free(char_idxs);
return max_len;
}
@@ -525,7 +571,8 @@ int gr_ttf_maxExW(const char *s, void *font, int max_width)
TrueTypeFont *f = font;
TrueTypeCacheEntry *ent;
int max_len = 0, total_w = 0;
- char c;
+ int utf_bytes = 0;
+ unsigned int unicode;
int char_idx, prev_idx = 0;
FT_Vector delta;
StringCacheEntry *e;
@@ -540,9 +587,10 @@ int gr_ttf_maxExW(const char *s, void *font, int max_width)
return max_len;
}
- for(; (c = *s++); ++max_len)
+ for(; *s; ++max_len)
{
- char_idx = FT_Get_Char_Index(f->face, c);
+ utf_bytes = utf8_to_unicode(s, &unicode);
+ s += (utf_bytes == 0)? 1: utf_bytes;
if(FT_HAS_KERNING(f->face) && prev_idx && char_idx)
{
FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta);