summaryrefslogtreecommitdiffstats
path: root/utf8.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2008-09-25 20:08:57 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2008-09-25 20:08:57 +0000
commitefe557313aef555b415fa2ea2c9a50c4404ed788 (patch)
tree4a197ade3d901f79bc8b0b990f9756d3da7f5f01 /utf8.c
parent9edb4d4b85a8714162817f2ae428e654e6bf1f31 (diff)
Internal screen data rewrite for better 256 colour/UTF-8 support.
Diffstat (limited to 'utf8.c')
-rw-r--r--utf8.c133
1 files changed, 53 insertions, 80 deletions
diff --git a/utf8.c b/utf8.c
index 77179e77..5e1c6b94 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,4 +1,4 @@
-/* $Id: utf8.c,v 1.1 2008-09-09 22:16:37 nicm Exp $ */
+/* $Id: utf8.c,v 1.2 2008-09-25 20:08:56 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,93 +22,66 @@
#include "tmux.h"
-/*
- * UTF8 data structures. Just crappy array + linear search for now.
- */
-
-/* Pack UTF8 index into attr, data. */
-void
-utf8_pack(int idx, u_char *data, u_short *attr)
-{
- *data = idx & 0xff;
-
- *attr &= ~(ATTR_UTF8b8|ATTR_UTF8b9);
- if (idx & 0x100)
- *attr |= ATTR_UTF8b8;
- if (idx & 0x200)
- *attr |= ATTR_UTF8b9;
- if (idx & 0x400)
- *attr |= ATTR_UTF8b10;
- if (idx & 0x800)
- *attr |= ATTR_UTF8b11;
-}
-
-/* Unpack UTF8 index from attr, data. */
-int
-utf8_unpack(u_char data, u_short attr)
+u_int
+utf8_combine(const u_char data[4])
{
- int idx;
-
- idx = data;
- if (attr & ATTR_UTF8b8)
- idx |= 0x100;
- if (attr & ATTR_UTF8b9)
- idx |= 0x200;
- if (attr & ATTR_UTF8b10)
- idx |= 0x400;
- if (attr & ATTR_UTF8b11)
- idx |= 0x800;
-
- return (idx);
-}
-
-void
-utf8_init(struct utf8_table *utab, int limit)
-{
- utab->limit = limit;
- ARRAY_INIT(&utab->array);
+ u_int uv;
+
+ if (data[1] == 0xff)
+ uv = data[0];
+ else if (data[2] == 0xff) {
+ uv = data[1] & 0x3f;
+ uv |= (data[0] & 0x1f) << 6;
+ } else if (data[3] == 0xff) {
+ uv = data[2] & 0x3f;
+ uv |= (data[1] & 0x3f) << 6;
+ uv |= (data[0] & 0x0f) << 12;
+ } else {
+ uv = data[3] & 0x3f;
+ uv |= (data[2] & 0x3f) << 6;
+ uv |= (data[1] & 0x3f) << 12;
+ uv |= (data[0] & 0x3f) << 18;
+ }
+ return (uv);
}
void
-utf8_free(struct utf8_table *utab)
+utf8_split(u_int uv, u_char data[4])
{
- ARRAY_FREE(&utab->array);
-}
-
-struct utf8_data *
-utf8_lookup(struct utf8_table *utab, int idx)
-{
- if (idx < 0 || idx >= (int) ARRAY_LENGTH(&utab->array))
- return (NULL);
- return (&ARRAY_ITEM(&utab->array, idx));
-}
-
-int
-utf8_search(struct utf8_table *utab, struct utf8_data *udat)
-{
- u_int idx;
-
- for (idx = 0; idx < ARRAY_LENGTH(&utab->array); idx++) {
- if (memcmp(udat->data,
- ARRAY_ITEM(&utab->array, idx).data, sizeof udat->data) == 0)
- return (idx);
+ memset(data, 0xff, sizeof data);
+
+ if (uv <= 0x7f)
+ data[0] = uv;
+ else if (uv > 0x7f && uv <= 0x7ff) {
+ data[0] = (uv >> 6) | 0xc0;
+ data[1] = (uv & 0x3f) | 0x80;
+ } else if (uv > 0x7ff && uv <= 0xffff) {
+ data[0] = (uv >> 12) | 0xe0;
+ data[1] = ((uv >> 6) & 0x3f) | 0x80;
+ data[2] = (uv & 0x3f) | 0x80;
+ } else if (uv > 0xffff && uv <= 0x10ffff) {
+ data[0] = (uv >> 18) | 0xf0;
+ data[1] = ((uv >> 12) & 0x3f) | 0x80;
+ data[2] = ((uv >> 6) & 0x3f) | 0x80;
+ data[3] = (uv & 0x3f) | 0x80;
}
- return (-1);
}
int
-utf8_add(struct utf8_table *utab, struct utf8_data *udat)
+utf8_width(u_int uv)
{
- int idx;
-
- if (ARRAY_LENGTH(&utab->array) == utab->limit)
- return (-1);
-
- if ((idx = utf8_search(utab, udat)) != -1)
- return (idx);
-
- ARRAY_EXPAND(&utab->array, 1);
- memcpy(
- &ARRAY_LAST(&utab->array), udat, sizeof ARRAY_LAST(&utab->array));
- return (ARRAY_LENGTH(&utab->array) - 1);
+ if ((uv >= 0x1100 && uv <= 0x115f) ||
+ uv == 0x2329 ||
+ uv == 0x232a ||
+ (uv >= 0x2e80 && uv <= 0xa4cf && uv != 0x303f) ||
+ (uv >= 0xac00 && uv <= 0xd7a3) ||
+ (uv >= 0xf900 && uv <= 0xfaff) ||
+ (uv >= 0xfe10 && uv <= 0xfe19) ||
+ (uv >= 0xfe30 && uv <= 0xfe6f) ||
+ (uv >= 0xff00 && uv <= 0xff60) ||
+ (uv >= 0xffe0 && uv <= 0xffe6) ||
+ (uv >= 0x20000 && uv <= 0x2fffd) ||
+ (uv >= 0x30000 && uv <= 0x3fffd))
+ return (2);
+ return (1);
}