diff options
author | Neil <nyamatongwe@gmail.com> | 2015-03-12 09:58:25 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2015-03-12 09:58:25 +1100 |
commit | 3aff75b4830ea69da17e87fdfe11c4df5a4d884d (patch) | |
tree | 0f168a9c377019f01bc208c9c6c25f90818e70ab /win32 | |
parent | 2cf0d3e80236e089e06a5033575f58ccc090a262 (diff) | |
download | scintilla-mirror-3aff75b4830ea69da17e87fdfe11c4df5a4d884d.tar.gz |
More efficient conversion to Hangul.
From johnsonj.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/HanjaDic.cxx | 40 | ||||
-rw-r--r-- | win32/HanjaDic.h | 2 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 64 |
3 files changed, 47 insertions, 59 deletions
diff --git a/win32/HanjaDic.cxx b/win32/HanjaDic.cxx index 94fc10b06..3a86ad313 100644 --- a/win32/HanjaDic.cxx +++ b/win32/HanjaDic.cxx @@ -97,26 +97,30 @@ public: } }; -int GetHangulOfHanja(int hanjaChar) { - // Convert hanja character to hangul one. - int hangulChar = -1; // If fails, return -1. +int GetHangulOfHanja(wchar_t *inout) { + // Convert every hanja to hangul. + // Return the number of characters converted. + int changed = 0; HanjaDic dict; - if (!dict.HJdictAvailable() || !dict.IsHanja(hanjaChar)) { - return hangulChar; - } - wchar_t convHnja[UTF8MaxBytes] = {0}; - convHnja[0] = static_cast<wchar_t>(hanjaChar); - - BSTR bstrHangul = SysAllocString(NULL); - BSTR bstrHanja = SysAllocString(convHnja); - HRESULT hr = dict.HJinterface->HanjaToHangul(bstrHanja, &bstrHangul); - if (SUCCEEDED(hr)) { - wchar_t wHangul = static_cast<wchar_t *>(bstrHangul)[0]; - hangulChar = static_cast<int>(wHangul); + if (dict.HJdictAvailable()) { + const size_t len = wcslen(inout); + wchar_t conv[UTF8MaxBytes] = {0}; + BSTR bstrHangul = SysAllocString(conv); + for (size_t i=0; i<len; i++) { + if (dict.IsHanja(static_cast<int>(inout[i]))) { // Pass hanja only! + conv[0] = inout[i]; + BSTR bstrHanja = SysAllocString(conv); + HRESULT hr = dict.HJinterface->HanjaToHangul(bstrHanja, &bstrHangul); + if (SUCCEEDED(hr)) { + inout[i] = static_cast<wchar_t>(bstrHangul[0]); + changed += 1; + } + SysFreeString(bstrHanja); + } + } + SysFreeString(bstrHangul); } - SysFreeString(bstrHangul); - SysFreeString(bstrHanja); - return hangulChar; + return changed; } } diff --git a/win32/HanjaDic.h b/win32/HanjaDic.h index 5ba61f661..d58735dca 100644 --- a/win32/HanjaDic.h +++ b/win32/HanjaDic.h @@ -15,7 +15,7 @@ namespace Scintilla { namespace HanjaDict { -int GetHangulOfHanja(int character); +int GetHangulOfHanja(wchar_t *inout); } diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 95caf83ad..2a26eee04 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -254,7 +254,7 @@ class ScintillaWin : void SetCandidateWindowPos(); void BytesToUniChar(const char *bytes, const int bytesLen, wchar_t *character, int &charsLen); void UniCharToBytes(const wchar_t *character, const int charsLen, char *bytes, int &bytesLen); - void RangeToHangul(int uniStrLen); + void SelectionToHangul(); void EscapeHanja(); void ToggleHanja(); @@ -832,40 +832,32 @@ void ScintillaWin::UniCharToBytes(const wchar_t *characters, const int charsLen, } } -void ScintillaWin::RangeToHangul(int uniStrLen) { - // Convert every hanja to hangul from current position to the length uniStrLen. - // Even if not coverted, the caret should advance by 1 character. - pdoc->BeginUndoAction(); - for (int i=0; i<uniStrLen; i++) { - unsigned int const safeLength = UTF8MaxBytes+1; +void ScintillaWin::SelectionToHangul() { + // Convert every hanja to hangul within the main range. + const int selStart = sel.RangeMain().Start().Position(); + const int documentStrLen = sel.RangeMain().Length(); + const int selEnd = selStart + documentStrLen; + const int utf16Len = pdoc->CountUTF16(selStart, selEnd); - int currentPos = CurrentPosition(); - int oneCharLen = pdoc->LenChar(currentPos); + if (utf16Len > 0) { + std::vector<wchar_t> uniStr(utf16Len+1, '\0'); + std::vector<char> documentStr(documentStrLen+1, '\0'); - if (oneCharLen > 1) { - wchar_t uniChar[safeLength] = { 0 }; - int uniCharLen = 1; - char oneChar[safeLength] = "\0\0\0\0"; - pdoc->GetCharRange(oneChar, currentPos, oneCharLen); + pdoc->GetCharRange(&documentStr[0], selStart, documentStrLen); - BytesToUniChar(oneChar, oneCharLen, uniChar, uniCharLen); + int countedUniLen = 0; + int countedDocLen = 0; + BytesToUniChar(&documentStr[0], documentStrLen, &uniStr[0], countedUniLen); + int converted = HanjaDict::GetHangulOfHanja(&uniStr[0]); + UniCharToBytes(&uniStr[0], countedUniLen, &documentStr[0], countedDocLen); - int hangul = HanjaDict::GetHangulOfHanja(uniChar[0]); - if (hangul > 0) { - uniChar[0] = static_cast<wchar_t>(hangul); - - UniCharToBytes(uniChar, uniCharLen, oneChar, oneCharLen); - - pdoc->DelChar(currentPos); - InsertPaste(oneChar, oneCharLen); - } else { - MoveImeCarets(oneCharLen); - } - } else { - MoveImeCarets(oneCharLen); + if (converted > 0) { + pdoc->BeginUndoAction(); + ClearSelection(); + InsertPaste(&documentStr[0], countedDocLen); + pdoc->EndUndoAction(); } } - pdoc->EndUndoAction(); } void ScintillaWin::EscapeHanja() { @@ -914,18 +906,10 @@ void ScintillaWin::ToggleHanja() { return; // Do not allow multi carets. } - int selStart = sel.RangeMain().Start().Position(); - int documentStrLen = sel.RangeMain().Length(); - int selEnd = selStart + documentStrLen; - int uniStrLen = pdoc->CountCharacters(selStart, selEnd); - - // Convert one by one from the start of main range. - SetSelection(selStart, selStart); - - if (uniStrLen > 0) { - RangeToHangul(uniStrLen); - } else { + if (sel.Empty()) { EscapeHanja(); + } else { + SelectionToHangul(); } } |