diff options
Diffstat (limited to 'win32/ScintillaWin.cxx')
-rw-r--r-- | win32/ScintillaWin.cxx | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 570a2bc88..9873b82a4 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -1293,7 +1293,7 @@ void ScintillaWin::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) MAKELPARAM(pt.x, pt.y)); } -class CaseFolderUTF8 : public CaseFolderTable { +class CaseFolderUTF8 : public CaseFolderTable { // Allocate the expandable storage here so that it does not need to be reallocated // for each call to Fold. std::vector<wchar_t> utf16Mixed; @@ -1337,13 +1337,63 @@ public: } }; +class CaseFolderDBCS : public CaseFolderTable { + // Allocate the expandable storage here so that it does not need to be reallocated + // for each call to Fold. + std::vector<wchar_t> utf16Mixed; + std::vector<wchar_t> utf16Folded; + UINT cp; +public: + CaseFolderDBCS(UINT cp_) : cp(cp_) { + StandardASCII(); + } + virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { + if ((lenMixed == 1) && (sizeFolded > 0)) { + folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; + return 1; + } else { + if (lenMixed > utf16Mixed.size()) { + utf16Mixed.resize(lenMixed + 8); + } + size_t nUtf16Mixed = ::MultiByteToWideChar(cp, 0, mixed, lenMixed, + &utf16Mixed[0], utf16Mixed.size()); + + if (nUtf16Mixed == 0) { + // Failed to convert -> bad input + folded[0] = '\0'; + return 1; + } + + if (nUtf16Mixed * 4 > utf16Folded.size()) { // Maximum folding expansion factor of 4 + utf16Folded.resize(nUtf16Mixed * 4 + 8); + } + int lenFlat = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, + LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, + &utf16Mixed[0], nUtf16Mixed, &utf16Folded[0], utf16Folded.size()); + + size_t lenOut = ::WideCharToMultiByte(cp, 0, + &utf16Folded[0], lenFlat, + NULL, 0, NULL, 0); + + if (lenOut < sizeFolded) { + ::WideCharToMultiByte(cp, 0, + &utf16Folded[0], lenFlat, + folded, lenOut, NULL, 0); + return lenOut; + } else { + return 0; + } + } + } +}; + CaseFolder *ScintillaWin::CaseFolderForEncoding() { UINT cpDest = CodePageOfDocument(); if (cpDest == SC_CP_UTF8) { return new CaseFolderUTF8(); } else { - CaseFolderTable *pcf = new CaseFolderTable(); if (pdoc->dbcsCodePage == 0) { + CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); // Only for single byte encodings UINT cpDoc = CodePageOfDocument(); @@ -1367,8 +1417,10 @@ CaseFolder *ScintillaWin::CaseFolderForEncoding() { } } } + return pcf; + } else { + return new CaseFolderDBCS(cpDest); } - return pcf; } } |