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/ScintillaGTK.cxx | |
| 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/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);  | 
