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); }