1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

TypefaceCache: Refactor to make more concise

This commit is contained in:
reuk 2024-03-19 16:54:05 +00:00
parent 9c1c61a06e
commit d406d51ad0
No known key found for this signature in database
GPG key ID: FCB43929F012EE5C

View file

@ -92,21 +92,19 @@ public:
Typeface::Ptr findTypefaceFor (const Font& font) Typeface::Ptr findTypefaceFor (const Font& font)
{ {
const auto faceName = font.getTypefaceName(); const Key key { font.getTypefaceName(), font.getTypefaceStyle() };
const auto faceStyle = font.getTypefaceStyle();
jassert (faceName.isNotEmpty()); jassert (key.name.isNotEmpty());
{ {
const ScopedReadLock slr (lock); const ScopedReadLock slr (lock);
for (int i = faces.size(); --i >= 0;) const auto range = makeRange (std::make_reverse_iterator (faces.end()),
{ std::make_reverse_iterator (faces.begin()));
CachedFace& face = faces.getReference (i);
if (face.typefaceName == faceName for (auto& face : range)
&& face.typefaceStyle == faceStyle {
&& face.typeface != nullptr) if (face.key == key && face.typeface != nullptr)
{ {
face.lastUsageCount = ++counter; face.lastUsageCount = ++counter;
return face.typeface; return face.typeface;
@ -115,33 +113,25 @@ public:
} }
const ScopedWriteLock slw (lock); const ScopedWriteLock slw (lock);
int replaceIndex = 0;
auto bestLastUsageCount = std::numeric_limits<size_t>::max();
for (int i = faces.size(); --i >= 0;) const auto replaceIter = std::min_element (faces.begin(),
{ faces.end(),
auto lu = faces.getReference (i).lastUsageCount; [] (const auto& a, const auto& b)
{
return a.lastUsageCount < b.lastUsageCount;
});
if (bestLastUsageCount > lu) jassert (replaceIter != faces.end());
{ auto& face = *replaceIter;
bestLastUsageCount = lu; face = CachedFace { key,
replaceIndex = i; ++counter,
} juce_getTypefaceForFont != nullptr
} ? juce_getTypefaceForFont (font)
: Font::getDefaultTypefaceForFont (font) };
auto& face = faces.getReference (replaceIndex);
face.typefaceName = faceName;
face.typefaceStyle = faceStyle;
face.lastUsageCount = ++counter;
if (juce_getTypefaceForFont == nullptr)
face.typeface = Font::getDefaultTypefaceForFont (font);
else
face.typeface = juce_getTypefaceForFont (font);
jassert (face.typeface != nullptr); // the look and feel must return a typeface! jassert (face.typeface != nullptr); // the look and feel must return a typeface!
if (defaultFace == nullptr && font == Font()) if (defaultFace == nullptr && key == Key{})
defaultFace = face.typeface; defaultFace = face.typeface;
return face.typeface; return face.typeface;
@ -154,15 +144,29 @@ public:
} }
private: private:
struct Key
{
String name = Font::getDefaultSansSerifFontName(), style = Font::getDefaultStyle();
bool operator== (const Key& other) const
{
const auto tie = [] (const auto& x) { return std::tie (x.name, x.style); };
return tie (*this) == tie (other);
}
bool operator!= (const Key& other) const
{
return ! operator== (other);
}
};
struct CachedFace struct CachedFace
{ {
CachedFace() noexcept {}
// Although it seems a bit wacky to store the name here, it's because it may be a // Although it seems a bit wacky to store the name here, it's because it may be a
// placeholder rather than a real one, e.g. "<Sans-Serif>" vs the actual typeface name. // placeholder rather than a real one, e.g. "<Sans-Serif>" vs the actual typeface name.
// Since the typeface itself doesn't know that it may have this alias, the name under // Since the typeface itself doesn't know that it may have this alias, the name under
// which it was fetched needs to be stored separately. // which it was fetched needs to be stored separately.
String typefaceName, typefaceStyle; Key key;
size_t lastUsageCount = 0; size_t lastUsageCount = 0;
Typeface::Ptr typeface; Typeface::Ptr typeface;
}; };