diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-12 14:08:05 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-12 14:16:50 +0800 |
commit | 3ac97d2511b5119e339ead697052657c5056d3d9 (patch) | |
tree | 96c6300794360872ffb296a8027fdbcff6b4612e | |
parent | 934b93d4b4c2a39858b842a7ef8efc798f74de7f (diff) |
Add utf16 variant of show_text and text_extents
-rw-r--r-- | src/sdl-font.c | 64 | ||||
-rw-r--r-- | src/sdl-freetype-utils.c | 56 | ||||
-rw-r--r-- | src/sdl-freetype-utils.h | 3 | ||||
-rw-r--r-- | src/sdl-freetype.h | 20 |
4 files changed, 138 insertions, 5 deletions
diff --git a/src/sdl-font.c b/src/sdl-font.c index 9545ef0..efef56b 100644 --- a/src/sdl-font.c +++ b/src/sdl-font.c @@ -1599,3 +1599,67 @@ sdl_freetype_font_utf8_fixed_extents (sdl_freetype_font_t * font, return ret; } + +sdl_freetype_error_t +sdl_freetype_font_show_utf16 (sdl_freetype_font_t * font, + void * dst, + unsigned char r, + unsigned char g, + unsigned char b, + unsigned char a, + int x, int y, + const short * utf16, int len) +{ + FT_Int32 * ucs4; + int ulen, ret; + + ulen = sdl_freetype_utf16_to_ucs4 (utf16, len, &ucs4); + if (ulen < 0) + return -1; + + ret = sdl_freetype_font_show_text (font, dst, + r, g, b, a, + x, y, ucs4, ulen); + + free (ucs4); + + return ret; +} + +sdl_freetype_error_t +sdl_freetype_font_utf16_extents (sdl_freetype_font_t * font, + sdl_freetype_text_extents_t * extents, + const short * utf16, int len) +{ + FT_Int32 * ucs4; + int ulen, ret; + + ulen = sdl_freetype_utf16_to_ucs4 (utf16, len, &ucs4); + if (ulen < 0) + return -1; + + ret = sdl_freetype_font_text_extents (font, extents, ucs4, ulen); + + free (ucs4); + + return ret; +} + +sdl_freetype_error_t +sdl_freetype_font_utf16_fixed_extents (sdl_freetype_font_t * font, + sdl_freetype_text_fixed_extents_t * extents, + const short * utf16, int len) +{ + FT_Int32 * ucs4; + int ulen, ret; + + ulen = sdl_freetype_utf16_to_ucs4 (utf16, len, &ucs4); + if (ulen < 0) + return -1; + + ret = sdl_freetype_font_text_fixed_extents (font, extents, ucs4, ulen); + + free (ucs4); + + return ret; +} 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 diff --git a/src/sdl-freetype-utils.h b/src/sdl-freetype-utils.h index 781091c..f020fe9 100644 --- a/src/sdl-freetype-utils.h +++ b/src/sdl-freetype-utils.h @@ -45,6 +45,9 @@ int sdl_freetype_utf8_to_ucs4 (const char * utf8, int len, FT_Int32 ** retucs4); int +sdl_freetype_utf16_to_ucs4 (const short * utf16, int len, FT_Int32 ** retucs4); + +int sdl_freetype_lround(double d); sdl_freetype_fixed_t diff --git a/src/sdl-freetype.h b/src/sdl-freetype.h index 434192d..2b8b1fb 100644 --- a/src/sdl-freetype.h +++ b/src/sdl-freetype.h @@ -358,6 +358,26 @@ sdl_freetype_font_utf8_fixed_extents (sdl_freetype_font_t * font, sdl_freetype_text_fixed_extents_t * extents, const char * utf8, int len); +sdl_freetype_error_t +sdl_freetype_font_show_utf16 (sdl_freetype_font_t * font, + void * dst, + unsigned char r, + unsigned char g, + unsigned char b, + unsigned char a, + int x, int y, + const short * utf16, int len); + +sdl_freetype_error_t +sdl_freetype_font_utf16_extents (sdl_freetype_font_t * font, + sdl_freetype_text_extents_t * extents, + const short * utf16, int len); + +sdl_freetype_error_t +sdl_freetype_font_utf16_fixed_extents (sdl_freetype_font_t * font, + sdl_freetype_text_fixed_extents_t * extents, + const short * utf16, int len); + #ifdef __cplusplus } #endif |