diff options
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | src/console.c | 78 |
2 files changed, 53 insertions, 29 deletions
diff --git a/meson.build b/meson.build index 7cf64b5..dd1944b 100644 --- a/meson.build +++ b/meson.build @@ -44,12 +44,14 @@ if not gl_dep.found() gl_dep = dependency('opengl') endif +libgrapheme = cc.find_library('grapheme') + deps_for_imv = [ dependency('pangocairo'), gl_dep, dependency('threads'), dependency('xkbcommon'), - dependency('icu-io'), + libgrapheme, dependency('inih', fallback : ['inih', 'inih_dep']), m_dep, ] diff --git a/src/console.c b/src/console.c index 073274f..7286288 100644 --- a/src/console.c +++ b/src/console.c @@ -6,8 +6,7 @@ #include <ctype.h> #include <stdlib.h> #include <string.h> -#include <unicode/utext.h> -#include <unicode/ubrk.h> +#include <grapheme.h> struct imv_console { char *buffer; @@ -22,25 +21,57 @@ struct imv_console { char *history_before; /* contents of line before history was opened */ }; -/* Iterates forwards over characters in a UTF-8 string */ -static size_t next_char(char *buffer, size_t position) +static size_t grapheme_strlen(char *str) { - size_t result = position; - UErrorCode status = U_ZERO_ERROR; - UText *ut = utext_openUTF8(NULL, buffer, -1, &status); + size_t len = 0, ret = 0; + char *s = strdup(str); + while (*s != '\0') { + len = grapheme_bytelen(s); + ret += len; + s += len; + } + return ret; +} - UBreakIterator *it = ubrk_open(UBRK_CHARACTER, NULL, NULL, 0, &status); - ubrk_setUText(it, ut, &status); +static int32_t grapheme_following(char* str, size_t strlength, int32_t offset) +{ + int32_t result; + char *s = strdup(str); + s += offset; + if (!((int)offset<(int)strlength)||*s=='\0') + return -1; + result = (int32_t) grapheme_bytelen(s); + return ((result + offset) > strlength) ? -2 : result + offset; +} - int boundary = ubrk_following(it, (int)position); - if (boundary != UBRK_DONE) { - result = (size_t)boundary; +static int32_t grapheme_preceding(char *str, size_t strlength, int32_t offset) +{ + size_t len; + int32_t result = 0; + if (offset<=0) + return -1; + char *s = strdup(str); + while (*s != '\0' && result < strlength) { + len = grapheme_bytelen(s); + s += len; + if ((result + (int32_t)len) < offset) + result += (int32_t)len; + else + return result; } + return -2; +} - ubrk_close(it); +/* Iterates forwards over characters in a UTF-8 string */ +static size_t next_char(char *buffer, size_t position) +{ + size_t result = position; + size_t length = grapheme_strlen(buffer); + int boundary = grapheme_following(buffer, length, position); + if (!(boundary < 0)) + result = (size_t)boundary; - utext_close(ut); - assert(U_SUCCESS(status)); + assert(boundary != -2); return result; } @@ -48,21 +79,12 @@ static size_t next_char(char *buffer, size_t position) static size_t prev_char(char *buffer, size_t position) { size_t result = position; - UErrorCode status = U_ZERO_ERROR; - UText *ut = utext_openUTF8(NULL, buffer, -1, &status); - - UBreakIterator *it = ubrk_open(UBRK_CHARACTER, NULL, NULL, 0, &status); - ubrk_setUText(it, ut, &status); - - int boundary = ubrk_preceding(it, (int)position); - if (boundary != UBRK_DONE) { + size_t length = grapheme_strlen(buffer); + int boundary = grapheme_preceding(buffer, length, position); + if (!(boundary < 0)) result = (size_t)boundary; - } - - ubrk_close(it); - utext_close(ut); - assert(U_SUCCESS(status)); + assert(boundary != -2); return result; } |