From 00781668ce936db58681e2b49d635857e5b2d25e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 7 Mar 2012 15:55:12 +0000 Subject: Unify string stepping delimiter code for text buttons, text editor and console (all had duplicate code). this is also a step toward the console working with utf8 though many todo's remain. --- source/blender/blenlib/intern/string_cursor_utf8.c | 181 +++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 source/blender/blenlib/intern/string_cursor_utf8.c (limited to 'source/blender/blenlib/intern/string_cursor_utf8.c') diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c new file mode 100644 index 00000000000..6dc88ec00a4 --- /dev/null +++ b/source/blender/blenlib/intern/string_cursor_utf8.c @@ -0,0 +1,181 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Campbell Barton. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/blenlib/intern/string_cursor_utf8.c + * \ingroup bli + */ + +#include +#include + +#include "BLI_utildefines.h" +#include "BLI_string_utf8.h" + +#include "BLI_string_cursor_utf8.h" /* own include */ + + +/* return 1 if char ch is special character, otherwise return 0 */ +static strCursorDelimType test_special_char(const char ch) +{ + /* TODO - use BLI_str_utf8_as_unicode rather then assuming ascii */ + + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch == '_') /* not quite correct but allow for python, could become configurable */ + ) + { + return STRCUR_DELIM_ALPHA; + } + + switch (ch) { + case ',': + case '.': + return STRCUR_DELIM_PUNCT; + + case '{': + case '}': + case '[': + case ']': + case '(': + case ')': + return STRCUR_DELIM_BRACE; + + case '+': + case '-': + case '=': + case '~': + case '%': + case '/': + case '<': + case '>': + case '^': + case '*': + case '&': + return STRCUR_DELIM_OPERATOR; + + case '\'': + case '\"': // " - an extra closing one for Aligorith's text editor + return STRCUR_DELIM_QUOTE; + + case ' ': + return STRCUR_DELIM_WHITESPACE; + + case '\\': + case '!': + case '@': + case '#': + case '$': + case ':': + case ';': + case '?': + /* case '_': */ /* special case, for python */ + return STRCUR_DELIM_OTHER; + + default: + break; + } + return STRCUR_DELIM_NONE; +} + +int BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, short *pos) +{ + const char *str_end= str + (maxlen + 1); + const char *str_pos= str + (*pos); + const char *str_next= BLI_str_find_next_char_utf8(str_pos, str_end); + if (str_next) { + (*pos) += (str_next - str_pos); + if((*pos) > maxlen) (*pos)= maxlen; + return TRUE; + } + + return FALSE; +} + +int BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), short *pos) +{ + if((*pos) > 0) { + const char *str_pos= str + (*pos); + const char *str_prev= BLI_str_find_prev_char_utf8(str, str_pos); + if (str_prev) { + (*pos) -= (str_pos - str_prev); + return TRUE; + } + } + + return FALSE; +} + +void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, + short *pos, strCursorJumpDirection direction, + strCursorJumpType jump) +{ + const short pos_prev= *pos; + + if (direction == STRCUR_DIR_NEXT) { + BLI_str_cursor_step_next_utf8(str, maxlen, pos); + + if (jump != STRCUR_JUMP_NONE) { + const strCursorDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : STRCUR_DELIM_NONE; + /* jump between special characters (/,\,_,-, etc.), + * look at function test_special_char() 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) && (is_special != test_special_char(str[(*pos)]))) break; + } + else { + break; /* unlikely but just incase */ + } + } + } + } + else if (direction == STRCUR_DIR_PREV) { + BLI_str_cursor_step_prev_utf8(str, maxlen, pos); + + if(jump != STRCUR_JUMP_NONE) { + const strCursorDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : STRCUR_DELIM_NONE; + /* jump between special characters (/,\,_,-, etc.), + * look at function test_special_char() for complete + * list of special character, ctr -> */ + while ((*pos) > 0) { + if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) { + if ((jump != STRCUR_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break; + } + else { + break; + } + } + + /* left only: compensate for index/change in direction */ + if (((*pos) != 0) && ABS(pos_prev - (*pos)) >= 1) { + BLI_str_cursor_step_next_utf8(str, maxlen, pos); + } + } + } + else { + BLI_assert(0); + } +} -- cgit v1.2.3