diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2008-09-25 20:08:57 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2008-09-25 20:08:57 +0000 |
commit | efe557313aef555b415fa2ea2c9a50c4404ed788 (patch) | |
tree | 4a197ade3d901f79bc8b0b990f9756d3da7f5f01 /utf8.c | |
parent | 9edb4d4b85a8714162817f2ae428e654e6bf1f31 (diff) | |
download | rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.tar.gz rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.tar.bz2 rtmux-efe557313aef555b415fa2ea2c9a50c4404ed788.zip |
Internal screen data rewrite for better 256 colour/UTF-8 support.
Diffstat (limited to 'utf8.c')
-rw-r--r-- | utf8.c | 133 |
1 files changed, 53 insertions, 80 deletions
@@ -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); } |