LibWeb: Store BorderRadiusStyleValue sub-values directly

Storing these within LengthPercentage is unnecessary
This commit is contained in:
Callum Law 2025-10-02 16:55:22 +13:00 committed by Sam Atkins
commit 25192d3c20
Notes: github-actions[bot] 2025-10-07 09:51:15 +00:00
6 changed files with 47 additions and 61 deletions

View file

@ -1501,13 +1501,11 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
auto const& to_horizontal_radius = to.as_border_radius().horizontal_radius(); auto const& to_horizontal_radius = to.as_border_radius().horizontal_radius();
auto const& from_vertical_radius = from.as_border_radius().vertical_radius(); auto const& from_vertical_radius = from.as_border_radius().vertical_radius();
auto const& to_vertical_radius = to.as_border_radius().vertical_radius(); auto const& to_vertical_radius = to.as_border_radius().vertical_radius();
auto const interpolated_horizontal_radius = interpolate_length_percentage(calculation_context, from_horizontal_radius, to_horizontal_radius, delta); auto interpolated_horizontal_radius = interpolate_value_impl(element, calculation_context, from_horizontal_radius, to_horizontal_radius, delta, allow_discrete);
auto const interpolated_vertical_radius = interpolate_length_percentage(calculation_context, from_vertical_radius, to_vertical_radius, delta); auto interpolated_vertical_radius = interpolate_value_impl(element, calculation_context, from_vertical_radius, to_vertical_radius, delta, allow_discrete);
if (!interpolated_horizontal_radius.has_value() || !interpolated_vertical_radius.has_value()) if (!interpolated_horizontal_radius || !interpolated_vertical_radius)
return {}; return {};
return BorderRadiusStyleValue::create( return BorderRadiusStyleValue::create(interpolated_horizontal_radius.release_nonnull(), interpolated_vertical_radius.release_nonnull());
interpolated_horizontal_radius.value(),
interpolated_vertical_radius.value());
} }
case StyleValue::Type::Color: { case StyleValue::Type::Color: {
ColorResolutionContext color_resolution_context {}; ColorResolutionContext color_resolution_context {};
@ -1730,18 +1728,6 @@ static T composite_raw_values(T underlying_raw_value, T animated_raw_value)
RefPtr<StyleValue const> composite_value(StyleValue const& underlying_value, StyleValue const& animated_value, Bindings::CompositeOperation composite_operation) RefPtr<StyleValue const> composite_value(StyleValue const& underlying_value, StyleValue const& animated_value, Bindings::CompositeOperation composite_operation)
{ {
auto composite_length_percentage = [](auto const& underlying_length_percentage, auto const& animated_length_percentage) -> Optional<LengthPercentage> {
if (underlying_length_percentage.is_length() && animated_length_percentage.is_length()) {
auto result = composite_raw_values(underlying_length_percentage.length().raw_value(), animated_length_percentage.length().raw_value());
return Length { result, underlying_length_percentage.length().unit() };
}
if (underlying_length_percentage.is_percentage() && animated_length_percentage.is_percentage()) {
auto result = composite_raw_values(underlying_length_percentage.percentage().value(), animated_length_percentage.percentage().value());
return Percentage { result };
}
return {};
};
auto composite_dimension_value = [](StyleValue const& underlying_value, StyleValue const& animated_value) -> Optional<double> { auto composite_dimension_value = [](StyleValue const& underlying_value, StyleValue const& animated_value) -> Optional<double> {
auto const& underlying_dimension = as<DimensionStyleValue>(underlying_value); auto const& underlying_dimension = as<DimensionStyleValue>(underlying_value);
auto const& animated_dimension = as<DimensionStyleValue>(animated_value); auto const& animated_dimension = as<DimensionStyleValue>(animated_value);
@ -1777,11 +1763,11 @@ RefPtr<StyleValue const> composite_value(StyleValue const& underlying_value, Sty
return BorderImageSliceStyleValue::create(composited_top.release_nonnull(), composited_right.release_nonnull(), composited_bottom.release_nonnull(), composited_left.release_nonnull(), underlying_border_image_slice_value.fill()); return BorderImageSliceStyleValue::create(composited_top.release_nonnull(), composited_right.release_nonnull(), composited_bottom.release_nonnull(), composited_left.release_nonnull(), underlying_border_image_slice_value.fill());
} }
case StyleValue::Type::BorderRadius: { case StyleValue::Type::BorderRadius: {
auto composited_horizontal_radius = composite_length_percentage(underlying_value.as_border_radius().horizontal_radius(), animated_value.as_border_radius().horizontal_radius()); auto composited_horizontal_radius = composite_value(underlying_value.as_border_radius().horizontal_radius(), animated_value.as_border_radius().horizontal_radius(), composite_operation);
auto composited_vertical_radius = composite_length_percentage(underlying_value.as_border_radius().vertical_radius(), animated_value.as_border_radius().vertical_radius()); auto composited_vertical_radius = composite_value(underlying_value.as_border_radius().vertical_radius(), animated_value.as_border_radius().vertical_radius(), composite_operation);
if (!composited_horizontal_radius.has_value() || !composited_vertical_radius.has_value()) if (!composited_horizontal_radius || !composited_vertical_radius)
return {}; return {};
return BorderRadiusStyleValue::create(*composited_horizontal_radius, *composited_vertical_radius); return BorderRadiusStyleValue::create(composited_horizontal_radius.release_nonnull(), composited_vertical_radius.release_nonnull());
} }
case StyleValue::Type::Integer: { case StyleValue::Type::Integer: {
auto result = composite_raw_values(underlying_value.as_integer().integer(), animated_value.as_integer().integer()); auto result = composite_raw_values(underlying_value.as_integer().integer(), animated_value.as_integer().integer());

View file

@ -1934,20 +1934,20 @@ RefPtr<StyleValue const> Parser::parse_border_radius_value(TokenStream<Component
{ {
if (tokens.remaining_token_count() == 2) { if (tokens.remaining_token_count() == 2) {
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
auto horizontal = parse_length_percentage(tokens); auto horizontal = parse_length_percentage_value(tokens);
auto vertical = parse_length_percentage(tokens); auto vertical = parse_length_percentage_value(tokens);
if (horizontal.has_value() && vertical.has_value()) { if (horizontal && vertical) {
transaction.commit(); transaction.commit();
return BorderRadiusStyleValue::create(horizontal.release_value(), vertical.release_value()); return BorderRadiusStyleValue::create(horizontal.release_nonnull(), vertical.release_nonnull());
} }
} }
if (tokens.remaining_token_count() == 1) { if (tokens.remaining_token_count() == 1) {
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
auto radius = parse_length_percentage(tokens); auto radius = parse_length_percentage_value(tokens);
if (radius.has_value()) { if (radius) {
transaction.commit(); transaction.commit();
return BorderRadiusStyleValue::create(radius.value(), radius.value()); return BorderRadiusStyleValue::create(*radius, *radius);
} }
} }
@ -1956,8 +1956,8 @@ RefPtr<StyleValue const> Parser::parse_border_radius_value(TokenStream<Component
RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream<ComponentValue>& tokens) RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream<ComponentValue>& tokens)
{ {
auto top_left = [&](Vector<LengthPercentage>& radii) { return radii[0]; }; auto top_left = [&](StyleValueVector& radii) { return radii[0]; };
auto top_right = [&](Vector<LengthPercentage>& radii) { auto top_right = [&](StyleValueVector& radii) {
switch (radii.size()) { switch (radii.size()) {
case 4: case 4:
case 3: case 3:
@ -1969,7 +1969,7 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
}; };
auto bottom_right = [&](Vector<LengthPercentage>& radii) { auto bottom_right = [&](StyleValueVector& radii) {
switch (radii.size()) { switch (radii.size()) {
case 4: case 4:
case 3: case 3:
@ -1981,7 +1981,7 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
}; };
auto bottom_left = [&](Vector<LengthPercentage>& radii) { auto bottom_left = [&](StyleValueVector& radii) {
switch (radii.size()) { switch (radii.size()) {
case 4: case 4:
return radii[3]; return radii[3];
@ -1995,8 +1995,8 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
} }
}; };
Vector<LengthPercentage> horizontal_radii; StyleValueVector horizontal_radii;
Vector<LengthPercentage> vertical_radii; StyleValueVector vertical_radii;
bool reading_vertical = false; bool reading_vertical = false;
auto transaction = tokens.begin_transaction(); auto transaction = tokens.begin_transaction();
@ -2010,17 +2010,17 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
continue; continue;
} }
auto maybe_dimension = parse_length_percentage(tokens); auto maybe_dimension = parse_length_percentage_value(tokens);
if (!maybe_dimension.has_value()) if (!maybe_dimension)
return nullptr; return nullptr;
if (maybe_dimension->is_length() && !property_accepts_length(PropertyID::BorderRadius, maybe_dimension->length())) if (maybe_dimension->is_length() && !property_accepts_length(PropertyID::BorderRadius, maybe_dimension->as_length().length()))
return nullptr; return nullptr;
if (maybe_dimension->is_percentage() && !property_accepts_percentage(PropertyID::BorderRadius, maybe_dimension->percentage())) if (maybe_dimension->is_percentage() && !property_accepts_percentage(PropertyID::BorderRadius, maybe_dimension->as_percentage().percentage()))
return nullptr; return nullptr;
if (reading_vertical) { if (reading_vertical) {
vertical_radii.append(maybe_dimension.release_value()); vertical_radii.append(maybe_dimension.release_nonnull());
} else { } else {
horizontal_radii.append(maybe_dimension.release_value()); horizontal_radii.append(maybe_dimension.release_nonnull());
} }
} }

View file

@ -14,14 +14,14 @@ namespace Web::CSS {
String BorderRadiusStyleValue::to_string(SerializationMode mode) const String BorderRadiusStyleValue::to_string(SerializationMode mode) const
{ {
if (m_properties.horizontal_radius == m_properties.vertical_radius) if (m_properties.horizontal_radius == m_properties.vertical_radius)
return m_properties.horizontal_radius.to_string(mode); return m_properties.horizontal_radius->to_string(mode);
return MUST(String::formatted("{} {}", m_properties.horizontal_radius.to_string(mode), m_properties.vertical_radius.to_string(mode))); return MUST(String::formatted("{} {}", m_properties.horizontal_radius->to_string(mode), m_properties.vertical_radius->to_string(mode)));
} }
ValueComparingNonnullRefPtr<StyleValue const> BorderRadiusStyleValue::absolutized(ComputationContext const& computation_context) const ValueComparingNonnullRefPtr<StyleValue const> BorderRadiusStyleValue::absolutized(ComputationContext const& computation_context) const
{ {
auto absolutized_horizontal_radius = m_properties.horizontal_radius.absolutized(computation_context); auto absolutized_horizontal_radius = m_properties.horizontal_radius->absolutized(computation_context);
auto absolutized_vertical_radius = m_properties.vertical_radius.absolutized(computation_context); auto absolutized_vertical_radius = m_properties.vertical_radius->absolutized(computation_context);
if (absolutized_vertical_radius == m_properties.vertical_radius && absolutized_horizontal_radius == m_properties.horizontal_radius) if (absolutized_vertical_radius == m_properties.vertical_radius && absolutized_horizontal_radius == m_properties.horizontal_radius)
return *this; return *this;

View file

@ -17,14 +17,14 @@ namespace Web::CSS {
class BorderRadiusStyleValue final : public StyleValueWithDefaultOperators<BorderRadiusStyleValue> { class BorderRadiusStyleValue final : public StyleValueWithDefaultOperators<BorderRadiusStyleValue> {
public: public:
static ValueComparingNonnullRefPtr<BorderRadiusStyleValue const> create(LengthPercentage const& horizontal_radius, LengthPercentage const& vertical_radius) static ValueComparingNonnullRefPtr<BorderRadiusStyleValue const> create(ValueComparingNonnullRefPtr<StyleValue const> const& horizontal_radius, ValueComparingNonnullRefPtr<StyleValue const> const& vertical_radius)
{ {
return adopt_ref(*new (nothrow) BorderRadiusStyleValue(horizontal_radius, vertical_radius)); return adopt_ref(*new (nothrow) BorderRadiusStyleValue(horizontal_radius, vertical_radius));
} }
virtual ~BorderRadiusStyleValue() override = default; virtual ~BorderRadiusStyleValue() override = default;
LengthPercentage const& horizontal_radius() const { return m_properties.horizontal_radius; } ValueComparingNonnullRefPtr<StyleValue const> const& horizontal_radius() const { return m_properties.horizontal_radius; }
LengthPercentage const& vertical_radius() const { return m_properties.vertical_radius; } ValueComparingNonnullRefPtr<StyleValue const> const& vertical_radius() const { return m_properties.vertical_radius; }
bool is_elliptical() const { return m_properties.is_elliptical; } bool is_elliptical() const { return m_properties.is_elliptical; }
virtual String to_string(SerializationMode) const override; virtual String to_string(SerializationMode) const override;
@ -32,7 +32,7 @@ public:
bool properties_equal(BorderRadiusStyleValue const& other) const { return m_properties == other.m_properties; } bool properties_equal(BorderRadiusStyleValue const& other) const { return m_properties == other.m_properties; }
private: private:
BorderRadiusStyleValue(LengthPercentage const& horizontal_radius, LengthPercentage const& vertical_radius) BorderRadiusStyleValue(ValueComparingNonnullRefPtr<StyleValue const> const& horizontal_radius, ValueComparingNonnullRefPtr<StyleValue const> const& vertical_radius)
: StyleValueWithDefaultOperators(Type::BorderRadius) : StyleValueWithDefaultOperators(Type::BorderRadius)
, m_properties { .is_elliptical = horizontal_radius != vertical_radius, .horizontal_radius = horizontal_radius, .vertical_radius = vertical_radius } , m_properties { .is_elliptical = horizontal_radius != vertical_radius, .horizontal_radius = horizontal_radius, .vertical_radius = vertical_radius }
{ {
@ -41,8 +41,8 @@ private:
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override; virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
struct Properties { struct Properties {
bool is_elliptical; bool is_elliptical;
LengthPercentage horizontal_radius; ValueComparingNonnullRefPtr<StyleValue const> horizontal_radius;
LengthPercentage vertical_radius; ValueComparingNonnullRefPtr<StyleValue const> vertical_radius;
bool operator==(Properties const&) const = default; bool operator==(Properties const&) const = default;
} m_properties; } m_properties;
}; };

View file

@ -374,7 +374,7 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
auto horizontal_radius = [&](auto& style_value) -> String { auto horizontal_radius = [&](auto& style_value) -> String {
if (style_value->is_border_radius()) if (style_value->is_border_radius())
return style_value->as_border_radius().horizontal_radius().to_string(mode); return style_value->as_border_radius().horizontal_radius()->to_string(mode);
return style_value->to_string(mode); return style_value->to_string(mode);
}; };
@ -385,7 +385,7 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
auto vertical_radius = [&](auto& style_value) -> String { auto vertical_radius = [&](auto& style_value) -> String {
if (style_value->is_border_radius()) if (style_value->is_border_radius())
return style_value->as_border_radius().vertical_radius().to_string(mode); return style_value->as_border_radius().vertical_radius()->to_string(mode);
return style_value->to_string(mode); return style_value->to_string(mode);
}; };

View file

@ -546,29 +546,29 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
if (border_bottom_left_radius.is_border_radius()) { if (border_bottom_left_radius.is_border_radius()) {
computed_values.set_border_bottom_left_radius( computed_values.set_border_bottom_left_radius(
CSS::BorderRadiusData { CSS::BorderRadiusData {
border_bottom_left_radius.as_border_radius().horizontal_radius(), CSS::LengthPercentage::from_style_value(border_bottom_left_radius.as_border_radius().horizontal_radius()),
border_bottom_left_radius.as_border_radius().vertical_radius() }); CSS::LengthPercentage::from_style_value(border_bottom_left_radius.as_border_radius().vertical_radius()) });
} }
auto const& border_bottom_right_radius = computed_style.property(CSS::PropertyID::BorderBottomRightRadius); auto const& border_bottom_right_radius = computed_style.property(CSS::PropertyID::BorderBottomRightRadius);
if (border_bottom_right_radius.is_border_radius()) { if (border_bottom_right_radius.is_border_radius()) {
computed_values.set_border_bottom_right_radius( computed_values.set_border_bottom_right_radius(
CSS::BorderRadiusData { CSS::BorderRadiusData {
border_bottom_right_radius.as_border_radius().horizontal_radius(), CSS::LengthPercentage::from_style_value(border_bottom_right_radius.as_border_radius().horizontal_radius()),
border_bottom_right_radius.as_border_radius().vertical_radius() }); CSS::LengthPercentage::from_style_value(border_bottom_right_radius.as_border_radius().vertical_radius()) });
} }
auto const& border_top_left_radius = computed_style.property(CSS::PropertyID::BorderTopLeftRadius); auto const& border_top_left_radius = computed_style.property(CSS::PropertyID::BorderTopLeftRadius);
if (border_top_left_radius.is_border_radius()) { if (border_top_left_radius.is_border_radius()) {
computed_values.set_border_top_left_radius( computed_values.set_border_top_left_radius(
CSS::BorderRadiusData { CSS::BorderRadiusData {
border_top_left_radius.as_border_radius().horizontal_radius(), CSS::LengthPercentage::from_style_value(border_top_left_radius.as_border_radius().horizontal_radius()),
border_top_left_radius.as_border_radius().vertical_radius() }); CSS::LengthPercentage::from_style_value(border_top_left_radius.as_border_radius().vertical_radius()) });
} }
auto const& border_top_right_radius = computed_style.property(CSS::PropertyID::BorderTopRightRadius); auto const& border_top_right_radius = computed_style.property(CSS::PropertyID::BorderTopRightRadius);
if (border_top_right_radius.is_border_radius()) { if (border_top_right_radius.is_border_radius()) {
computed_values.set_border_top_right_radius( computed_values.set_border_top_right_radius(
CSS::BorderRadiusData { CSS::BorderRadiusData {
border_top_right_radius.as_border_radius().horizontal_radius(), CSS::LengthPercentage::from_style_value(border_top_right_radius.as_border_radius().horizontal_radius()),
border_top_right_radius.as_border_radius().vertical_radius() }); CSS::LengthPercentage::from_style_value(border_top_right_radius.as_border_radius().vertical_radius()) });
} }
computed_values.set_display(computed_style.display()); computed_values.set_display(computed_style.display());
computed_values.set_display_before_box_type_transformation(computed_style.display_before_box_type_transformation()); computed_values.set_display_before_box_type_transformation(computed_style.display_before_box_type_transformation());