diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-12-29 09:54:43 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-12-29 09:54:43 +0400 |
commit | d0ec1b1caa7ad7048bcd23f58a0b26e548c8c551 (patch) | |
tree | 53fc01a7c9ffb9267f3b4bd209471e32487974ba /source | |
parent | 07851dd8df23f716b60aa215c8cd9f7c591b0fde (diff) |
Fix for 3d text ctrl+arrow keys failing for multi-byte characters.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_string_cursor_utf8.h | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/string_cursor_utf8.c | 113 | ||||
-rw-r--r-- | source/blender/editors/curve/editfont.c | 40 |
3 files changed, 119 insertions, 38 deletions
diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h index 04d9df2abda..45910666a1e 100644 --- a/source/blender/blenlib/BLI_string_cursor_utf8.h +++ b/source/blender/blenlib/BLI_string_cursor_utf8.h @@ -48,4 +48,8 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, int *pos, strCursorJumpDirection direction, strCursorJumpType jump, bool use_init_step); +void BLI_str_cursor_step_wchar(const wchar_t *str, size_t maxlen, + int *pos, strCursorJumpDirection direction, + strCursorJumpType jump, bool use_init_step); + #endif /* __BLI_STRING_CURSOR_UTF8_H__ */ diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c index 0a579fa7108..2d2c03add97 100644 --- a/source/blender/blenlib/intern/string_cursor_utf8.c +++ b/source/blender/blenlib/intern/string_cursor_utf8.c @@ -51,12 +51,8 @@ typedef enum strCursorDelimType { STRCUR_DELIM_OTHER } strCursorDelimType; -static strCursorDelimType cursor_delim_type(const char *ch_utf8) +static strCursorDelimType cursor_delim_type_unicode(const unsigned int uch) { - /* for full unicode support we really need to have large lookup tables to figure - * out whats what in every possible char set - and python, glib both have these. */ - unsigned int uch = BLI_str_utf8_as_unicode(ch_utf8); - switch (uch) { case ',': case '.': @@ -90,6 +86,7 @@ static strCursorDelimType cursor_delim_type(const char *ch_utf8) case ' ': case '\t': + case '\n': return STRCUR_DELIM_WHITESPACE; case '\\': @@ -111,6 +108,14 @@ static strCursorDelimType cursor_delim_type(const char *ch_utf8) return STRCUR_DELIM_ALPHANUMERIC; /* Not quite true, but ok for now */ } +static strCursorDelimType cursor_delim_type_utf8(const char *ch_utf8) +{ + /* for full unicode support we really need to have large lookup tables to figure + * out whats what in every possible char set - and python, glib both have these. */ + unsigned int uch = BLI_str_utf8_as_unicode(ch_utf8); + return cursor_delim_type_unicode(uch); +} + int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos) { const char *str_end = str + (maxlen + 1); @@ -156,13 +161,13 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, } if (jump != STRCUR_JUMP_NONE) { - const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type(&str[*pos]) : STRCUR_DELIM_NONE; + const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type_utf8(&str[*pos]) : STRCUR_DELIM_NONE; /* jump between special characters (/,\,_,-, etc.), * look at function cursor_delim_type() for complete * list of special character, ctr -> */ while ((*pos) < maxlen) { if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) { - if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type(&str[*pos]))) { + if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) { break; } } @@ -181,14 +186,14 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, } if (jump != STRCUR_JUMP_NONE) { - const strCursorDelimType delim_type = (*pos) > 0 ? cursor_delim_type(&str[(*pos) - 1]) : STRCUR_DELIM_NONE; + const strCursorDelimType delim_type = (*pos) > 0 ? cursor_delim_type_utf8(&str[(*pos) - 1]) : STRCUR_DELIM_NONE; /* jump between special characters (/,\,_,-, etc.), * look at function cursor_delim_type() for complete * list of special character, ctr -> */ while ((*pos) > 0) { const int pos_prev = *pos; if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) { - if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type(&str[*pos]))) { + if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) { /* left only: compensate for index/change in direction */ if ((pos_orig - (*pos)) >= 1) { *pos = pos_prev; @@ -206,3 +211,93 @@ void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, BLI_assert(0); } } + +/* wchar_t version of BLI_str_cursor_step_utf8 (keep in sync!) + * less complex since it doesn't need to do multi-byte stepping. + */ + +/* helper funcs so we can match BLI_str_cursor_step_utf8 */ +static bool wchar_t_step_next(const wchar_t *UNUSED(str), size_t maxlen, int *pos) +{ + if ((*pos) >= (int)maxlen) { + return false; + } + (*pos)++; + return true; +} + +static bool wchar_t_step_prev(const wchar_t *UNUSED(str), size_t UNUSED(maxlen), int *pos) +{ + if ((*pos) <= 0) { + return false; + } + (*pos)--; + return true; +} + +void BLI_str_cursor_step_wchar(const wchar_t *str, size_t maxlen, + int *pos, strCursorJumpDirection direction, + strCursorJumpType jump, bool use_init_step) +{ + const int pos_orig = *pos; + + if (direction == STRCUR_DIR_NEXT) { + if (use_init_step) { + wchar_t_step_next(str, maxlen, pos); + } + else { + BLI_assert(jump == STRCUR_JUMP_DELIM); + } + + if (jump != STRCUR_JUMP_NONE) { + const strCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type_unicode((unsigned int)str[*pos]) : STRCUR_DELIM_NONE; + /* jump between special characters (/,\,_,-, etc.), + * look at function cursor_delim_type_unicode() for complete + * list of special character, ctr -> */ + while ((*pos) < maxlen) { + if (wchar_t_step_next(str, maxlen, pos)) { + if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_unicode((unsigned int)str[*pos]))) { + break; + } + } + else { + break; /* unlikely but just in case */ + } + } + } + } + else if (direction == STRCUR_DIR_PREV) { + if (use_init_step) { + wchar_t_step_prev(str, maxlen, pos); + } + else { + BLI_assert(jump == STRCUR_JUMP_DELIM); + } + + if (jump != STRCUR_JUMP_NONE) { + const strCursorDelimType delim_type = (*pos) > 0 ? cursor_delim_type_unicode((unsigned int)str[(*pos) - 1]) : STRCUR_DELIM_NONE; + /* jump between special characters (/,\,_,-, etc.), + * look at function cursor_delim_type() for complete + * list of special character, ctr -> */ + while ((*pos) > 0) { + const int pos_prev = *pos; + if (wchar_t_step_prev(str, maxlen, pos)) { + if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_unicode((unsigned int)str[*pos]))) { + /* left only: compensate for index/change in direction */ + if ((pos_orig - (*pos)) >= 1) { + *pos = pos_prev; + } + break; + } + } + else { + break; + } + } + } + } + else { + BLI_assert(0); + } +} + diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index baedc7ecf25..795dfc9d607 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_string_cursor_utf8.h" #include "BLI_utildefines.h" #include "DNA_curve_types.h" @@ -545,33 +546,6 @@ void ED_text_to_object(bContext *C, Text *text, int split_lines) } /********************** utilities ***************************/ -static short next_word(Curve *cu) -{ - short s; - for (s = cu->pos; ((cu->str[s]) && (cu->str[s] != ' ') && (cu->str[s] != '\n') && - (cu->str[s] != 1) && (cu->str[s] != '\r')); - s++) - { - /* pass */ - } - - return cu->str[s] ? (s + 1) : s; -} - -static short prev_word(Curve *cu) -{ - short s; - - if (cu->pos == 0) return(0); - for (s = cu->pos - 2; ((cu->str[s]) && (cu->str[s] != ' ') && (cu->str[s] != '\n') && - (cu->str[s] != 1) && (cu->str[s] != '\r')); - s--) - { - /* pass */ - } - - return cu->str[s] ? (s + 1) : s; -} static int kill_selection(Object *obedit, int ins) /* 1 == new character */ { @@ -877,16 +851,24 @@ static int move_cursor(bContext *C, int type, int select) break; case PREV_WORD: + { + int pos = cu->pos; if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1; - cu->pos = prev_word(cu); + BLI_str_cursor_step_wchar(ef->textbuf, cu->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true); + cu->pos = pos; cursmove = FO_CURS; break; + } case NEXT_WORD: + { + int pos = cu->pos; if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1; - cu->pos = next_word(cu); + BLI_str_cursor_step_wchar(ef->textbuf, cu->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true); + cu->pos = pos; cursmove = FO_CURS; break; + } case PREV_CHAR: if ((select) && (cu->selstart == 0)) cu->selstart = cu->selend = cu->pos + 1; |