diff options
| author | Zufu Liu <unknown> | 2021-07-29 09:23:11 +1000 | 
|---|---|---|
| committer | Zufu Liu <unknown> | 2021-07-29 09:23:11 +1000 | 
| commit | ff085a4ce95380e9d981e0170e2d1eeaa93fdb88 (patch) | |
| tree | a290341caea8722cd045d676ae5347aa50ec03a5 /src/PositionCache.cxx | |
| parent | 884df029d33db4f93557885fb5020e5cdc9e8a9d (diff) | |
| download | scintilla-mirror-ff085a4ce95380e9d981e0170e2d1eeaa93fdb88.tar.gz | |
Feature [feature-requests:#1413] Decrease cost of representation for \r\n.
Diffstat (limited to 'src/PositionCache.cxx')
| -rw-r--r-- | src/PositionCache.cxx | 58 | 
1 files changed, 42 insertions, 16 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 285bf2816..1497adee7 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -533,8 +533,10 @@ std::shared_ptr<LineLayout> LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci:  	return std::make_shared<LineLayout>(lineNumber, maxChars);  } +namespace { +  // Simply pack the (maximum 4) character bytes into an int -static unsigned int KeyFromString(std::string_view charBytes) noexcept { +constexpr unsigned int KeyFromString(std::string_view charBytes) noexcept {  	PLATFORM_ASSERT(charBytes.length() <= 4);  	unsigned int k=0;  	for (size_t i=0; i < charBytes.length(); i++) { @@ -545,6 +547,10 @@ static unsigned int KeyFromString(std::string_view charBytes) noexcept {  	return k;  } +constexpr unsigned int representationKeyCrLf = KeyFromString("\r\n"); + +} +  void SpecialRepresentations::SetRepresentation(std::string_view charBytes, std::string_view value) {  	if ((charBytes.length() <= 4) && (value.length() <= Representation::maxLength)) {  		const unsigned int key = KeyFromString(charBytes); @@ -553,6 +559,9 @@ void SpecialRepresentations::SetRepresentation(std::string_view charBytes, std::  			// New entry so increment for first byte  			const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0];  			startByteHasReprs[ucStart]++; +			if (key == representationKeyCrLf) { +				crlf = true; +			}  		}  		mapReprs[key] = Representation(value);  	} @@ -585,24 +594,33 @@ void SpecialRepresentations::SetRepresentationColour(std::string_view charBytes,  void SpecialRepresentations::ClearRepresentation(std::string_view charBytes) {  	if (charBytes.length() <= 4) { -		MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes)); +		const unsigned int key = KeyFromString(charBytes); +		MapRepresentation::iterator it = mapReprs.find(key);  		if (it != mapReprs.end()) {  			mapReprs.erase(it);  			const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0];  			startByteHasReprs[ucStart]--; +			if (key == representationKeyCrLf) { +				crlf = false; +			}  		}  	}  } +const Representation *SpecialRepresentations::GetRepresentation(std::string_view charBytes) const { +	MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); +	if (it != mapReprs.end()) { +		return &(it->second); +	} +	return nullptr; +} +  const Representation *SpecialRepresentations::RepresentationFromCharacter(std::string_view charBytes) const {  	if (charBytes.length() <= 4) {  		const unsigned char ucStart = charBytes.empty() ? 0 : charBytes[0];  		if (!startByteHasReprs[ucStart])  			return nullptr; -		MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes)); -		if (it != mapReprs.end()) { -			return &(it->second); -		} +		return GetRepresentation(charBytes);  	}  	return nullptr;  } @@ -620,6 +638,7 @@ void SpecialRepresentations::Clear() {  	mapReprs.clear();  	constexpr short none = 0;  	std::fill(startByteHasReprs, std::end(startByteHasReprs), none); +	crlf = false;  }  void BreakFinder::Insert(Sci::Position val) { @@ -694,16 +713,23 @@ TextSegment BreakFinder::Next() {  		const int prev = nextBreak;  		while (nextBreak < lineRange.end) {  			int charWidth = 1; -			if (encodingFamily == EncodingFamily::unicode) -				charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(&ll->chars[nextBreak]), -					static_cast<int>(lineRange.end - nextBreak)); -			else if (encodingFamily == EncodingFamily::dbcs) -				charWidth = pdoc->DBCSDrawBytes( -					std::string_view(&ll->chars[nextBreak], lineRange.end - nextBreak)); -			// Special case \r\n line ends if there is a representation -			if (preprs->Contains("\r\n") && ll->chars[nextBreak] == '\r' && ll->chars[nextBreak + 1] == '\n') -				charWidth = 2; -			const Representation *repr = preprs->RepresentationFromCharacter(std::string_view(&ll->chars[nextBreak], charWidth)); +			const char * const chars = &ll->chars[nextBreak]; +			const unsigned char ch = chars[0]; +			if (!UTF8IsAscii(ch) && encodingFamily != EncodingFamily::eightBit) { +				if (encodingFamily == EncodingFamily::unicode) { +					charWidth = UTF8DrawBytes(reinterpret_cast<const unsigned char *>(chars), static_cast<int>(lineRange.end - nextBreak)); +				} else { +					charWidth = pdoc->DBCSDrawBytes(std::string_view(chars, lineRange.end - nextBreak)); +				} +			} +			const Representation *repr = nullptr; +			if (preprs->MayContain(ch)) { +				// Special case \r\n line ends if there is a representation +				if (ch == '\r' && preprs->ContainsCrLf() && chars[1] == '\n') { +					charWidth = 2; +				} +				repr = preprs->GetRepresentation(std::string_view(chars, charWidth)); +			}  			if (((nextBreak > 0) && (ll->styles[nextBreak] != ll->styles[nextBreak - 1])) ||  					repr ||  					(nextBreak == saeNext)) {  | 
