(svn r9003) -Codechange: Introduce a function Utf8PrevCharLen that finds the starting character of an UTF-8 sequence from a given position and returns the length to the first UTF-8 encoding byte of that sequence.
authorDarkvater
Sun, 04 Mar 2007 00:49:40 +0000
changeset 6211 91567df8ebd6
parent 6210 854d178ace69
child 6212 2bf1ef095cf3
(svn r9003) -Codechange: Introduce a function Utf8PrevCharLen that finds the starting character of an UTF-8 sequence from a given position and returns the length to the first UTF-8 encoding byte of that sequence.
src/misc_gui.cpp
src/string.h
--- a/src/misc_gui.cpp	Sat Mar 03 22:15:37 2007 +0000
+++ b/src/misc_gui.cpp	Sun Mar 04 00:49:40 2007 +0000
@@ -805,11 +805,7 @@
 	uint width;
 	size_t len;
 
-	if (backspace) {
-		do {
-			tb->caretpos--;
-		} while (IsUtf8Part(*(tb->buf + tb->caretpos)));
-	}
+	if (backspace) tb->caretpos -= Utf8PrevCharLen(tb->buf + tb->caretpos);
 
 	len = Utf8Decode(&c, tb->buf + tb->caretpos);
 	width = GetCharacterWidth(FS_NORMAL, c);
@@ -892,10 +888,7 @@
 		if (tb->caretpos != 0) {
 			WChar c;
 
-			do {
-				tb->caretpos--;
-			} while (IsUtf8Part(*(tb->buf + tb->caretpos)));
-
+			tb->caretpos -= Utf8PrevCharLen(tb->buf + tb->caretpos);
 			Utf8Decode(&c, tb->buf + tb->caretpos);
 			tb->caretxoffs -= GetCharacterWidth(FS_NORMAL, c);
 
--- a/src/string.h	Sat Mar 03 22:15:37 2007 +0000
+++ b/src/string.h	Sun Mar 04 00:49:40 2007 +0000
@@ -106,6 +106,28 @@
 	return GB(c, 6, 2) == 2;
 }
 
+/**
+ * Retrieve the (partial) length of the previous UNICODE character
+ * in an UTF-8 encoded string.
+ * @param s char pointer pointing to the first char of the next character
+ * @returns the decoded length in bytes (size) of the UNICODE character
+ * that was just before the one where 's' is pointing to
+ * @note If 's' is not pointing to the first byte of the next UNICODE character
+ * only a partial length of the sequence will be returned.
+ * For example given this sequence: 0xE3 0x85 0x80, 0xE3 0x81 0x9E
+ * 1. 's' is pointing to the second 0xE3, return value is 3
+ * 2. 's' is pointing to 0x80, return value is 2.
+ * So take care with the return values of this function. To get the real length
+ * for an (invalid) sequence, pass the string offset of this function's return
+ * value to Utf8EncodedCharLen() or Utf8Decode()
+ */
+static inline size_t Utf8PrevCharLen(const char *s)
+{
+	size_t len = 1;
+	while (IsUtf8Part(*--s)) len++;
+	return len;
+}
+
 
 static inline bool IsPrintable(WChar c)
 {