(svn r25654) -Fix: Improve character and word deletion for CJK languages and complex scripts.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
michi_cc 11 years ago
parent 76367f6bf1
commit a31be4ce11

@ -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;
}
/**

@ -65,8 +65,6 @@ private:
StringIterator *char_iter;
bool CanDelChar(bool backspace);
WChar GetNextDelChar(bool backspace);
void DelChar(bool backspace);
void UpdateStringIter();
void UpdateWidth();

Loading…
Cancel
Save