From 4910cc1879975d605678367c1d0eb085ce24d890 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 15 Sep 2022 12:03:41 +0200 Subject: [PATCH] LibGfx: Cache vector fonts by family name Instead of just keeping them in an unsorted Vector, which led to increasingly noticeable O(n) lookups, we now cache a list of Typefaces per family name. --- .../Libraries/LibGfx/Font/FontDatabase.cpp | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/FontDatabase.cpp b/Userland/Libraries/LibGfx/Font/FontDatabase.cpp index ba18d5290c..6d064b5454 100644 --- a/Userland/Libraries/LibGfx/Font/FontDatabase.cpp +++ b/Userland/Libraries/LibGfx/Font/FontDatabase.cpp @@ -119,7 +119,7 @@ Font& FontDatabase::default_fixed_width_font() struct FontDatabase::Private { HashMap> full_name_to_font_map; - Vector> typefaces; + HashMap>> typefaces; }; void FontDatabase::load_all_fonts_from_path(String const& root) @@ -217,8 +217,11 @@ RefPtr FontDatabase::get_by_name(StringView name) RefPtr FontDatabase::get(FlyString const& family, float point_size, unsigned weight, unsigned slope, Font::AllowInexactSizeMatch allow_inexact_size_match) { - for (auto typeface : m_private->typefaces) { - if (typeface->family() == family && typeface->weight() == weight && typeface->slope() == slope) + auto it = m_private->typefaces.find(family); + if (it == m_private->typefaces.end()) + return nullptr; + for (auto const& typeface : it->value) { + if (typeface->weight() == weight && typeface->slope() == slope) return typeface->get_font(point_size, allow_inexact_size_match); } return nullptr; @@ -226,8 +229,11 @@ RefPtr FontDatabase::get(FlyString const& family, float point_size, u RefPtr FontDatabase::get(FlyString const& family, FlyString const& variant, float point_size, Font::AllowInexactSizeMatch allow_inexact_size_match) { - for (auto typeface : m_private->typefaces) { - if (typeface->family() == family && typeface->variant() == variant) + auto it = m_private->typefaces.find(family); + if (it == m_private->typefaces.end()) + return nullptr; + for (auto const& typeface : it->value) { + if (typeface->variant() == variant) return typeface->get_font(point_size, allow_inexact_size_match); } return nullptr; @@ -235,19 +241,24 @@ RefPtr FontDatabase::get(FlyString const& family, FlyString const& va RefPtr FontDatabase::get_or_create_typeface(String const& family, String const& variant) { - for (auto typeface : m_private->typefaces) { - if (typeface->family() == family && typeface->variant() == variant) - return typeface; + auto it = m_private->typefaces.find(family); + if (it != m_private->typefaces.end()) { + for (auto const& typeface : it->value) { + if (typeface->variant() == variant) + return typeface; + } } auto typeface = adopt_ref(*new Typeface(family, variant)); - m_private->typefaces.append(typeface); + m_private->typefaces.ensure(family).append(typeface); return typeface; } void FontDatabase::for_each_typeface(Function callback) { - for (auto typeface : m_private->typefaces) { - callback(*typeface); + for (auto const& it : m_private->typefaces) { + for (auto const& jt : it.value) { + callback(*jt); + } } }