1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 08:47:44 +00:00

LibGfx+LibWeb: Move Gfx::ScaledFont caching from LibWeb into LibGfx

Before this change, we would only cache and reuse Gfx::ScaledFont
instances for downloaded CSS fonts.

By moving it into Gfx::VectorFont, we get caching for all vector fonts,
including local system TTFs etc.

This avoids a *lot* of style invalidations in LibWeb, since we now vend
the same Gfx::Font pointer for the same font when used repeatedly.
This commit is contained in:
Andreas Kling 2023-12-25 12:45:18 +01:00
parent bf8107b247
commit f900957d26
16 changed files with 54 additions and 137 deletions

View file

@ -155,7 +155,9 @@ u8 ScaledFont::glyph_fixed_width() const
RefPtr<Font> ScaledFont::with_size(float point_size) const
{
return adopt_ref(*new Gfx::ScaledFont(*m_font, point_size, point_size));
if (point_size == m_point_height && point_size == m_point_width)
return const_cast<ScaledFont*>(this);
return m_font->scaled_font(point_size);
}
Gfx::FontPixelMetrics ScaledFont::pixel_metrics() const

View file

@ -64,7 +64,7 @@ RefPtr<Font> Typeface::get_font(float point_size, Font::AllowInexactSizeMatch al
VERIFY(point_size >= 0);
if (m_vector_font)
return adopt_ref(*new Gfx::ScaledFont(*m_vector_font, point_size, point_size));
return m_vector_font->scaled_font(point_size);
RefPtr<BitmapFont> best_match;
int size = roundf(point_size);

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Font/ScaledFont.h>
#include <LibGfx/Font/VectorFont.h>
namespace Gfx {
VectorFont::VectorFont() = default;
VectorFont::~VectorFont() = default;
NonnullRefPtr<ScaledFont> VectorFont::scaled_font(float point_size) const
{
auto it = m_scaled_fonts.find(point_size);
if (it != m_scaled_fonts.end())
return *it->value;
// FIXME: It might be nice to have a global cap on the number of fonts we cache
// instead of doing it at the per-VectorFont level like this.
constexpr size_t max_cached_font_size_count = 128;
if (m_scaled_fonts.size() > max_cached_font_size_count)
m_scaled_fonts.remove(m_scaled_fonts.begin());
auto scaled_font = adopt_ref(*new ScaledFont(*this, point_size, point_size));
m_scaled_fonts.set(point_size, scaled_font);
return scaled_font;
}
}

View file

@ -14,6 +14,8 @@
namespace Gfx {
class ScaledFont;
struct ScaledFontMetrics {
float ascender { 0 };
float descender { 0 };
@ -35,7 +37,7 @@ struct ScaledGlyphMetrics {
class VectorFont : public RefCounted<VectorFont> {
public:
virtual ~VectorFont() { }
virtual ~VectorFont();
virtual ScaledFontMetrics metrics(float x_scale, float y_scale) const = 0;
virtual ScaledGlyphMetrics glyph_metrics(u32 glyph_id, float x_scale, float y_scale, float point_width, float point_height) const = 0;
virtual float glyphs_horizontal_kerning(u32 left_glyph_id, u32 right_glyph_id, float x_scale) const = 0;
@ -52,6 +54,14 @@ public:
virtual u8 slope() const = 0;
virtual bool is_fixed_width() const = 0;
virtual bool has_color_bitmaps() const = 0;
[[nodiscard]] NonnullRefPtr<ScaledFont> scaled_font(float point_size) const;
protected:
VectorFont();
private:
mutable HashMap<float, NonnullRefPtr<ScaledFont>> m_scaled_fonts;
};
}