summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2011-06-12 14:08:05 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2011-06-12 14:16:50 +0800
commit3ac97d2511b5119e339ead697052657c5056d3d9 (patch)
tree96c6300794360872ffb296a8027fdbcff6b4612e
parent934b93d4b4c2a39858b842a7ef8efc798f74de7f (diff)
Add utf16 variant of show_text and text_extents
-rw-r--r--src/sdl-font.c64
-rw-r--r--src/sdl-freetype-utils.c56
-rw-r--r--src/sdl-freetype-utils.h3
-rw-r--r--src/sdl-freetype.h20
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