From 7ae229ead797fde0215a03eea15da063702e2736 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sat, 9 Dec 2023 09:03:36 +0100 Subject: [PATCH] LibGfx: Cache family, width, weight, and slope for OpenType fonts These properties could be cached in the font object once they are decoded from the table for the first time to make subsequent access faster. This change makes `Node::scaled_font()` in LibWeb go down from 6% to 1.5% in my profiles because building a font cache key is now a lot cheaper. --- .../Libraries/LibGfx/Font/OpenType/Font.cpp | 72 +++++++++++-------- .../Libraries/LibGfx/Font/OpenType/Font.h | 5 ++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp index 8f37b79fc2..9280a796d3 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.cpp @@ -495,10 +495,15 @@ u16 Font::units_per_em() const String Font::family() const { - auto string = m_name.typographic_family_name(); - if (!string.is_empty()) - return string; - return m_name.family_name(); + if (!m_family.has_value()) { + m_family = [&] { + auto string = m_name.typographic_family_name(); + if (!string.is_empty()) + return string; + return m_name.family_name(); + }(); + } + return *m_family; } String Font::variant() const @@ -511,40 +516,51 @@ String Font::variant() const u16 Font::weight() const { - constexpr u16 bold_bit { 1 }; - if (m_os2.has_value() && m_os2->weight_class()) - return m_os2->weight_class(); - if (m_head.style() & bold_bit) - return 700; - - return 400; + if (!m_weight.has_value()) { + m_weight = [&]() -> u16 { + constexpr u16 bold_bit { 1 }; + if (m_os2.has_value() && m_os2->weight_class()) + return m_os2->weight_class(); + if (m_head.style() & bold_bit) + return 700; + return 400; + }(); + } + return *m_weight; } u16 Font::width() const { - if (m_os2.has_value()) { - return m_os2->width_class(); + if (!m_width.has_value()) { + m_width = [&]() -> u16 { + if (m_os2.has_value()) + return m_os2->width_class(); + return Gfx::FontWidth::Normal; + }(); } - - return Gfx::FontWidth::Normal; + return *m_width; } u8 Font::slope() const { - // https://docs.microsoft.com/en-us/typography/opentype/spec/os2 - constexpr u16 italic_selection_bit { 1 }; - constexpr u16 oblique_selection_bit { 512 }; - // https://docs.microsoft.com/en-us/typography/opentype/spec/head - constexpr u16 italic_style_bit { 2 }; + if (!m_slope.has_value()) { + m_slope = [&]() -> u8 { + // https://docs.microsoft.com/en-us/typography/opentype/spec/os2 + constexpr u16 italic_selection_bit { 1 }; + constexpr u16 oblique_selection_bit { 512 }; + // https://docs.microsoft.com/en-us/typography/opentype/spec/head + constexpr u16 italic_style_bit { 2 }; - if (m_os2.has_value() && m_os2->selection() & oblique_selection_bit) - return 2; - if (m_os2.has_value() && m_os2->selection() & italic_selection_bit) - return 1; - if (m_head.style() & italic_style_bit) - return 1; - - return 0; + if (m_os2.has_value() && m_os2->selection() & oblique_selection_bit) + return 2; + if (m_os2.has_value() && m_os2->selection() & italic_selection_bit) + return 1; + if (m_head.style() & italic_style_bit) + return 1; + return 0; + }(); + } + return *m_slope; } bool Font::is_fixed_width() const diff --git a/Userland/Libraries/LibGfx/Font/OpenType/Font.h b/Userland/Libraries/LibGfx/Font/OpenType/Font.h index 8b6cc057c7..97c3b5add3 100644 --- a/Userland/Libraries/LibGfx/Font/OpenType/Font.h +++ b/Userland/Libraries/LibGfx/Font/OpenType/Font.h @@ -138,6 +138,11 @@ private: mutable HashMap m_kerning_cache; + Optional mutable m_family; + Optional mutable m_width; + Optional mutable m_weight; + Optional mutable m_slope; + GlyphPage const& glyph_page(size_t page_index) const; void populate_glyph_page(GlyphPage&, size_t page_index) const; };