aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2015-03-12 09:58:25 +1100
committerNeil <nyamatongwe@gmail.com>2015-03-12 09:58:25 +1100
commit3aff75b4830ea69da17e87fdfe11c4df5a4d884d (patch)
tree0f168a9c377019f01bc208c9c6c25f90818e70ab
parent2cf0d3e80236e089e06a5033575f58ccc090a262 (diff)
downloadscintilla-mirror-3aff75b4830ea69da17e87fdfe11c4df5a4d884d.tar.gz
More efficient conversion to Hangul.
From johnsonj.
-rw-r--r--win32/HanjaDic.cxx40
-rw-r--r--win32/HanjaDic.h2
-rw-r--r--win32/ScintillaWin.cxx64
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();
}
}