浏览代码

LibHTML: Add a simple font cache

The FontCache caches the result of font lookups. The cache key is a
simple object called FontSelector which consists of the font family
and font weight (both strings.)

This drastically reduces time spent in font lookup.
Andreas Kling 5 年之前
父节点
当前提交
60be51f908

+ 7 - 0
Libraries/LibHTML/CSS/StyleProperties.cpp

@@ -1,5 +1,6 @@
 #include <LibCore/CDirIterator.h>
 #include <LibHTML/CSS/StyleProperties.h>
+#include <LibHTML/FontCache.h>
 #include <ctype.h>
 
 void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value)
@@ -44,6 +45,11 @@ void StyleProperties::load_font() const
     auto font_family = string_or_fallback(CSS::PropertyID::FontFamily, "Katica");
     auto font_weight = string_or_fallback(CSS::PropertyID::FontWeight, "normal");
 
+    if (auto cached_font = FontCache::the().get({ font_family, font_weight })) {
+        m_font = cached_font;
+        return;
+    }
+
     String weight;
     if (font_weight == "lighter")
         weight = "Thin";
@@ -92,6 +98,7 @@ void StyleProperties::load_font() const
 #endif
 
     m_font = Font::load_from_file(String::format("/res/fonts/%s", file_name.characters()));
+    FontCache::the().set({ font_family, font_weight }, *m_font);
 }
 
 int StyleProperties::line_height() const

+ 21 - 0
Libraries/LibHTML/FontCache.cpp

@@ -0,0 +1,21 @@
+#include <LibDraw/Font.h>
+#include <LibHTML/FontCache.h>
+
+FontCache& FontCache::the()
+{
+    static FontCache cache;
+    return cache;
+}
+
+RefPtr<Font> FontCache::get(const FontSelector& font_selector) const
+{
+    auto cached_font = m_fonts.get(font_selector);
+    if (cached_font.has_value())
+        return cached_font.value();
+    return nullptr;
+}
+
+void FontCache::set(const FontSelector& font_selector, NonnullRefPtr<Font> font)
+{
+    m_fonts.set(font_selector, move(font));
+}

+ 34 - 0
Libraries/LibHTML/FontCache.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include <AK/HashMap.h>
+#include <AK/String.h>
+
+class Font;
+
+struct FontSelector {
+    String family;
+    String weight;
+
+    bool operator==(const FontSelector& other) const
+    {
+        return family == other.family && weight == other.weight;
+    }
+};
+
+namespace AK {
+template<>
+struct Traits<FontSelector> : public GenericTraits<FontSelector> {
+    static unsigned hash(const FontSelector& key) { return pair_int_hash(key.family.hash(), key.weight.hash()); }
+};
+}
+
+class FontCache {
+public:
+    static FontCache& the();
+    RefPtr<Font> get(const FontSelector&) const;
+    void set(const FontSelector&, NonnullRefPtr<Font>);
+
+private:
+    FontCache() {}
+    mutable HashMap<FontSelector, NonnullRefPtr<Font>> m_fonts;
+};

+ 1 - 0
Libraries/LibHTML/Makefile.shared

@@ -51,6 +51,7 @@ LIBHTML_OBJS = \
     Layout/LineBox.o \
     Layout/LineBoxFragment.o \
     Layout/LayoutTreeBuilder.o \
+    FontCache.o \
     ResourceLoader.o \
     HtmlView.o \
     Frame.o \