about summary refs log tree commit diff stats
path: root/cpp/termbox/utf8.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/termbox/utf8.c')
-rw-r--r--cpp/termbox/utf8.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/cpp/termbox/utf8.c b/cpp/termbox/utf8.c
new file mode 100644
index 00000000..0c37dae5
--- /dev/null
+++ b/cpp/termbox/utf8.c
@@ -0,0 +1,79 @@
+#include "termbox.h"
+
+static const unsigned char utf8_length[256] = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
+};
+
+static const unsigned char utf8_mask[6] = {
+	0x7F,
+	0x1F,
+	0x0F,
+	0x07,
+	0x03,
+	0x01
+};
+
+int tb_utf8_char_length(char c)
+{
+	return utf8_length[(unsigned char)c];
+}
+
+int tb_utf8_char_to_unicode(uint32_t *out, const char *c)
+{
+	if (*c == 0)
+		return TB_EOF;
+
+	int i;
+	unsigned char len = tb_utf8_char_length(*c);
+	unsigned char mask = utf8_mask[len-1];
+	uint32_t result = c[0] & mask;
+	for (i = 1; i < len; ++i) {
+		result <<= 6;
+		result |= c[i] & 0x3f;
+	}
+
+	*out = result;
+	return (int)len;
+}
+
+int tb_utf8_unicode_to_char(char *out, uint32_t c)
+{
+	int len = 0;
+	int first;
+	int i;
+
+	if (c < 0x80) {
+		first = 0;
+		len = 1;
+	} else if (c < 0x800) {
+		first = 0xc0;
+		len = 2;
+	} else if (c < 0x10000) {
+		first = 0xe0;
+		len = 3;
+	} else if (c < 0x200000) {
+		first = 0xf0;
+		len = 4;
+	} else if (c < 0x4000000) {
+		first = 0xf8;
+		len = 5;
+	} else {
+		first = 0xfc;
+		len = 6;
+	}
+
+	for (i = len - 1; i > 0; --i) {
+		out[i] = (c & 0x3f) | 0x80;
+		c >>= 6;
+	}
+	out[0] = c | first;
+
+	return len;
+}