diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 0ec3d4e3c63..ce1dc4752d9 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include #include namespace Web::CSS { @@ -30,6 +33,47 @@ StyleComputer::StyleComputer(DOM::Document& document) { } +StyleComputer::~StyleComputer() = default; + +class StyleComputer::FontLoader : public ResourceClient { +public: + explicit FontLoader(StyleComputer& style_computer, FlyString family_name, AK::URL url) + : m_style_computer(style_computer) + , m_family_name(move(family_name)) + { + LoadRequest request; + request.set_url(move(url)); + set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); + } + + virtual ~FontLoader() override { } + + virtual void resource_did_load() override + { + auto result = TTF::Font::try_load_from_externally_owned_memory(resource()->encoded_data()); + if (result.is_error()) + return; + m_ttf_font = result.release_value(); + m_style_computer.did_load_font(m_family_name); + } + + virtual void resource_did_fail() override + { + } + + RefPtr font_with_point_size(float point_size) const + { + if (!m_ttf_font) + return nullptr; + return adopt_ref(*new TTF::ScaledFont(*m_ttf_font, point_size, point_size)); + } + +private: + StyleComputer& m_style_computer; + FlyString m_family_name; + RefPtr m_ttf_font; +}; + static StyleSheet& default_stylesheet() { static StyleSheet* sheet; @@ -880,6 +924,12 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele float font_size_in_pt = font_size_in_px * 0.75f; font_selector = { family, font_size_in_pt, weight, slope }; + if (auto it = m_loaded_fonts.find(family); it != m_loaded_fonts.end()) { + auto& loader = *it->value; + if (auto found_font = loader.font_with_point_size(font_size_in_pt)) + return found_font; + } + if (auto found_font = FontCache::the().get(font_selector)) return found_font; @@ -1041,6 +1091,7 @@ NonnullRefPtr StyleComputer::create_document_style() const NonnullRefPtr StyleComputer::compute_style(DOM::Element& element, Optional pseudo_element) const { + load_fonts_if_needed(); build_rule_cache_if_needed(); auto style = StyleProperties::create(); @@ -1183,4 +1234,28 @@ Gfx::IntRect StyleComputer::viewport_rect() const return {}; } +void StyleComputer::did_load_font([[maybe_unused]] FlyString const& family_name) +{ + document().invalidate_style(); +} + +void StyleComputer::load_fonts_if_needed() const +{ + for_each_stylesheet(CascadeOrigin::Author, [&](StyleSheet const& sheet) { + for (auto const& rule : static_cast(sheet).rules()) { + if (!is(rule)) + continue; + auto const& font_face = static_cast(rule).font_face(); + if (font_face.sources().is_empty()) + continue; + if (m_loaded_fonts.contains(font_face.font_family())) + continue; + + LoadRequest request; + auto url = m_document.parse_url(font_face.sources().first().url.to_string()); + auto loader = make(const_cast(*this), font_face.font_family(), move(url)); + const_cast(*this).m_loaded_fonts.set(font_face.font_family(), move(loader)); + } + }); +} } diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index 7ca23ea7fd4..c67ce8fd3d1 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,7 @@ private: class StyleComputer { public: explicit StyleComputer(DOM::Document&); - ~StyleComputer() = default; + ~StyleComputer(); DOM::Document& document() { return m_document; } DOM::Document const& document() const { return m_document; } @@ -71,6 +72,8 @@ public: Gfx::Font const& initial_font() const; + void did_load_font(FlyString const& family_name); + private: void compute_cascaded_values(StyleProperties&, DOM::Element&, Optional) const; void compute_font(StyleProperties&, DOM::Element const*, Optional) const; @@ -109,6 +112,11 @@ private: Vector other_rules; }; OwnPtr m_rule_cache; + + void load_fonts_if_needed() const; + + class FontLoader; + HashMap> m_loaded_fonts; }; }