mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-23 21:15:14 +00:00
LibWeb/CSS: Add FontSourceStyleValue
This will be used by the `@font { src: ... }` descriptor once we parse descriptors as style values.
This commit is contained in:
parent
ceeaf352c8
commit
790923e7c5
8 changed files with 186 additions and 0 deletions
|
@ -164,6 +164,7 @@ set(SOURCES
|
|||
CSS/StyleValues/EasingStyleValue.cpp
|
||||
CSS/StyleValues/EdgeStyleValue.cpp
|
||||
CSS/StyleValues/FilterValueListStyleValue.cpp
|
||||
CSS/StyleValues/FontSourceStyleValue.cpp
|
||||
CSS/StyleValues/GridAutoFlowStyleValue.cpp
|
||||
CSS/StyleValues/GridTemplateAreaStyleValue.cpp
|
||||
CSS/StyleValues/GridTrackPlacementStyleValue.cpp
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FitContentStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FlexStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FontSourceStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
|
||||
|
@ -196,6 +197,12 @@ FlexStyleValue const& CSSStyleValue::as_flex() const
|
|||
return static_cast<FlexStyleValue const&>(*this);
|
||||
}
|
||||
|
||||
FontSourceStyleValue const& CSSStyleValue::as_font_source() const
|
||||
{
|
||||
VERIFY(is_font_source());
|
||||
return static_cast<FontSourceStyleValue const&>(*this);
|
||||
}
|
||||
|
||||
FrequencyStyleValue const& CSSStyleValue::as_frequency() const
|
||||
{
|
||||
VERIFY(is_frequency());
|
||||
|
|
|
@ -106,6 +106,7 @@ public:
|
|||
FilterValueList,
|
||||
FitContent,
|
||||
Flex,
|
||||
FontSource,
|
||||
FontVariant,
|
||||
Frequency,
|
||||
GridAutoFlow,
|
||||
|
@ -228,6 +229,10 @@ public:
|
|||
FlexStyleValue const& as_flex() const;
|
||||
FlexStyleValue& as_flex() { return const_cast<FlexStyleValue&>(const_cast<CSSStyleValue const&>(*this).as_flex()); }
|
||||
|
||||
bool is_font_source() const { return type() == Type::FontSource; }
|
||||
FontSourceStyleValue const& as_font_source() const;
|
||||
FontSourceStyleValue& as_font_source() { return const_cast<FontSourceStyleValue&>(const_cast<CSSStyleValue const&>(*this).as_font_source()); }
|
||||
|
||||
bool is_frequency() const { return type() == Type::Frequency; }
|
||||
FrequencyStyleValue const& as_frequency() const;
|
||||
FrequencyStyleValue& as_frequency() { return const_cast<FrequencyStyleValue&>(const_cast<CSSStyleValue const&>(*this).as_frequency()); }
|
||||
|
|
|
@ -341,6 +341,7 @@ private:
|
|||
RefPtr<PositionStyleValue> parse_position_value(TokenStream<ComponentValue>&, PositionParsingMode = PositionParsingMode::Normal);
|
||||
RefPtr<CSSStyleValue> parse_filter_value_list_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<StringStyleValue> parse_opentype_tag_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<FontSourceStyleValue> parse_font_source_value(TokenStream<ComponentValue>&);
|
||||
|
||||
RefPtr<CSSStyleValue> parse_angle_value(TokenStream<ComponentValue>&);
|
||||
RefPtr<CSSStyleValue> parse_angle_percentage_value(TokenStream<ComponentValue>&);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <AK/GenericLexer.h>
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/CSS/FontFace.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/PropertyName.h>
|
||||
#include <LibWeb/CSS/StyleValues/AngleStyleValue.h>
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FitContentStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FlexStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FontSourceStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/FrequencyStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/GridTrackPlacementStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h>
|
||||
|
@ -3655,6 +3657,67 @@ RefPtr<StringStyleValue> Parser::parse_opentype_tag_value(TokenStream<ComponentV
|
|||
return string_value;
|
||||
}
|
||||
|
||||
RefPtr<FontSourceStyleValue> Parser::parse_font_source_value(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
// <font-src> = <url> [ format(<font-format>)]? [ tech( <font-tech>#)]? | local(<family-name>)
|
||||
auto transaction = tokens.begin_transaction();
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
// local(<family-name>)
|
||||
if (tokens.next_token().is_function("local"sv)) {
|
||||
auto const& function = tokens.consume_a_token().function();
|
||||
TokenStream function_tokens { function.value };
|
||||
if (auto family_name = parse_family_name_value(function_tokens)) {
|
||||
transaction.commit();
|
||||
return FontSourceStyleValue::create(FontSourceStyleValue::Local { family_name.release_nonnull() }, {});
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// <url> [ format(<font-format>)]? [ tech( <font-tech>#)]?
|
||||
auto url = parse_url_function(tokens);
|
||||
if (!url.has_value() || !url->is_valid())
|
||||
return nullptr;
|
||||
|
||||
Optional<FlyString> format;
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
// [ format(<font-format>)]?
|
||||
if (tokens.next_token().is_function("format"sv)) {
|
||||
auto const& function = tokens.consume_a_token().function();
|
||||
auto context_guard = push_temporary_value_parsing_context(FunctionContext { function.name });
|
||||
|
||||
TokenStream format_tokens { function.value };
|
||||
format_tokens.discard_whitespace();
|
||||
auto const& format_name_token = format_tokens.consume_a_token();
|
||||
FlyString format_name;
|
||||
if (format_name_token.is(Token::Type::Ident)) {
|
||||
format_name = format_name_token.token().ident();
|
||||
} else if (format_name_token.is(Token::Type::String)) {
|
||||
format_name = format_name_token.token().string();
|
||||
} else {
|
||||
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: font source invalid (`format()` parameter not an ident or string; is: {}); discarding.", format_name_token.to_debug_string());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!font_format_is_supported(format_name)) {
|
||||
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: font source format({}) not supported; skipping.", format_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
format = move(format_name);
|
||||
}
|
||||
|
||||
tokens.discard_whitespace();
|
||||
|
||||
// FIXME: [ tech( <font-tech>#)]?
|
||||
|
||||
transaction.commit();
|
||||
return FontSourceStyleValue::create(url.release_value(), move(format));
|
||||
}
|
||||
|
||||
NonnullRefPtr<CSSStyleValue> Parser::resolve_unresolved_style_value(ParsingParams const& context, DOM::Element& element, Optional<PseudoElement> pseudo_element, PropertyID property_id, UnresolvedStyleValue const& unresolved)
|
||||
{
|
||||
// Unresolved always contains a var() or attr(), unless it is a custom property's value, in which case we shouldn't be trying
|
||||
|
|
67
Libraries/LibWeb/CSS/StyleValues/FontSourceStyleValue.cpp
Normal file
67
Libraries/LibWeb/CSS/StyleValues/FontSourceStyleValue.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/Serialize.h>
|
||||
#include <LibWeb/CSS/StyleValues/FontSourceStyleValue.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
FontSourceStyleValue::FontSourceStyleValue(Source source, Optional<FlyString> format)
|
||||
: StyleValueWithDefaultOperators(Type::FontSource)
|
||||
, m_source(move(source))
|
||||
, m_format(move(format))
|
||||
{
|
||||
}
|
||||
|
||||
FontSourceStyleValue::~FontSourceStyleValue() = default;
|
||||
|
||||
String FontSourceStyleValue::to_string(SerializationMode) const
|
||||
{
|
||||
// <font-src> = <url> [ format(<font-format>)]? [ tech( <font-tech>#)]? | local(<family-name>)
|
||||
return m_source.visit(
|
||||
[](Local const& local) {
|
||||
// local(<family-name>)
|
||||
StringBuilder builder;
|
||||
serialize_a_local(builder, local.name->to_string(SerializationMode::Normal));
|
||||
return builder.to_string_without_validation();
|
||||
},
|
||||
[this](URL::URL const& url) {
|
||||
// <url> [ format(<font-format>)]? [ tech( <font-tech>#)]?
|
||||
// FIXME: tech()
|
||||
StringBuilder builder;
|
||||
serialize_a_url(builder, url.to_string());
|
||||
|
||||
if (m_format.has_value()) {
|
||||
builder.append(" format("sv);
|
||||
serialize_an_identifier(builder, *m_format);
|
||||
builder.append(")"sv);
|
||||
}
|
||||
|
||||
return builder.to_string_without_validation();
|
||||
});
|
||||
}
|
||||
|
||||
bool FontSourceStyleValue::properties_equal(FontSourceStyleValue const& other) const
|
||||
{
|
||||
bool sources_equal = m_source.visit(
|
||||
[&other](Local const& local) {
|
||||
if (auto* other_local = other.m_source.get_pointer<Local>()) {
|
||||
return local.name == other_local->name;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[&other](URL::URL const& url) {
|
||||
if (auto* other_url = other.m_source.get_pointer<URL::URL>()) {
|
||||
return url == *other_url;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return sources_equal
|
||||
&& m_format == other.m_format;
|
||||
}
|
||||
|
||||
}
|
41
Libraries/LibWeb/CSS/StyleValues/FontSourceStyleValue.h
Normal file
41
Libraries/LibWeb/CSS/StyleValues/FontSourceStyleValue.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibWeb/CSS/CSSStyleValue.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class FontSourceStyleValue final : public StyleValueWithDefaultOperators<FontSourceStyleValue> {
|
||||
public:
|
||||
struct Local {
|
||||
NonnullRefPtr<CSSStyleValue> name;
|
||||
};
|
||||
using Source = Variant<Local, URL::URL>;
|
||||
|
||||
static ValueComparingNonnullRefPtr<FontSourceStyleValue> create(Source source, Optional<FlyString> format)
|
||||
{
|
||||
return adopt_ref(*new (nothrow) FontSourceStyleValue(move(source), move(format)));
|
||||
}
|
||||
virtual ~FontSourceStyleValue() override;
|
||||
|
||||
Source const& source() const { return m_source; }
|
||||
Optional<FlyString> const& format() const { return m_format; }
|
||||
|
||||
virtual String to_string(SerializationMode) const override;
|
||||
|
||||
bool properties_equal(FontSourceStyleValue const&) const;
|
||||
|
||||
private:
|
||||
FontSourceStyleValue(Source source, Optional<FlyString> format);
|
||||
|
||||
Source m_source;
|
||||
Optional<FlyString> m_format;
|
||||
};
|
||||
|
||||
}
|
|
@ -198,6 +198,7 @@ class FlexOrCalculated;
|
|||
class FlexStyleValue;
|
||||
class FontFace;
|
||||
class FontFaceSet;
|
||||
class FontSourceStyleValue;
|
||||
class Frequency;
|
||||
class FrequencyOrCalculated;
|
||||
class FrequencyPercentage;
|
||||
|
|
Loading…
Add table
Reference in a new issue