aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/ScintillaWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/ScintillaWin.cxx')
-rw-r--r--win32/ScintillaWin.cxx73
1 files changed, 48 insertions, 25 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index d0ea62a31..92df2aad6 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -100,6 +100,14 @@
#define UNICODE_NOCHAR 0xFFFF
#endif
+#ifndef IS_HIGH_SURROGATE
+#define IS_HIGH_SURROGATE(x) ((x) >= SURROGATE_LEAD_FIRST && (x) <= SURROGATE_LEAD_LAST)
+#endif
+
+#ifndef IS_LOW_SURROGATE
+#define IS_LOW_SURROGATE(x) ((x) >= SURROGATE_TRAIL_FIRST && (x) <= SURROGATE_TRAIL_LAST)
+#endif
+
#ifndef MK_ALT
#define MK_ALT 32
#endif
@@ -212,6 +220,7 @@ class ScintillaWin :
public ScintillaBase {
bool lastKeyDownConsumed;
+ wchar_t lastHighSurrogateChar;
bool capturedMouse;
bool trackedMouseLeave;
@@ -269,6 +278,7 @@ class ScintillaWin :
virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
int TargetAsUTF8(char *text);
+ void AddCharUTF16(wchar_t const *wcs, unsigned int wclen);
int EncodedFromUTF8(char *utf8, char *encoded) const;
sptr_t WndPaint(uptr_t wParam);
@@ -383,6 +393,7 @@ ATOM ScintillaWin::callClassAtom = 0;
ScintillaWin::ScintillaWin(HWND hwnd) {
lastKeyDownConsumed = false;
+ lastHighSurrogateChar = 0;
capturedMouse = false;
trackedMouseLeave = false;
@@ -729,6 +740,26 @@ int ScintillaWin::EncodedFromUTF8(char *utf8, char *encoded) const {
}
}
+// Add one character from a UTF-16 string, by converting to either UTF-8 or
+// the current codepage. Code is similar to HandleCompositionWindowed().
+void ScintillaWin::AddCharUTF16(wchar_t const *wcs, unsigned int wclen) {
+ if (IsUnicodeMode()) {
+ char utfval[maxLenInputIME * 3];
+ unsigned int len = UTF8Length(wcs, wclen);
+ UTF8FromUTF16(wcs, wclen, utfval, len);
+ utfval[len] = '\0';
+ AddCharUTF(utfval, len);
+ } else {
+ UINT cpDest = CodePageOfDocument();
+ char inBufferCP[maxLenInputIME * 2];
+ int size = ::WideCharToMultiByte(cpDest,
+ 0, wcs, wclen, inBufferCP, sizeof(inBufferCP) - 1, 0, 0);
+ for (int i=0; i<size; i++) {
+ AddChar(inBufferCP[i]);
+ }
+ }
+}
+
sptr_t ScintillaWin::WndPaint(uptr_t wParam) {
//ElapsedTime et;
@@ -1414,40 +1445,32 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
case WM_CHAR:
if (((wParam >= 128) || !iscntrl(static_cast<int>(wParam))) || !lastKeyDownConsumed) {
- wchar_t wcs[2] = {static_cast<wchar_t>(wParam), 0};
- if (IsUnicodeMode()) {
- // For a wide character version of the window:
- char utfval[UTF8MaxBytes];
- unsigned int len = UTF8Length(wcs, 1);
- UTF8FromUTF16(wcs, 1, utfval, len);
- AddCharUTF(utfval, len);
- } else {
- UINT cpDest = CodePageOfDocument();
- char inBufferCP[20];
- int size = ::WideCharToMultiByte(cpDest,
- 0, wcs, 1, inBufferCP, sizeof(inBufferCP) - 1, 0, 0);
- inBufferCP[size] = '\0';
- AddCharUTF(inBufferCP, size);
+ wchar_t wcs[3] = {static_cast<wchar_t>(wParam), 0};
+ unsigned int wclen = 1;
+ if (IS_HIGH_SURROGATE(wcs[0])) {
+ // If this is a high surrogate character, we need a second one
+ lastHighSurrogateChar = wcs[0];
+ return 0;
+ } else if (IS_LOW_SURROGATE(wcs[0])) {
+ wcs[1] = wcs[0];
+ wcs[0] = lastHighSurrogateChar;
+ lastHighSurrogateChar = 0;
+ wclen = 2;
}
+ AddCharUTF16(wcs, wclen);
}
return 0;
case WM_UNICHAR:
if (wParam == UNICODE_NOCHAR) {
- return IsUnicodeMode() ? 1 : 0;
+ return TRUE;
} else if (lastKeyDownConsumed) {
return 1;
} else {
- if (IsUnicodeMode()) {
- char utfval[UTF8MaxBytes];
- wchar_t wcs[2] = {static_cast<wchar_t>(wParam), 0};
- unsigned int len = UTF8Length(wcs, 1);
- UTF8FromUTF16(wcs, 1, utfval, len);
- AddCharUTF(utfval, len);
- return 1;
- } else {
- return 0;
- }
+ wchar_t wcs[3] = {0};
+ unsigned int wclen = UTF16FromUTF32Character(wParam, wcs);
+ AddCharUTF16(wcs, wclen);
+ return FALSE;
}
case WM_SYSKEYDOWN: