LibWeb: Store corner-*-shape properties in computed form

This commit is contained in:
Callum Law 2025-10-09 01:20:48 +13:00 committed by Sam Atkins
parent 397e39f316
commit 20a2e8ab12
5 changed files with 89 additions and 15 deletions

View File

@ -73,6 +73,7 @@
#include <LibWeb/CSS/StyleValues/ShorthandStyleValue.h>
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
#include <LibWeb/CSS/StyleValues/SuperellipseStyleValue.h>
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
#include <LibWeb/CSS/StyleValues/TransitionStyleValue.h>
@ -3236,6 +3237,11 @@ NonnullRefPtr<StyleValue const> StyleComputer::compute_value_of_property(Propert
return compute_border_or_outline_width(absolutized_value, get_property_specified_value(PropertyID::BorderTopStyle), device_pixels_per_css_pixel);
case PropertyID::OutlineWidth:
return compute_border_or_outline_width(absolutized_value, get_property_specified_value(PropertyID::OutlineStyle), device_pixels_per_css_pixel);
case PropertyID::CornerBottomLeftShape:
case PropertyID::CornerBottomRightShape:
case PropertyID::CornerTopLeftShape:
case PropertyID::CornerTopRightShape:
return compute_corner_shape(absolutized_value);
case PropertyID::FontVariationSettings:
return compute_font_variation_settings(absolutized_value);
case PropertyID::LetterSpacing:
@ -3335,6 +3341,40 @@ NonnullRefPtr<StyleValue const> StyleComputer::compute_border_or_outline_width(N
return LengthStyleValue::create(Length::make_px(snap_a_length_as_a_border_width(device_pixels_per_css_pixel, absolute_length)));
}
// https://drafts.csswg.org/css-borders-4/#propdef-corner-top-left-shape
NonnullRefPtr<StyleValue const> StyleComputer::compute_corner_shape(NonnullRefPtr<StyleValue const> const& absolutized_value)
{
// the corresponding superellipse() value
if (absolutized_value->is_superellipse())
return absolutized_value;
switch (absolutized_value->to_keyword()) {
case Keyword::Round:
// The corner shape is a quarter of a convex ellipse. Equivalent to superellipse(1).
return SuperellipseStyleValue::create(NumberStyleValue::create(1));
case Keyword::Squircle:
// The corner shape is a quarter of a "squircle", a convex curve between round and square. Equivalent to superellipse(2).
return SuperellipseStyleValue::create(NumberStyleValue::create(2));
case Keyword::Square:
// The corner shape is a convex 90deg angle. Equivalent to superellipse(infinity).
return SuperellipseStyleValue::create(NumberStyleValue::create(AK::Infinity<double>));
case Keyword::Bevel:
// The corner shape is a straight diagonal line, neither convex nor concave. Equivalent to superellipse(0).
return SuperellipseStyleValue::create(NumberStyleValue::create(0));
case Keyword::Scoop:
// The corner shape is a concave quarter-ellipse. Equivalent to superellipse(-1).
return SuperellipseStyleValue::create(NumberStyleValue::create(-1));
case Keyword::Notch:
// The corner shape is a concave 90deg angle. Equivalent to superellipse(-infinity).
return SuperellipseStyleValue::create(NumberStyleValue::create(-AK::Infinity<double>));
default:
VERIFY_NOT_REACHED();
}
VERIFY_NOT_REACHED();
}
NonnullRefPtr<StyleValue const> StyleComputer::compute_font_size(NonnullRefPtr<StyleValue const> const& specified_value, int computed_math_depth, CSSPixels inherited_font_size, int inherited_math_depth, ComputationContext const& computation_context)
{
// https://drafts.csswg.org/css-fonts/#font-size-prop

View File

@ -201,6 +201,7 @@ public:
static NonnullRefPtr<StyleValue const> compute_value_of_property(PropertyID, NonnullRefPtr<StyleValue const> const& specified_value, Function<NonnullRefPtr<StyleValue const>(PropertyID)> const& get_property_specified_value, ComputationContext const&, double device_pixels_per_css_pixel);
static NonnullRefPtr<StyleValue const> compute_animation_name(NonnullRefPtr<StyleValue const> const& absolutized_value);
static NonnullRefPtr<StyleValue const> compute_border_or_outline_width(NonnullRefPtr<StyleValue const> const& absolutized_value, NonnullRefPtr<StyleValue const> const& style_specified_value, double device_pixels_per_css_pixel);
static NonnullRefPtr<StyleValue const> compute_corner_shape(NonnullRefPtr<StyleValue const> const& absolutized_value);
static NonnullRefPtr<StyleValue const> compute_font_size(NonnullRefPtr<StyleValue const> const& specified_value, int computed_math_depth, CSSPixels inherited_font_size, int inherited_math_depth, ComputationContext const&);
static NonnullRefPtr<StyleValue const> compute_font_style(NonnullRefPtr<StyleValue const> const& specified_value, ComputationContext const&);
static NonnullRefPtr<StyleValue const> compute_font_weight(NonnullRefPtr<StyleValue const> const& specified_value, double inherited_font_weight, ComputationContext const&);

View File

@ -11,6 +11,28 @@ namespace Web::CSS {
String SuperellipseStyleValue::to_string(SerializationMode mode) const
{
if (mode == SerializationMode::ResolvedValue && m_parameter->is_number()) {
auto number = m_parameter->as_number().number();
if (number == 1)
return "round"_string;
if (number == 2)
return "squircle"_string;
if (number == AK::Infinity<double>)
return "square"_string;
if (number == 0)
return "bevel"_string;
if (number == -1)
return "scoop"_string;
if (number == -AK::Infinity<double>)
return "notch"_string;
}
auto stringified_parameter = [&] {
if (!m_parameter->is_number())
return m_parameter->to_string(mode);
@ -29,4 +51,14 @@ String SuperellipseStyleValue::to_string(SerializationMode mode) const
return MUST(String::formatted("superellipse({})", stringified_parameter));
}
ValueComparingNonnullRefPtr<StyleValue const> SuperellipseStyleValue::absolutized(ComputationContext const& computation_context) const
{
auto const& absolutized_parameter = m_parameter->absolutized(computation_context);
if (absolutized_parameter == m_parameter)
return *this;
return SuperellipseStyleValue::create(absolutized_parameter);
}
}

View File

@ -20,6 +20,8 @@ public:
virtual String to_string(SerializationMode serialization_mode) const override;
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
bool properties_equal(SuperellipseStyleValue const& other) const { return m_parameter == other.m_parameter; }
private:

View File

@ -2,18 +2,17 @@ Harness status: OK
Found 38 tests
25 Pass
13 Fail
38 Pass
Pass Property corner-top-left-shape value 'round'
Pass Property corner-top-left-shape value 'scoop'
Pass Property corner-top-left-shape value 'superellipse(5)'
Pass Property corner-top-left-shape value 'superellipse(0.2)'
Fail Property corner-top-left-shape value 'superellipse(-infinity)'
Fail Property corner-top-left-shape value 'superellipse(infinity)'
Fail Property corner-top-left-shape value 'superellipse(1)'
Fail Property corner-top-left-shape value 'superellipse(0)'
Fail Property corner-top-left-shape value 'superellipse(2)'
Fail Property corner-top-left-shape value 'superellipse( -1)'
Pass Property corner-top-left-shape value 'superellipse(-infinity)'
Pass Property corner-top-left-shape value 'superellipse(infinity)'
Pass Property corner-top-left-shape value 'superellipse(1)'
Pass Property corner-top-left-shape value 'superellipse(0)'
Pass Property corner-top-left-shape value 'superellipse(2)'
Pass Property corner-top-left-shape value 'superellipse( -1)'
Pass Property corner-top-right-shape value 'round'
Pass Property corner-top-right-shape value 'superellipse(5)'
Pass Property corner-bottom-right-shape value 'scoop'
@ -25,20 +24,20 @@ Pass Property corner-shape value 'superellipse(-5) superellipse(3) superellipse(
Pass Property corner-shape value 'round round round round'
Pass Property corner-shape value 'round scoop'
Pass Property corner-shape value 'round scoop round scoop'
Fail Property corner-shape value 'bevel superellipse(1)'
Fail Property corner-shape value 'superellipse(-1) superellipse(3) square'
Fail Property corner-shape value 'superellipse(-1) superellipse(3) superellipse(0)'
Fail Property corner-shape value 'bevel superellipse(1) squircle round'
Fail Property corner-shape value 'superellipse(-1) superellipse(3) superellipse(0) superellipse(infinity)'
Pass Property corner-shape value 'bevel superellipse(1)'
Pass Property corner-shape value 'superellipse(-1) superellipse(3) square'
Pass Property corner-shape value 'superellipse(-1) superellipse(3) superellipse(0)'
Pass Property corner-shape value 'bevel superellipse(1) squircle round'
Pass Property corner-shape value 'superellipse(-1) superellipse(3) superellipse(0) superellipse(infinity)'
Pass Property corner-left-shape value 'round scoop'
Pass Property corner-top-shape value 'round scoop'
Pass Property corner-top-shape value 'superellipse(4)'
Pass Property corner-right-shape value 'superellipse(-1.5) superellipse(3)'
Fail Property corner-right-shape value 'superellipse(-1) superellipse(2)'
Pass Property corner-right-shape value 'superellipse(-1) superellipse(2)'
Pass Property corner-bottom-shape value 'scoop scoop'
Pass Property corner-inline-start-shape value 'round scoop'
Pass Property corner-block-start-shape value 'round scoop'
Pass Property corner-block-end-shape value 'superellipse(4)'
Pass Property corner-inline-end-shape value 'superellipse(-1.5) superellipse(3)'
Fail Property corner-inline-start-shape value 'superellipse(-1) superellipse(2)'
Pass Property corner-inline-start-shape value 'superellipse(-1) superellipse(2)'
Pass Property corner-block-end-shape value 'scoop scoop'