diff options
| author | nyamatongwe <devnull@localhost> | 2010-03-25 12:10:59 +0000 |
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2010-03-25 12:10:59 +0000 |
| commit | 374db89c1efb33ef9a169fd7d26ceda068a07d12 (patch) | |
| tree | 661dd867b477a189c846fada99399ba9a61bc191 /gtk | |
| parent | 83f6510033d98712a774606cb834a540cef840cc (diff) | |
| download | scintilla-mirror-374db89c1efb33ef9a169fd7d26ceda068a07d12.tar.gz | |
New case insensitive searching implementation uses objects implementing
the CaseFolder interface to fold both search text and document text
so they can be compared with a simple strcmp.
A simple table based folder CaseFolderTable is used for 8 bit encodings
and maps input bytes to folded bytes. For multi-byte encodings
except for UTF-8 a null (output same as input) CaseFolderTable is used.
For UTF-8, more complex subclasses are used which call platform APIs
to perform the folding.
Folding is approximately to lower case although this differs between
platforms.
Diffstat (limited to 'gtk')
| -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); |
