aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2015-02-23 10:10:54 +1100
committerNeil <nyamatongwe@gmail.com>2015-02-23 10:10:54 +1100
commitc4c875b860d9a447967b625f67748e962b697652 (patch)
tree58c0712ac5b959bc7ad559a40c84e7eeb1155c64
parentee3a66f0ebaea12c3fd4000a1acffdcc2b93176f (diff)
downloadscintilla-mirror-c4c875b860d9a447967b625f67748e962b697652.tar.gz
Fix non-BMP character entry through the inline IME.
-rw-r--r--src/UniConversion.cxx6
-rw-r--r--src/UniConversion.h6
-rw-r--r--win32/ScintillaWin.cxx35
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);