diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.cpp b/Userland/Libraries/LibWeb/CSS/FontFace.cpp index b0401996cd..4618ccb695 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFace.cpp @@ -8,9 +8,10 @@ namespace Web::CSS { -FontFace::FontFace(FlyString font_family, Vector sources) +FontFace::FontFace(FlyString font_family, Vector sources, Vector unicode_ranges) : m_font_family(move(font_family)) , m_sources(move(sources)) + , m_unicode_ranges(move(unicode_ranges)) { } diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h index e90aa75b19..821a33cd46 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.h +++ b/Userland/Libraries/LibWeb/CSS/FontFace.h @@ -8,6 +8,7 @@ #include #include +#include namespace Web::CSS { @@ -17,16 +18,18 @@ public: AK::URL url; }; - FontFace(FlyString font_family, Vector sources); + FontFace(FlyString font_family, Vector sources, Vector unicode_ranges); ~FontFace() = default; FlyString font_family() const { return m_font_family; } Vector const& sources() const { return m_sources; } - // FIXME: font-style, font-weight, font-stretch, unicode-range, font-feature-settings + Vector const& unicode_ranges() const { return m_unicode_ranges; } + // FIXME: font-style, font-weight, font-stretch, font-feature-settings private: FlyString m_font_family; Vector m_sources; + Vector m_unicode_ranges; }; } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 4c16383b06..5595de37d5 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -4384,6 +4384,7 @@ RefPtr Parser::parse_font_face_rule(TokenStream& tokens Optional font_family; Vector src; + Vector unicode_range; for (auto& declaration_or_at_rule : declarations_and_at_rules) { if (declaration_or_at_rule.is_at_rule()) { @@ -4460,6 +4461,29 @@ RefPtr Parser::parse_font_face_rule(TokenStream& tokens if (supported_sources.is_empty()) continue; src = move(supported_sources); + continue; + } + if (declaration.name().equals_ignoring_case("unicode-range"sv)) { + Vector unicode_ranges; + bool unicode_range_invalid = false; + TokenStream all_tokens { declaration.values() }; + auto range_token_lists = parse_a_comma_separated_list_of_component_values(all_tokens); + for (auto& range_tokens : range_token_lists) { + TokenStream range_token_stream { range_tokens }; + auto maybe_unicode_range = parse_unicode_range(range_token_stream); + if (!maybe_unicode_range.has_value()) { + dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-face unicode-range format invalid; discarding."); + unicode_range_invalid = true; + break; + } + unicode_ranges.append(maybe_unicode_range.release_value()); + } + + if (unicode_range_invalid || unicode_ranges.is_empty()) + continue; + + unicode_range = move(unicode_ranges); + continue; } dbgln_if(CSS_PARSER_DEBUG, "CSSParser: Unrecognized descriptor '{}' in @font-family; discarding.", declaration.name()); @@ -4470,7 +4494,11 @@ RefPtr Parser::parse_font_face_rule(TokenStream& tokens return {}; } - return CSSFontFaceRule::create(FontFace { font_family.release_value(), move(src) }); + if (unicode_range.is_empty()) { + unicode_range.empend(0x0u, 0x10FFFFu); + } + + return CSSFontFaceRule::create(FontFace { font_family.release_value(), move(src), move(unicode_range) }); } RefPtr Parser::parse_list_style_value(Vector const& component_values) diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 850f3796c4..98079aae46 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -580,6 +580,13 @@ void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rul indent(builder, indent_levels + 2); builder.appendff("{}\n", source.url); } + + indent(builder, indent_levels + 1); + builder.append("unicode-ranges:\n"); + for (auto const& unicode_range : font_face.unicode_ranges()) { + indent(builder, indent_levels + 2); + builder.appendff("{}\n", unicode_range.to_string()); + } } void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule, int indent_levels)