Created
December 3, 2016 20:37
-
-
Save andlabs/e5990d4f7e0b8e6071df49b5a951bff3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 3 december 2016 | |
#include "../ui.h" | |
#include "uipriv.h" | |
struct uiAttributedString { | |
char *s; | |
size_t len; | |
// TODO attributes | |
// indiscriminately keep a UTF-16 copy of the string on all platforms so we can hand this off to the grapheme calculator | |
// this ensures no one platform has a speed advantage (sorry GTK+) | |
uint16_t *u16; | |
size_t u16len; | |
size_t *u8tou16; | |
size_t *u16tou8; | |
// TODO grapheme sequences? | |
}; | |
static void resize(uiAttributedString *s, size_t u8, size_t u16) | |
{ | |
s->len = u8; | |
s->s = (char *) uiRealloc(s->s, (s->len + 1) * sizeof (char), "char[] (uiAttributedString)"); | |
s->u8tou16 = (size_t *) uiRealloc(s->u8tou16, (s->len + 1) * sizeof (size_t), "size_t[] (uiAttributedString)"); | |
s->u16len = u16; | |
s->u16 = (uint16_t *) uiRealloc(s->u16, (s->u16len + 1) * sizeof (uint16_t), "uint16_t[] (uiAttributedString)"); | |
s->u16tou8 = (size_t *) uiRealloc(s->u16tou8, (s->u16len + 1) * sizeof (size_t), "size_t[] (uiAttributedString)"); | |
} | |
uiAttributedString *uiNewAttributedString(const char *initialString) | |
{ | |
uiAttributedString *s; | |
s = uiNew(uiAttributedString); | |
uiAttributedStringAppendUnattributed(s, initialString); | |
return s; | |
} | |
void uiFreeAttributedString(uiAttributedString *s) | |
{ | |
uiFree(s->u16tou8); | |
uiFree(s->u8tou16); | |
uiFree(s->u16); | |
uiFree(s->s); | |
uiFree(s); | |
} | |
const char *uiAttributedStringString(uiAttributedString *s) | |
{ | |
return s->s; | |
} | |
void uiAttributedStringAppendUnattributed(uiAttributedString *s, const char *str) | |
{ | |
const char *t; | |
uint32_t rune; | |
char buf[4]; | |
uint16_t u16buf[2]; | |
size_t n, n16; | |
size_t old, old; | |
// first figure out how much we need to grow by | |
// this includes post-validated UTF-8 | |
t = str; | |
n = 0; | |
n16 = 0; | |
while (*t) { | |
t = utf8DecodeRune(t, 0, &rune); | |
n += utf8EncodeRune(rune, buf); | |
n16 += utf16EncodeRune(rune, buf16); | |
} | |
// and resize | |
old = s->len; | |
old16 = s->len16; | |
resize(s, s->len + n, s->u16len + n16); | |
// and copy | |
while (*str) { | |
str = utf8DecodeRune(str, 0, &rune); | |
n = utf8EncodeRune(rune, buf); | |
n16 = utf16EncodeRune(rune, buf16); | |
s->s[old] = buf[0]; | |
s->u8tou16[old] = old16; | |
if (n > 1) { | |
s->s[old + 1] = buf[1]; | |
s->u8tou16[old + 1] = old16; | |
} | |
if (n > 2) { | |
s->s[old + 2] = buf[2]; | |
s->u8tou16[old + 2] = old16; | |
} | |
if (n > 3) { | |
s->s[old + 3] = buf[3]; | |
s->u8tou16[old + 3] = old16; | |
} | |
s->u16[old16] = buf16[0]; | |
s->u16tou8[old16] = old; | |
if (n16 > 1) { | |
s->u16[old16 + 1] = buf16[1]; | |
s->u16tou8[old16 + 1] = old; | |
} | |
old += n; | |
old16 += n16; | |
} | |
// TODO invalidate the grapheme conversion? | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment