diff options
Diffstat (limited to 'win32/ScintillaWin.cxx')
| -rw-r--r-- | win32/ScintillaWin.cxx | 74 | 
1 files changed, 74 insertions, 0 deletions
| diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index a509ef0ec..a14b8d01b 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -216,6 +216,7 @@ class ScintillaWin :  	virtual int GetCtrlID();  	virtual void NotifyParent(SCNotification scn);  	virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); +	virtual CaseFolder *CaseFolderForEncoding();  	virtual std::string CaseMapString(const std::string &s, int caseMapping);  	virtual void Copy();  	virtual void CopyAllowLine(); @@ -1298,6 +1299,79 @@ void ScintillaWin::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt)  			  MAKELPARAM(pt.x, pt.y));  } +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; +	std::vector<wchar_t> utf16Folded; +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 { +			if (lenMixed > utf16Mixed.size()) { +				utf16Mixed.resize(lenMixed + 8); +			} +			size_t nUtf16Mixed = ::MultiByteToWideChar(65001, 0, mixed, lenMixed, +				&utf16Mixed[0], utf16Mixed.size()); + +			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 = UTF8Length(&utf16Folded[0], lenFlat); +			if (lenOut < sizeFolded) { +				UTF8FromUTF16(&utf16Folded[0], lenFlat, folded, lenOut); +				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) { +			pcf->StandardASCII(); +			// Only for single byte encodings +			UINT cpDoc = CodePageOfDocument(); +			for (int i=0x80; i<0x100; i++) { +				char sCharacter[2] = "A"; +				sCharacter[0] = static_cast<char>(i); +				wchar_t wCharacter[20]; +				unsigned int lengthUTF16 = ::MultiByteToWideChar(cpDoc, 0, sCharacter, 1, +					wCharacter, sizeof(wCharacter)/sizeof(wCharacter[0])); +				if (lengthUTF16 == 1) { +					wchar_t wLower[20]; +					int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, +						LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, +						wCharacter, lengthUTF16, wLower, sizeof(wLower)/sizeof(wLower[0])); +					char sCharacterLowered[20]; +					unsigned int lengthConverted = ::WideCharToMultiByte(cpDoc, 0, +						wLower, charsConverted, +						sCharacterLowered, sizeof(sCharacterLowered), NULL, 0); +					if ((lengthConverted == 1) && (sCharacter[0] != sCharacterLowered[0])) { +						pcf->SetTranslation(sCharacter[0], sCharacterLowered[0]); +					} +				} +			} +		} +		return pcf; +	} +} +  std::string ScintillaWin::CaseMapString(const std::string &s, int caseMapping) {  	if (s.size() == 0)  		return std::string(); | 
