summaryrefslogtreecommitdiff
path: root/src/sdl-freetype-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdl-freetype-utils.c')
-rw-r--r--src/sdl-freetype-utils.c56
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