LibWeb: Interpolate inset() function by computed value

This commit is contained in:
Tim Ledbetter 2025-09-13 13:54:02 +01:00 committed by Sam Atkins
commit be94c8d456
Notes: github-actions[bot] 2025-09-15 09:36:31 +00:00
4 changed files with 586 additions and 38 deletions

View file

@ -1194,6 +1194,41 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
interpolated_left.release_nonnull(),
from_border_image_slice.fill());
}
case StyleValue::Type::BasicShape: {
// https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation
auto& from_shape = from.as_basic_shape().basic_shape();
auto& to_shape = to.as_basic_shape().basic_shape();
if (from_shape.index() != to_shape.index())
return {};
auto interpolate_length_box = [](CalculationContext const& calculation_context, LengthBox const& from, LengthBox const& to, float delta) -> Optional<LengthBox> {
auto interpolated_top = interpolate_length_percentage_or_auto(calculation_context, from.top(), to.top(), delta);
auto interpolated_right = interpolate_length_percentage_or_auto(calculation_context, from.right(), to.right(), delta);
auto interpolated_bottom = interpolate_length_percentage_or_auto(calculation_context, from.bottom(), to.bottom(), delta);
auto interpolated_left = interpolate_length_percentage_or_auto(calculation_context, from.left(), to.left(), delta);
if (!interpolated_top.has_value() || !interpolated_right.has_value() || !interpolated_bottom.has_value() || !interpolated_left.has_value())
return {};
return LengthBox { *interpolated_top, *interpolated_right, *interpolated_bottom, *interpolated_left };
};
auto interpolated_shape = from_shape.visit(
[&](Inset const& from_inset) -> Optional<BasicShape> {
// If both shapes are of type inset(), interpolate between each value in the shape functions.
auto& to_inset = to_shape.get<Inset>();
auto interpolated_inset_box = interpolate_length_box(calculation_context, from_inset.inset_box, to_inset.inset_box, delta);
if (!interpolated_inset_box.has_value())
return {};
return Inset { *interpolated_inset_box };
},
[](auto&) -> Optional<BasicShape> {
return {};
});
if (!interpolated_shape.has_value())
return {};
return BasicShapeStyleValue::create(*interpolated_shape);
}
case StyleValue::Type::BorderRadius: {
auto const& from_horizontal_radius = from.as_border_radius().horizontal_radius();
auto const& to_horizontal_radius = to.as_border_radius().horizontal_radius();