mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Cache font matching algorithm results
The majority of time in `compute_font()` was spent in `font_matching_algorithm()` repeatedly computing the same values. We now cache these values to avoid unnecessary work.
This commit is contained in:
parent
4ed6eac5be
commit
8d81421526
Notes:
github-actions[bot]
2025-11-05 11:03:01 +00:00
Author: https://github.com/tcl3
Commit: 8d81421526
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6702
Reviewed-by: https://github.com/kalenikaliaksandr
2 changed files with 34 additions and 1 deletions
|
|
@ -131,6 +131,18 @@ struct Traits<Web::CSS::OwnFontFaceKey> : public DefaultTraits<Web::CSS::OwnFont
|
||||||
static unsigned hash(Web::CSS::OwnFontFaceKey const& key) { return pair_int_hash(key.family_name.hash(), pair_int_hash(key.weight, key.slope)); }
|
static unsigned hash(Web::CSS::OwnFontFaceKey const& key) { return pair_int_hash(key.family_name.hash(), pair_int_hash(key.weight, key.slope)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Traits<Web::CSS::FontMatchingAlgorithmCacheKey> : public DefaultTraits<Web::CSS::FontMatchingAlgorithmCacheKey> {
|
||||||
|
static unsigned hash(Web::CSS::FontMatchingAlgorithmCacheKey const& key)
|
||||||
|
{
|
||||||
|
auto hash = key.family_name.hash();
|
||||||
|
hash = pair_int_hash(hash, key.weight);
|
||||||
|
hash = pair_int_hash(hash, key.slope);
|
||||||
|
hash = pair_int_hash(hash, Traits<float>::hash(key.font_size_in_pt));
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
@ -1694,9 +1706,17 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::find_matching_font_weight_desc
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<Gfx::FontCascadeList const> StyleComputer::font_matching_algorithm(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const
|
||||||
|
{
|
||||||
|
FontMatchingAlgorithmCacheKey key { family_name, weight, slope, font_size_in_pt };
|
||||||
|
return m_font_matching_algorithm_cache.ensure(key, [&] {
|
||||||
|
return font_matching_algorithm_impl(family_name, weight, slope, font_size_in_pt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Partial implementation of the font-matching algorithm: https://www.w3.org/TR/css-fonts-4/#font-matching-algorithm
|
// Partial implementation of the font-matching algorithm: https://www.w3.org/TR/css-fonts-4/#font-matching-algorithm
|
||||||
// FIXME: This should be replaced by the full CSS font selection algorithm.
|
// FIXME: This should be replaced by the full CSS font selection algorithm.
|
||||||
RefPtr<Gfx::FontCascadeList const> StyleComputer::font_matching_algorithm(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const
|
RefPtr<Gfx::FontCascadeList const> StyleComputer::font_matching_algorithm_impl(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const
|
||||||
{
|
{
|
||||||
// If a font family match occurs, the user agent assembles the set of font faces in that family and then
|
// If a font family match occurs, the user agent assembles the set of font faces in that family and then
|
||||||
// narrows the set to a single face using other font properties in the order given below.
|
// narrows the set to a single face using other font properties in the order given below.
|
||||||
|
|
@ -2948,6 +2968,7 @@ void StyleComputer::invalidate_rule_cache()
|
||||||
|
|
||||||
void StyleComputer::did_load_font(FlyString const&)
|
void StyleComputer::did_load_font(FlyString const&)
|
||||||
{
|
{
|
||||||
|
m_font_matching_algorithm_cache = {};
|
||||||
document().invalidate_style(DOM::StyleInvalidationReason::CSSFontLoaded);
|
document().invalidate_style(DOM::StyleInvalidationReason::CSSFontLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,15 @@ struct OwnFontFaceKey {
|
||||||
int slope { 0 };
|
int slope { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FontMatchingAlgorithmCacheKey {
|
||||||
|
FlyString family_name;
|
||||||
|
int weight;
|
||||||
|
int slope;
|
||||||
|
float font_size_in_pt;
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator==(FontMatchingAlgorithmCacheKey const& other) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
struct RuleCache {
|
struct RuleCache {
|
||||||
HashMap<FlyString, Vector<MatchingRule>> rules_by_id;
|
HashMap<FlyString, Vector<MatchingRule>> rules_by_id;
|
||||||
HashMap<FlyString, Vector<MatchingRule>> rules_by_class;
|
HashMap<FlyString, Vector<MatchingRule>> rules_by_class;
|
||||||
|
|
@ -241,6 +250,7 @@ private:
|
||||||
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_ascending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, Gfx::FontVariationSettings const& variations, bool inclusive);
|
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_ascending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, Gfx::FontVariationSettings const& variations, bool inclusive);
|
||||||
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_descending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, Gfx::FontVariationSettings const& variations, bool inclusive);
|
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_descending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, Gfx::FontVariationSettings const& variations, bool inclusive);
|
||||||
RefPtr<Gfx::FontCascadeList const> font_matching_algorithm(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const;
|
RefPtr<Gfx::FontCascadeList const> font_matching_algorithm(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const;
|
||||||
|
RefPtr<Gfx::FontCascadeList const> font_matching_algorithm_impl(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const;
|
||||||
void compute_custom_properties(ComputedProperties&, DOM::AbstractElement) const;
|
void compute_custom_properties(ComputedProperties&, DOM::AbstractElement) const;
|
||||||
void compute_math_depth(ComputedProperties&, Optional<DOM::AbstractElement>) const;
|
void compute_math_depth(ComputedProperties&, Optional<DOM::AbstractElement>) const;
|
||||||
void start_needed_transitions(ComputedProperties const& old_style, ComputedProperties& new_style, DOM::AbstractElement) const;
|
void start_needed_transitions(ComputedProperties const& old_style, ComputedProperties& new_style, DOM::AbstractElement) const;
|
||||||
|
|
@ -309,6 +319,8 @@ private:
|
||||||
CSSPixelRect m_viewport_rect;
|
CSSPixelRect m_viewport_rect;
|
||||||
|
|
||||||
OwnPtr<CountingBloomFilter<u8, 14>> m_ancestor_filter;
|
OwnPtr<CountingBloomFilter<u8, 14>> m_ancestor_filter;
|
||||||
|
|
||||||
|
mutable HashMap<FontMatchingAlgorithmCacheKey, RefPtr<Gfx::FontCascadeList const>> m_font_matching_algorithm_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontLoader final : public GC::Cell {
|
class FontLoader final : public GC::Cell {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue