diff options
Diffstat (limited to 'src/sdl-freetype-utils.c')
-rw-r--r-- | src/sdl-freetype-utils.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/src/sdl-freetype-utils.c b/src/sdl-freetype-utils.c index d95b025..9d0d040 100644 --- a/src/sdl-freetype-utils.c +++ b/src/sdl-freetype-utils.c @@ -76,9 +76,9 @@ utf8_to_ucs4 (const char * str, FT_Int32 * ucs4, int len) if (!len) return 0; - + ch = *utf8++; - + if (!(ch & 0x80)) { unicode = ch; extra = 0; @@ -109,10 +109,10 @@ utf8_to_ucs4 (const char * str, FT_Int32 * ucs4, int len) while (extra--) { unicode <<= 6; ch = *utf8++; - + if ((ch & 0xc0) != 0x80) return -1; - + unicode |= ch & 0x3f; } @@ -147,7 +147,7 @@ sdl_freetype_utf8_strlen (const char * utf8, int len) int sdl_freetype_utf8_to_ucs4 (const char * utf8, int len, FT_Int32 ** retucs4) { - + int i, slen, clen; FT_Int32 * ucs4; @@ -170,6 +170,52 @@ sdl_freetype_utf8_to_ucs4 (const char * utf8, int len, FT_Int32 ** retucs4) return slen; } +#define UNI_SUR_HIGH_START 0xd800 +#define UNI_SUR_HIGH_END 0xdbff +#define UNI_SUR_LOW_START 0xdc00 +#define UNI_SUR_LOW_END 0xdfff +int +sdl_freetype_utf16_to_ucs4 (const short * utf16, int len, FT_Int32 ** retucs4) +{ + + int i, clen; + FT_Int32 * ucs4; + + if (len < 0) { + const short * s = utf16; + len = 0; + + while (*s++) + len++; + } + + ucs4 = malloc (sizeof(FT_Int32) * (len + 1)); + if (!ucs4) + return -1; + + for (i = 0; len > 0; i++) { + unsigned int ch; + + ch = *utf16++ & 0xffff; + len--; + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END && + len > 0) { + unsigned int ch2 = *utf16 & 0xfffff; + + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = (ch - UNI_SUR_HIGH_START) << 10; + ch += ch2 - UNI_SUR_LOW_START + 0x0010000; + utf16++; + len--; + } + } + ucs4[i] = ch; + } + + ucs4[i] = 0; + *retucs4 = ucs4; + return i; +} /* code from cairo */ /* This function is identical to the C99 function lround(), except that it |