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& from_vertical_radius = from.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 const interpolated_vertical_radius = interpolate_length_percentage(calculation_context, from_vertical_radius, to_vertical_radius, delta);
if (!interpolated_horizontal_radius.has_value() || !interpolated_vertical_radius.has_value())
auto interpolated_horizontal_radius = interpolate_value_impl(element, calculation_context, from_horizontal_radius, to_horizontal_radius, delta, allow_discrete);
auto interpolated_vertical_radius = interpolate_value_impl(element, calculation_context, from_vertical_radius, to_vertical_radius, delta, allow_discrete);
if (!interpolated_horizontal_radius || !interpolated_vertical_radius)
return {};
return BorderRadiusStyleValue::create(
interpolated_horizontal_radius.value(),
interpolated_vertical_radius.value());
return BorderRadiusStyleValue::create(interpolated_horizontal_radius.release_nonnull(), interpolated_vertical_radius.release_nonnull());
}
case StyleValue::Type::Color: {
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)
{
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 const& underlying_dimension = as<DimensionStyleValue>(underlying_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());
}
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_vertical_radius = composite_length_percentage(underlying_value.as_border_radius().vertical_radius(), animated_value.as_border_radius().vertical_radius());
if (!composited_horizontal_radius.has_value() || !composited_vertical_radius.has_value())
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_value(underlying_value.as_border_radius().vertical_radius(), animated_value.as_border_radius().vertical_radius(), composite_operation);
if (!composited_horizontal_radius || !composited_vertical_radius)
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: {
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) {
auto transaction = tokens.begin_transaction();
auto horizontal = parse_length_percentage(tokens);
auto vertical = parse_length_percentage(tokens);
if (horizontal.has_value() && vertical.has_value()) {
auto horizontal = parse_length_percentage_value(tokens);
auto vertical = parse_length_percentage_value(tokens);
if (horizontal && vertical) {
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) {
auto transaction = tokens.begin_transaction();
auto radius = parse_length_percentage(tokens);
if (radius.has_value()) {
auto radius = parse_length_percentage_value(tokens);
if (radius) {
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)
{
auto top_left = [&](Vector<LengthPercentage>& radii) { return radii[0]; };
auto top_right = [&](Vector<LengthPercentage>& radii) {
auto top_left = [&](StyleValueVector& radii) { return radii[0]; };
auto top_right = [&](StyleValueVector& radii) {
switch (radii.size()) {
case 4:
case 3:
@ -1969,7 +1969,7 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
VERIFY_NOT_REACHED();
}
};
auto bottom_right = [&](Vector<LengthPercentage>& radii) {
auto bottom_right = [&](StyleValueVector& radii) {
switch (radii.size()) {
case 4:
case 3:
@ -1981,7 +1981,7 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
VERIFY_NOT_REACHED();
}
};
auto bottom_left = [&](Vector<LengthPercentage>& radii) {
auto bottom_left = [&](StyleValueVector& radii) {
switch (radii.size()) {
case 4:
return radii[3];
@ -1995,8 +1995,8 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
}
};
Vector<LengthPercentage> horizontal_radii;
Vector<LengthPercentage> vertical_radii;
StyleValueVector horizontal_radii;
StyleValueVector vertical_radii;
bool reading_vertical = false;
auto transaction = tokens.begin_transaction();
@ -2010,17 +2010,17 @@ RefPtr<StyleValue const> Parser::parse_border_radius_shorthand_value(TokenStream
continue;
}
auto maybe_dimension = parse_length_percentage(tokens);
if (!maybe_dimension.has_value())
auto maybe_dimension = parse_length_percentage_value(tokens);
if (!maybe_dimension)
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;
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;
if (reading_vertical) {
vertical_radii.append(maybe_dimension.release_value());
vertical_radii.append(maybe_dimension.release_nonnull());
} 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
{
if (m_properties.horizontal_radius == m_properties.vertical_radius)
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 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)));
}
ValueComparingNonnullRefPtr<StyleValue const> BorderRadiusStyleValue::absolutized(ComputationContext const& computation_context) const
{
auto absolutized_horizontal_radius = m_properties.horizontal_radius.absolutized(computation_context);
auto absolutized_vertical_radius = m_properties.vertical_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);
if (absolutized_vertical_radius == m_properties.vertical_radius && absolutized_horizontal_radius == m_properties.horizontal_radius)
return *this;

View file

@ -17,14 +17,14 @@ namespace Web::CSS {
class BorderRadiusStyleValue final : public StyleValueWithDefaultOperators<BorderRadiusStyleValue> {
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));
}
virtual ~BorderRadiusStyleValue() override = default;
LengthPercentage const& horizontal_radius() const { return m_properties.horizontal_radius; }
LengthPercentage const& vertical_radius() const { return m_properties.vertical_radius; }
ValueComparingNonnullRefPtr<StyleValue const> const& horizontal_radius() const { return m_properties.horizontal_radius; }
ValueComparingNonnullRefPtr<StyleValue const> const& vertical_radius() const { return m_properties.vertical_radius; }
bool is_elliptical() const { return m_properties.is_elliptical; }
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; }
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)
, 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;
struct Properties {
bool is_elliptical;
LengthPercentage horizontal_radius;
LengthPercentage vertical_radius;
ValueComparingNonnullRefPtr<StyleValue const> horizontal_radius;
ValueComparingNonnullRefPtr<StyleValue const> vertical_radius;
bool operator==(Properties const&) const = default;
} m_properties;
};

View file

@ -374,7 +374,7 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
auto horizontal_radius = [&](auto& style_value) -> String {
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);
};
@ -385,7 +385,7 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
auto vertical_radius = [&](auto& style_value) -> String {
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);
};

View file

@ -546,29 +546,29 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
if (border_bottom_left_radius.is_border_radius()) {
computed_values.set_border_bottom_left_radius(
CSS::BorderRadiusData {
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().horizontal_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);
if (border_bottom_right_radius.is_border_radius()) {
computed_values.set_border_bottom_right_radius(
CSS::BorderRadiusData {
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().horizontal_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);
if (border_top_left_radius.is_border_radius()) {
computed_values.set_border_top_left_radius(
CSS::BorderRadiusData {
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().horizontal_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);
if (border_top_right_radius.is_border_radius()) {
computed_values.set_border_top_right_radius(
CSS::BorderRadiusData {
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().horizontal_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_before_box_type_transformation(computed_style.display_before_box_type_transformation());