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); | 
