From a31be4ce1152ec7f7819c657dffcdb83673a4000 Mon Sep 17 00:00:00 2001 From: michi_cc Date: Mon, 5 Aug 2013 20:35:35 +0000 Subject: (svn r25654) -Fix: Improve character and word deletion for CJK languages and complex scripts. --- src/textbuf.cpp | 120 +++++++++++++++++++++----------------------------------- 1 file changed, 44 insertions(+), 76 deletions(-) (limited to 'src/textbuf.cpp') 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; } /** -- cgit v1.2.3-54-g00ecf