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.
This commit is contained in:
Andreas Kling 2019-10-18 23:02:10 +02:00
parent 76e2c08fbf
commit 60be51f908
Notes: sideshowbarker 2024-07-19 11:38:45 +09:00
4 changed files with 63 additions and 0 deletions

View file

@ -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

View file

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

View file

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

View file

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