From 0fece0650ec6298761f1ac4ab258a8ebf3f7feac Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 14 Jul 2025 17:59:58 +0200 Subject: [PATCH] LibGfx: Let FontCascadeList quickly reject out-of-range code points By keeping track of the enclosing range around all Unicode ranges of a FontCascadeList entry, we can quickly reject any code point that's outside all ranges. This knocks font_for_code_point() from 7% to 3% in the profile when scrolling on https://screenshotone.com/ --- Libraries/LibGfx/FontCascadeList.cpp | 20 +++++++++++++++++--- Libraries/LibGfx/FontCascadeList.h | 8 +++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Libraries/LibGfx/FontCascadeList.cpp b/Libraries/LibGfx/FontCascadeList.cpp index 7e8e17d8ad0..45cc71ceab3 100644 --- a/Libraries/LibGfx/FontCascadeList.cpp +++ b/Libraries/LibGfx/FontCascadeList.cpp @@ -15,7 +15,19 @@ void FontCascadeList::add(NonnullRefPtr font) void FontCascadeList::add(NonnullRefPtr font, Vector unicode_ranges) { - m_fonts.append({ move(font), move(unicode_ranges) }); + u32 lowest_code_point = 0xFFFFFFFF; + u32 highest_code_point = 0; + + for (auto& range : unicode_ranges) { + lowest_code_point = min(lowest_code_point, range.min_code_point()); + highest_code_point = max(highest_code_point, range.max_code_point()); + } + + m_fonts.append({ move(font), + Entry::RangeData { + { lowest_code_point, highest_code_point }, + move(unicode_ranges), + } }); } void FontCascadeList::extend(FontCascadeList const& other) @@ -26,8 +38,10 @@ void FontCascadeList::extend(FontCascadeList const& other) Gfx::Font const& FontCascadeList::font_for_code_point(u32 code_point) const { for (auto const& entry : m_fonts) { - if (entry.unicode_ranges.has_value()) { - for (auto const& range : *entry.unicode_ranges) { + 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; } diff --git a/Libraries/LibGfx/FontCascadeList.h b/Libraries/LibGfx/FontCascadeList.h index e41a659bd22..36bc44840d8 100644 --- a/Libraries/LibGfx/FontCascadeList.h +++ b/Libraries/LibGfx/FontCascadeList.h @@ -40,7 +40,13 @@ public: struct Entry { NonnullRefPtr font; - Optional> unicode_ranges; + struct RangeData { + // The enclosing range is the union of all Unicode ranges. Used for fast skipping. + UnicodeRange enclosing_range; + + Vector unicode_ranges; + }; + Optional range_data; }; void set_last_resort_font(NonnullRefPtr font) { m_last_resort_font = move(font); }