Mercurial > hg > openttd
changeset 20234:54db6b11351b draft
-Fix: [Win32] Handle Unicode characters from outside the BMP correctly.
author | Michael Lutz <michi@icosahedron.de> |
---|---|
date | Sun, 24 Mar 2013 01:00:46 +0100 (2013-03-24) |
parents | 98cec258f8e1 |
children | 45ee665489d3 |
files | src/string_func.h src/video/win32_v.cpp |
diffstat | 2 files changed, 52 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/string_func.h +++ b/src/string_func.h @@ -190,6 +190,38 @@ return c == 0x0020 /* SPACE */ || c == 0x3000; /* IDEOGRAPHIC SPACE */ } +/** + * Is the given character a lead surrogate code point? + * @param c The character to test. + * @return True if the character is a lead surrogate code point. + */ +static inline bool IsUTF16LeadSurrogate(uint c) +{ + return c >= 0xD800 && c <= 0xDBFF; +} + +/** + * Is the given character a lead surrogate code point? + * @param c The character to test. + * @return True if the character is a lead surrogate code point. + */ +static inline bool IsUTF16TrailSurrogate(uint c) +{ + return c >= 0xDC00 && c <= 0xDFFF; +} + +/** + * Convert an UTF-16 surrogate pair to the corresponding Unicode character. + * @param lead Lead surrogate code point. + * @param trail Trail surrogate code point. + * @return Decoded Unicode character. + */ +static inline WChar DecodeUTF16Surrogate(uint lead, uint trail) +{ + return 0x10000 + ((lead - 0xD800) << 10) | (trail - 0xDC00); +} + + /* Needed for NetBSD version (so feature) testing */ #if defined(__NetBSD__) || defined(__FreeBSD__) #include <sys/param.h>
--- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -431,12 +431,31 @@ } /** Forward key presses to the window system. */ -static LRESULT HandleCharMsg(uint keycode, uint charcode) +static LRESULT HandleCharMsg(uint keycode, WChar charcode) { #if !defined(UNICODE) wchar_t w; int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1); charcode = len == 1 ? w : 0; +#else + static WChar prev_char = 0; + + /* Did we get an lead surrogate? If yes, store and exit. */ + if (IsUTF16LeadSurrogate(charcode)) { + if (prev_char != 0) DEBUG(driver, 1, "Got two UTF-16 lead surrogates, dropping the first one"); + prev_char = charcode; + return 0; + } + + /* Stored lead surrogate and incoming trail surrogate? Combine and forward to input handling. */ + if (prev_char != 0) { + if (IsUTF16TrailSurrogate(charcode)) { + charcode = DecodeUTF16Surrogate(prev_char, charcode); + } else { + DEBUG(driver, 1, "Got an UTF-16 lead surrogate without a trail surrogate, dropping the lead surrogate"); + } + } + prev_char = 0; #endif /* UNICODE */ HandleKeypress(keycode, charcode);