summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:35:35 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:35:35 +0000
commita31be4ce1152ec7f7819c657dffcdb83673a4000 (patch)
tree98adbfff1498cb9d76db56312d7a10b7c9cc98fd
parent76367f6bf1b5b459c9a15faa0cc0ea1dab191c6f (diff)
downloadopenttd-a31be4ce1152ec7f7819c657dffcdb83673a4000.tar.xz
(svn r25654) -Fix: Improve character and word deletion for CJK languages and complex scripts.
-rw-r--r--src/textbuf.cpp120
-rw-r--r--src/textbuf_type.h2
2 files changed, 44 insertions, 78 deletions
diff --git a/src/textbuf.cpp b/src/textbuf.cpp
index 9a307058f..c7071565a 100644
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -43,100 +43,68 @@ bool Textbuf::CanDelChar(bool backspace)
}
/**
- * Get the next character that will be removed by DelChar.
- * @param backspace if set, delete the character before the caret,
- * otherwise, delete the character after it.
- * @return the next character that will be removed by DelChar.
- * @warning You should ensure Textbuf::CanDelChar returns true before calling this function.
+ * Delete a character from a textbuffer, either with 'Delete' or 'Backspace'
+ * The character is delete from the position the caret is at
+ * @param keycode Type of deletion, either WKC_BACKSPACE or WKC_DELETE
+ * @return Return true on successful change of Textbuf, or false otherwise
*/
-WChar Textbuf::GetNextDelChar(bool backspace)
+bool Textbuf::DeleteChar(uint16 keycode)
{
- assert(this->CanDelChar(backspace));
+ bool word = (keycode & WKC_CTRL) != 0;
- const char *s;
- if (backspace) {
- s = Utf8PrevChar(this->buf + this->caretpos);
- } else {
- s = this->buf + this->caretpos;
- }
+ keycode &= ~WKC_SPECIAL_KEYS;
+ if (keycode != WKC_BACKSPACE && keycode != WKC_DELETE) return false;
- WChar c;
- Utf8Decode(&c, s);
- return c;
-}
+ bool backspace = keycode == WKC_BACKSPACE;
-/**
- * Delete a character at the caret position in a text buf.
- * @param backspace if set, delete the character before the caret,
- * else delete the character after it.
- * @warning You should ensure Textbuf::CanDelChar returns true before calling this function.
- */
-void Textbuf::DelChar(bool backspace)
-{
- assert(this->CanDelChar(backspace));
+ if (!CanDelChar(backspace)) return false;
- WChar c;
char *s = this->buf + this->caretpos;
-
- if (backspace) s = Utf8PrevChar(s);
-
- uint16 len = (uint16)Utf8Decode(&c, s);
+ uint16 len = 0;
+
+ if (word) {
+ /* Delete a complete word. */
+ if (backspace) {
+ /* Delete whitespace and word in front of the caret. */
+ len = this->caretpos - (uint16)this->char_iter->Prev(StringIterator::ITER_WORD);
+ s -= len;
+ } else {
+ /* Delete word and following whitespace following the caret. */
+ len = (uint16)this->char_iter->Next(StringIterator::ITER_WORD) - this->caretpos;
+ }
+ /* Update character count. */
+ for (const char *ss = s; ss < s + len; Utf8Consume(&ss)) {
+ this->chars--;
+ }
+ } else {
+ /* Delete a single character. */
+ if (backspace) {
+ /* Delete the last code point in front of the caret. */
+ s = Utf8PrevChar(s);
+ WChar c;
+ len = (uint16)Utf8Decode(&c, s);
+ this->chars--;
+ } else {
+ /* Delete the complete character following the caret. */
+ len = (uint16)this->char_iter->Next(StringIterator::ITER_CHARACTER) - this->caretpos;
+ /* Update character count. */
+ for (const char *ss = s; ss < s + len; Utf8Consume(&ss)) {
+ this->chars--;
+ }
+ }
+ }
/* Move the remaining characters over the marker */
memmove(s, s + len, this->bytes - (s - this->buf) - len);
this->bytes -= len;
- this->chars--;
if (backspace) this->caretpos -= len;
this->UpdateStringIter();
this->UpdateWidth();
this->UpdateCaretPosition();
-}
-/**
- * Delete a character from a textbuffer, either with 'Delete' or 'Backspace'
- * The character is delete from the position the caret is at
- * @param keycode Type of deletion, either WKC_BACKSPACE or WKC_DELETE
- * @return Return true on successful change of Textbuf, or false otherwise
- */
-bool Textbuf::DeleteChar(uint16 keycode)
-{
- if (keycode == WKC_BACKSPACE || keycode == WKC_DELETE) {
- bool backspace = keycode == WKC_BACKSPACE;
- if (CanDelChar(backspace)) {
- this->DelChar(backspace);
- return true;
- }
- return false;
- }
-
- if (keycode == (WKC_CTRL | WKC_BACKSPACE) || keycode == (WKC_CTRL | WKC_DELETE)) {
- bool backspace = keycode == (WKC_CTRL | WKC_BACKSPACE);
-
- if (!CanDelChar(backspace)) return false;
- WChar c = this->GetNextDelChar(backspace);
-
- /* Backspace: Delete left whitespaces.
- * Delete: Delete right word.
- */
- while (backspace ? IsWhitespace(c) : !IsWhitespace(c)) {
- this->DelChar(backspace);
- if (!this->CanDelChar(backspace)) return true;
- c = this->GetNextDelChar(backspace);
- }
- /* Backspace: Delete left word.
- * Delete: Delete right whitespaces.
- */
- while (backspace ? !IsWhitespace(c) : IsWhitespace(c)) {
- this->DelChar(backspace);
- if (!this->CanDelChar(backspace)) return true;
- c = this->GetNextDelChar(backspace);
- }
- return true;
- }
-
- return false;
+ return true;
}
/**
diff --git a/src/textbuf_type.h b/src/textbuf_type.h
index f5100249c..4d1a926fb 100644
--- a/src/textbuf_type.h
+++ b/src/textbuf_type.h
@@ -65,8 +65,6 @@ private:
StringIterator *char_iter;
bool CanDelChar(bool backspace);
- WChar GetNextDelChar(bool backspace);
- void DelChar(bool backspace);
void UpdateStringIter();
void UpdateWidth();