diff options
Diffstat (limited to 'gtk/ScintillaGTK.cxx')
-rw-r--r-- | gtk/ScintillaGTK.cxx | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index f4e762832..b53b46691 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -195,6 +195,7 @@ private: void NotifyKey(int key, int modifiers); void NotifyURIDropped(const char *list); const char *CharacterSetID() const; + virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual int KeyDefault(int key, int modifiers); virtual void CopyToClipboard(const SelectionText &selectedText); @@ -1338,6 +1339,64 @@ const char *ScintillaGTK::CharacterSetID() const { return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet); } +class CaseFolderUTF8 : public CaseFolderTable { +public: + CaseFolderUTF8() { + 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 { + gchar *mapped = g_utf8_casefold(mixed, lenMixed); + size_t lenMapped = strlen(mapped); + if (lenMapped < sizeFolded) { + memcpy(folded, mapped, lenMapped); + } else { + lenMapped = 0; + } + g_free(mapped); + return lenMapped; + } + } +}; + +CaseFolder *ScintillaGTK::CaseFolderForEncoding() { + if (pdoc->dbcsCodePage == SC_CP_UTF8) { + return new CaseFolderUTF8(); + } else { + CaseFolderTable *pcf = new CaseFolderTable(); + const char *charSetBuffer = CharacterSetID(); + if ((pdoc->dbcsCodePage == 0) && charSetBuffer) { + pcf->StandardASCII(); + // Only for single byte encodings + for (int i=0x80; i<0x100; i++) { + char sCharacter[2] = "A"; + sCharacter[0] = i; + int convertedLength = 1; + const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1, + "UTF-8", charSetBuffer, false); + if (sUTF8) { + gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8)); + if (mapped) { + int mappedLength = strlen(mapped); + const char *mappedBack = ConvertText(&mappedLength, mapped, + mappedLength, charSetBuffer, "UTF-8", false); + if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) { + pcf->SetTranslation(sCharacter[0], mappedBack[0]); + } + delete []mappedBack; + g_free(mapped); + } + } + delete []sUTF8; + } + } + return pcf; + } +} + std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { #if GTK_MAJOR_VERSION < 2 return Editor::CaseMapString(s, caseMapping); |