diff options
-rw-r--r-- | src/UniConversion.cxx | 6 | ||||
-rw-r--r-- | src/UniConversion.h | 6 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 35 |
3 files changed, 25 insertions, 22 deletions
diff --git a/src/UniConversion.cxx b/src/UniConversion.cxx index dea069843..0d69d9969 100644 --- a/src/UniConversion.cxx +++ b/src/UniConversion.cxx @@ -17,7 +17,6 @@ using namespace Scintilla; namespace Scintilla { #endif -enum { SURROGATE_LEAD_FIRST = 0xD800 }; enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; enum { SURROGATE_TRAIL_LAST = 0xDFFF }; enum { SUPPLEMENTAL_PLANE_FIRST = 0x10000 }; @@ -43,7 +42,7 @@ unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { } void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) { - int k = 0; + unsigned int k = 0; for (unsigned int i = 0; i < tlen && uptr[i];) { unsigned int uch = uptr[i]; if (uch < 0x80) { @@ -67,7 +66,8 @@ void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned } i++; } - putf[len] = '\0'; + if (k < len) + putf[k] = '\0'; } unsigned int UTF8CharLength(unsigned char ch) { diff --git a/src/UniConversion.h b/src/UniConversion.h index 8c7ac4a27..08898cac3 100644 --- a/src/UniConversion.h +++ b/src/UniConversion.h @@ -55,6 +55,12 @@ inline bool UTF8IsNEL(const unsigned char *us) { return (us[0] == 0xc2) && (us[1] == 0x85); } +enum { SURROGATE_LEAD_FIRST = 0xD800 }; +enum { SURROGATE_LEAD_LAST = 0xDBFF }; +inline unsigned int UTF16CharLength(wchar_t uch) { + return ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_LEAD_LAST)) ? 2 : 1; +} + #ifdef SCI_NAMESPACE } #endif diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index f4e43bb54..95caf83ad 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -979,22 +979,20 @@ sptr_t ScintillaWin::HandleCompositionInline(uptr_t, sptr_t lParam) { bool tmpRecordingMacro = recordingMacro; recordingMacro = false; - for (unsigned int i = 0; i < wcsLen; i++) { - wchar_t uniChar[1] = { 0 }; + for (size_t i = 0; i < wcsLen; ) { + const size_t ucWidth = UTF16CharLength(wcs[i]); + const std::wstring uniChar(wcs+i, ucWidth); char oneChar[UTF8MaxBytes + 1] = "\0\0\0\0"; // Maximum 4 bytes in utf8 unsigned int oneCharLen = 0; - uniChar[0] = wcs[i]; - if (IsUnicodeMode()) { - oneCharLen = UTF8Length(uniChar, 1); - UTF8FromUTF16(uniChar, 1, oneChar, oneCharLen); - oneChar[oneCharLen] = '\0'; + oneCharLen = UTF8Length(uniChar.c_str(), static_cast<unsigned int>(uniChar.length())); + UTF8FromUTF16(uniChar.c_str(), static_cast<unsigned int>(uniChar.length()), oneChar, oneCharLen); } else { oneCharLen = ::WideCharToMultiByte(InputCodePage(), 0, - uniChar, 1, oneChar, sizeof(oneChar)-1, 0, 0); - oneChar[oneCharLen] = '\0'; + uniChar.c_str(), static_cast<unsigned int>(uniChar.length()), oneChar, sizeof(oneChar)-1, 0, 0); } + oneChar[oneCharLen] = '\0'; // Display a character. AddCharUTF(oneChar, oneCharLen); @@ -1018,6 +1016,7 @@ sptr_t ScintillaWin::HandleCompositionInline(uptr_t, sptr_t lParam) { break; } DrawImeIndicator(indicator, oneCharLen); + i += ucWidth; } recordingMacro = tmpRecordingMacro; @@ -1032,23 +1031,22 @@ sptr_t ScintillaWin::HandleCompositionInline(uptr_t, sptr_t lParam) { (hIMC, GCS_RESULTSTR, wcs, maxLenInputIME); unsigned int wcsLen = bytes / 2; - for (unsigned int i = 0; i < wcsLen; i++) { - wchar_t uniChar[1] = { 0 }; + for (size_t i = 0; i < wcsLen;) { + const size_t ucWidth = UTF16CharLength(wcs[i]); + const std::wstring uniChar(wcs+i, ucWidth); char oneChar[UTF8MaxBytes+1] = "\0\0\0\0"; // Maximum 4 bytes in UTF-8. unsigned int oneCharLen = 0; - uniChar[0] = wcs[i]; - if (IsUnicodeMode()) { - oneCharLen = UTF8Length(uniChar, 1); - UTF8FromUTF16(uniChar, 1, oneChar, oneCharLen); - oneChar[oneCharLen] = '\0'; + oneCharLen = UTF8Length(uniChar.c_str(), static_cast<unsigned int>(uniChar.length())); + UTF8FromUTF16(uniChar.c_str(), static_cast<unsigned int>(uniChar.length()), oneChar, oneCharLen); } else { oneCharLen = ::WideCharToMultiByte(InputCodePage(), 0, - uniChar, 1, oneChar, sizeof(oneChar)-1, 0, 0); - oneChar[oneCharLen] = '\0'; + uniChar.c_str(), static_cast<unsigned int>(uniChar.length()), oneChar, sizeof(oneChar)-1, 0, 0); } + oneChar[oneCharLen] = '\0'; AddCharUTF(oneChar, oneCharLen); + i += ucWidth; } } SetCandidateWindowPos(); @@ -2224,7 +2222,6 @@ void ScintillaWin::Paste() { unsigned int mlen = UTF8Length(&uptr[0], ulen); std::vector<char> putf(mlen+1); - // CP_UTF8 not available on Windows 95, so use UTF8FromUTF16() UTF8FromUTF16(&uptr[0], ulen, &putf[0], mlen); InsertPasteShape(&putf[0], mlen, pasteShape); |