diff options
author | michi_cc <michi_cc@openttd.org> | 2013-08-05 20:35:23 +0000 |
---|---|---|
committer | michi_cc <michi_cc@openttd.org> | 2013-08-05 20:35:23 +0000 |
commit | 33f3cf3a5daeaf9e6e5b5414696f93676249bc41 (patch) | |
tree | 9de7c6fec9a311f66a3e598cdb3286cfdd1cadff /src/textbuf.cpp | |
parent | 9d7ec75fc0a396b47f91a5f7ec4bea59024fea5f (diff) | |
download | openttd-33f3cf3a5daeaf9e6e5b5414696f93676249bc41.tar.xz |
(svn r25651) -Fix: Textbuf caret rendering for complex scripts (e.g. Tamil).
Diffstat (limited to 'src/textbuf.cpp')
-rw-r--r-- | src/textbuf.cpp | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/textbuf.cpp b/src/textbuf.cpp index e84b14e7b..84aa7157e 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -81,18 +81,17 @@ void Textbuf::DelChar(bool backspace) if (backspace) s = Utf8PrevChar(s); uint16 len = (uint16)Utf8Decode(&c, s); - uint width = GetCharacterWidth(FS_NORMAL, c); - - this->pixels -= width; - if (backspace) { - this->caretpos -= len; - this->caretxoffs -= width; - } /* Move the remaining characters over the marker */ memmove(s, s + len, this->bytes - (s - this->buf) - len); this->bytes -= len; this->chars--; + + this->UpdateWidth(); + if (backspace) { + this->caretpos -= len; + this->UpdateCaretPosition(); + } } /** @@ -159,17 +158,16 @@ void Textbuf::DeleteAll() */ bool Textbuf::InsertChar(WChar key) { - const byte charwidth = GetCharacterWidth(FS_NORMAL, key); uint16 len = (uint16)Utf8CharLen(key); if (this->bytes + len <= this->max_bytes && this->chars + 1 <= this->max_chars) { memmove(this->buf + this->caretpos + len, this->buf + this->caretpos, this->bytes - this->caretpos); Utf8Encode(this->buf + this->caretpos, key); this->chars++; this->bytes += len; - this->pixels += charwidth; + this->UpdateWidth(); this->caretpos += len; - this->caretxoffs += charwidth; + this->UpdateCaretPosition(); return true; } return false; @@ -187,7 +185,7 @@ bool Textbuf::InsertClipboard() if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false; - uint16 pixels = 0, bytes = 0, chars = 0; + uint16 bytes = 0, chars = 0; WChar c; for (const char *ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) { if (!IsValidChar(c, this->afilter)) break; @@ -196,9 +194,6 @@ bool Textbuf::InsertClipboard() if (this->bytes + bytes + len > this->max_bytes) break; if (this->chars + chars + 1 > this->max_chars) break; - byte char_pixels = GetCharacterWidth(FS_NORMAL, c); - - pixels += char_pixels; bytes += len; chars++; } @@ -207,8 +202,6 @@ bool Textbuf::InsertClipboard() memmove(this->buf + this->caretpos + bytes, this->buf + this->caretpos, this->bytes - this->caretpos); memcpy(this->buf + this->caretpos, utf8_buf, bytes); - this->pixels += pixels; - this->caretxoffs += pixels; this->bytes += bytes; this->chars += chars; @@ -217,6 +210,9 @@ bool Textbuf::InsertClipboard() assert(this->chars <= this->max_chars); this->buf[this->bytes - 1] = '\0'; // terminating zero + this->UpdateWidth(); + this->UpdateCaretPosition(); + return true; } @@ -242,7 +238,7 @@ WChar Textbuf::MoveCaretLeft() const char *s = Utf8PrevChar(this->buf + this->caretpos); Utf8Decode(&c, s); this->caretpos = s - this->buf; - this->caretxoffs -= GetCharacterWidth(FS_NORMAL, c); + this->UpdateCaretPosition(); return c; } @@ -267,12 +263,24 @@ WChar Textbuf::MoveCaretRight() WChar c; this->caretpos += (uint16)Utf8Decode(&c, this->buf + this->caretpos); - this->caretxoffs += GetCharacterWidth(FS_NORMAL, c); + this->UpdateCaretPosition(); Utf8Decode(&c, this->buf + this->caretpos); return c; } +/** Update pixel width of the text. */ +void Textbuf::UpdateWidth() +{ + this->pixels = GetStringBoundingBox(this->buf, FS_NORMAL).width; +} + +/** Update pixel position of the caret. */ +void Textbuf::UpdateCaretPosition() +{ + this->caretxoffs = this->chars > 1 ? GetCharPosInString(this->buf, this->buf + this->caretpos, FS_NORMAL).x : 0; +} + /** * Handle text navigation with arrow keys left/right. * This defines where the caret will blink and the next character interaction will occur @@ -336,12 +344,12 @@ bool Textbuf::MovePos(uint16 keycode) case WKC_HOME: this->caretpos = 0; - this->caretxoffs = 0; + this->UpdateCaretPosition(); return true; case WKC_END: this->caretpos = this->bytes - 1; - this->caretxoffs = this->pixels; + this->UpdateCaretPosition(); return true; default: @@ -418,21 +426,20 @@ void Textbuf::UpdateSize() { const char *buf = this->buf; - this->pixels = 0; this->chars = this->bytes = 1; // terminating zero WChar c; while ((c = Utf8Consume(&buf)) != '\0') { - this->pixels += GetCharacterWidth(FS_NORMAL, c); this->bytes += Utf8CharLen(c); this->chars++; } - assert(this->bytes <= this->max_bytes); assert(this->chars <= this->max_chars); this->caretpos = this->bytes - 1; - this->caretxoffs = this->pixels; + this->UpdateWidth(); + + this->UpdateCaretPosition(); } /** |