[Bf-blender-cvs] [d0ec1b1] master: Fix for 3d text ctrl+arrow keys failing for multi-byte characters.

Campbell Barton noreply at git.blender.org
Sun Dec 29 06:55:14 CET 2013


Commit: d0ec1b1caa7ad7048bcd23f58a0b26e548c8c551
Author: Campbell Barton
Date:   Sun Dec 29 16:54:43 2013 +1100
https://developer.blender.org/rBd0ec1b1caa7ad7048bcd23f58a0b26e548c8c551

Fix for 3d text ctrl+arrow keys failing for multi-byte characters.

===================================================================

M	source/blender/blenlib/BLI_string_cursor_utf8.h
M	source/blender/blenlib/intern/string_cursor_utf8.c
M	source/blender/editors/curve/editfont.c

===================================================================

diff --git a/source/blender/blenlib/BLI_string_cursor_utf8.h b/source/blender/blenlib/BLI_string_cursor_utf8.h
index 04d9df2..4591066 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 0a579fa..2d2c03a 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 baedc7e..795dfc9 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;




More information about the Bf-blender-cvs mailing list