diff --git a/Libraries/LibGfx/FontCascadeList.cpp b/Libraries/LibGfx/FontCascadeList.cpp index 1edb84c2ba..3b4991c6f7 100644 --- a/Libraries/LibGfx/FontCascadeList.cpp +++ b/Libraries/LibGfx/FontCascadeList.cpp @@ -41,27 +41,38 @@ void FontCascadeList::extend(FontCascadeList const& other) Gfx::Font const& FontCascadeList::font_for_code_point(u32 code_point) const { + if (code_point < m_ascii_cache.size()) { + if (auto const* cached = m_ascii_cache[code_point]) + return *cached; + } + + auto cache_and_return = [&](Font const& font) -> Font const& { + if (code_point < m_ascii_cache.size()) + m_ascii_cache[code_point] = &font; + return font; + }; + for (auto const& entry : m_fonts) { if (entry.range_data.has_value()) { if (!entry.range_data->enclosing_range.contains(code_point)) continue; for (auto const& range : entry.range_data->unicode_ranges) { if (range.contains(code_point) && entry.font->contains_glyph(code_point)) - return entry.font; + return cache_and_return(*entry.font); } } else if (entry.font->contains_glyph(code_point)) { - return entry.font; + return cache_and_return(*entry.font); } } if (m_system_font_fallback_callback) { if (auto fallback = m_system_font_fallback_callback(code_point, first())) { m_fonts.append({ fallback.release_nonnull(), {} }); - return *m_fonts.last().font; + return cache_and_return(*m_fonts.last().font); } } - return *m_last_resort_font; + return cache_and_return(*m_last_resort_font); } bool FontCascadeList::equals(FontCascadeList const& other) const diff --git a/Libraries/LibGfx/FontCascadeList.h b/Libraries/LibGfx/FontCascadeList.h index 84bdb8ca83..1f053f9e4c 100644 --- a/Libraries/LibGfx/FontCascadeList.h +++ b/Libraries/LibGfx/FontCascadeList.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -67,6 +68,10 @@ private: RefPtr m_last_resort_font; mutable Vector m_fonts; SystemFontFallbackCallback m_system_font_fallback_callback; + + // OPTIMIZATION: Cache of resolved fonts for ASCII code points. Since m_fonts only grows and the cascade returns + // the first matching font, a cached hit can never become stale. + mutable Array m_ascii_cache {}; }; }