diff options
author | Neil <nyamatongwe@gmail.com> | 2023-01-23 14:34:17 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2023-01-23 14:34:17 +1100 |
commit | 1a9af9dcdfcc8b6c1124278f3c1d9d64075ae82b (patch) | |
tree | 88b46a550d5054d2c19959607c085294b497ba0f /src/PositionCache.cxx | |
parent | 887da82073d4ab855a3ba95deaa652d475df21e2 (diff) | |
download | scintilla-mirror-1a9af9dcdfcc8b6c1124278f3c1d9d64075ae82b.tar.gz |
Allow UTF-8 entries to coexist in the position cache alongside the document
encoding. Elements like character representations may be in UTF-8 while the
document is in a different encoding. UTF-8 will be used for additional features
and may later be the only encoding for the position cache.
This change does not change performance or the proportion of strings cached -
its purpose is to clean up callers and prepare for greater UTF-8 use.
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r-- | src/PositionCache.cxx | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index c4bcbc411..ce932521a 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -826,6 +826,7 @@ class PositionCacheEntry { uint16_t styleNumber; uint16_t len; uint16_t clock; + bool unicode; std::unique_ptr<XYPOSITION[]> positions; public: PositionCacheEntry() noexcept; @@ -836,10 +837,10 @@ public: void operator=(const PositionCacheEntry &) = delete; void operator=(PositionCacheEntry &&) = delete; ~PositionCacheEntry(); - void Set(unsigned int styleNumber_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_); + void Set(unsigned int styleNumber_, bool unicode_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_); void Clear() noexcept; - bool Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept; - static size_t Hash(unsigned int styleNumber_, std::string_view sv) noexcept; + bool Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept; + static size_t Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept; bool NewerThan(const PositionCacheEntry &other) const noexcept; void ResetClock() noexcept; }; @@ -862,16 +863,16 @@ public: void SetSize(size_t size_) override; size_t GetSize() const noexcept override; void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, - std::string_view sv, XYPOSITION *positions, bool needsLocking) override; + bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) override; }; PositionCacheEntry::PositionCacheEntry() noexcept : - styleNumber(0), len(0), clock(0) { + styleNumber(0), len(0), clock(0), unicode(false) { } // Copy constructor not currently used, but needed for being element in std::vector. PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) : - styleNumber(other.styleNumber), len(other.len), clock(other.clock) { + styleNumber(other.styleNumber), len(other.len), clock(other.clock), unicode(other.unicode) { if (other.positions) { const size_t lenData = len + (len / sizeof(XYPOSITION)) + 1; positions = std::make_unique<XYPOSITION[]>(lenData); @@ -879,12 +880,13 @@ PositionCacheEntry::PositionCacheEntry(const PositionCacheEntry &other) : } } -void PositionCacheEntry::Set(unsigned int styleNumber_, std::string_view sv, +void PositionCacheEntry::Set(unsigned int styleNumber_, bool unicode_, std::string_view sv, const XYPOSITION *positions_, uint16_t clock_) { Clear(); styleNumber = static_cast<uint16_t>(styleNumber_); len = static_cast<uint16_t>(sv.length()); clock = clock_; + unicode = unicode_; if (sv.data() && positions_) { positions = std::make_unique<XYPOSITION[]>(len + (len / sizeof(XYPOSITION)) + 1); for (unsigned int i=0; i<len; i++) { @@ -905,8 +907,8 @@ void PositionCacheEntry::Clear() noexcept { clock = 0; } -bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv, XYPOSITION *positions_) const noexcept { - if ((styleNumber == styleNumber_) && (len == sv.length()) && +bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, bool unicode_, std::string_view sv, XYPOSITION *positions_) const noexcept { + if ((styleNumber == styleNumber_) && (unicode == unicode_) && (len == sv.length()) && (memcmp(&positions[len], sv.data(), sv.length())== 0)) { for (unsigned int i=0; i<len; i++) { positions_[i] = positions[i]; @@ -917,10 +919,10 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, std::string_view sv } } -size_t PositionCacheEntry::Hash(unsigned int styleNumber_, std::string_view sv) noexcept { +size_t PositionCacheEntry::Hash(unsigned int styleNumber_, bool unicode_, std::string_view sv) noexcept { const size_t h1 = std::hash<std::string_view>{}(sv); const size_t h2 = std::hash<unsigned int>{}(styleNumber_); - return h1 ^ (h2 << 1); + return h1 ^ (h2 << 1) ^ static_cast<size_t>(unicode_); } bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const noexcept { @@ -959,7 +961,7 @@ size_t PositionCache::GetSize() const noexcept { } void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, - std::string_view sv, XYPOSITION *positions, bool needsLocking) { + bool unicode, std::string_view sv, XYPOSITION *positions, bool needsLocking) { const Style &style = vstyle.styles[styleNumber]; if (style.monospaceASCII) { if (AllGraphicASCII(sv)) { @@ -977,17 +979,17 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns // long comments with only a single comment. // Two way associative: try two probe positions. - const size_t hashValue = PositionCacheEntry::Hash(styleNumber, sv); + const size_t hashValue = PositionCacheEntry::Hash(styleNumber, unicode, sv); probe = hashValue % pces.size(); std::unique_lock<std::mutex> guard(mutex, std::defer_lock); if (needsLocking) { guard.lock(); } - if (pces[probe].Retrieve(styleNumber, sv, positions)) { + if (pces[probe].Retrieve(styleNumber, unicode, sv, positions)) { return; } const size_t probe2 = (hashValue * 37) % pces.size(); - if (pces[probe2].Retrieve(styleNumber, sv, positions)) { + if (pces[probe2].Retrieve(styleNumber, unicode, sv, positions)) { return; } // Not found. Choose the oldest of the two slots to replace @@ -997,7 +999,11 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns } const Font *fontStyle = style.font.get(); - surface->MeasureWidths(fontStyle, sv, positions); + if (unicode) { + surface->MeasureWidthsUTF8(fontStyle, sv, positions); + } else { + surface->MeasureWidths(fontStyle, sv, positions); + } if (probe < pces.size()) { // Store into cache std::unique_lock<std::mutex> guard(mutex, std::defer_lock); @@ -1014,7 +1020,7 @@ void PositionCache::MeasureWidths(Surface *surface, const ViewStyle &vstyle, uns clock = 2; } allClear = false; - pces[probe].Set(styleNumber, sv, positions, clock); + pces[probe].Set(styleNumber, unicode, sv, positions, clock); } } |