mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-05 07:41:01 +00:00
LibWeb: Implement interpolation of edge values
This commit is contained in:
parent
31dea89fe0
commit
0beb22f19e
Notes:
github-actions[bot]
2025-04-23 08:39:39 +00:00
Author: https://github.com/tcl3
Commit: 0beb22f19e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4315
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/shannonbooth
3 changed files with 47 additions and 21 deletions
|
@ -577,6 +577,14 @@ NonnullRefPtr<CSSStyleValue const> interpolate_value(DOM::Element& element, Calc
|
||||||
return delta >= 0.5f ? to : from;
|
return delta >= 0.5f ? to : from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto interpolate_length_percentage = [](LengthPercentage const& from, LengthPercentage const& to, float delta) -> Optional<LengthPercentage> {
|
||||||
|
if (from.is_length() && to.is_length())
|
||||||
|
return Length::make_px(interpolate_raw(from.length().raw_value(), to.length().raw_value(), delta));
|
||||||
|
if (from.is_percentage() && to.is_percentage())
|
||||||
|
return Percentage(interpolate_raw(from.percentage().value(), to.percentage().value(), delta));
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
switch (from.type()) {
|
switch (from.type()) {
|
||||||
case CSSStyleValue::Type::Angle:
|
case CSSStyleValue::Type::Angle:
|
||||||
return AngleStyleValue::create(Angle::make_degrees(interpolate_raw(from.as_angle().angle().to_degrees(), to.as_angle().angle().to_degrees(), delta)));
|
return AngleStyleValue::create(Angle::make_degrees(interpolate_raw(from.as_angle().angle().to_degrees(), to.as_angle().angle().to_degrees(), delta)));
|
||||||
|
@ -586,6 +594,17 @@ NonnullRefPtr<CSSStyleValue const> interpolate_value(DOM::Element& element, Calc
|
||||||
layout_node = *node;
|
layout_node = *node;
|
||||||
return CSSColorValue::create_from_color(interpolate_color(from.to_color(layout_node), to.to_color(layout_node), delta), ColorSyntax::Modern);
|
return CSSColorValue::create_from_color(interpolate_color(from.to_color(layout_node), to.to_color(layout_node), delta), ColorSyntax::Modern);
|
||||||
}
|
}
|
||||||
|
case CSSStyleValue::Type::Edge: {
|
||||||
|
auto resolved_from = from.as_edge().resolved_value(calculation_context);
|
||||||
|
auto resolved_to = to.as_edge().resolved_value(calculation_context);
|
||||||
|
auto const& edge = delta >= 0.5f ? resolved_to->edge() : resolved_from->edge();
|
||||||
|
auto const& from_offset = resolved_from->offset();
|
||||||
|
auto const& to_offset = resolved_to->offset();
|
||||||
|
if (auto interpolated_value = interpolate_length_percentage(from_offset, to_offset, delta); interpolated_value.has_value())
|
||||||
|
return EdgeStyleValue::create(edge, *interpolated_value);
|
||||||
|
|
||||||
|
return delta >= 0.5f ? to : from;
|
||||||
|
}
|
||||||
case CSSStyleValue::Type::Integer: {
|
case CSSStyleValue::Type::Integer: {
|
||||||
// https://drafts.csswg.org/css-values/#combine-integers
|
// https://drafts.csswg.org/css-values/#combine-integers
|
||||||
// Interpolation of <integer> is defined as Vresult = round((1 - p) × VA + p × VB);
|
// Interpolation of <integer> is defined as Vresult = round((1 - p) × VA + p × VB);
|
||||||
|
|
|
@ -11,27 +11,9 @@ namespace Web::CSS {
|
||||||
String EdgeStyleValue::to_string(SerializationMode mode) const
|
String EdgeStyleValue::to_string(SerializationMode mode) const
|
||||||
{
|
{
|
||||||
if (mode == CSSStyleValue::SerializationMode::ResolvedValue) {
|
if (mode == CSSStyleValue::SerializationMode::ResolvedValue) {
|
||||||
if (edge() == PositionEdge::Right || edge() == PositionEdge::Bottom) {
|
|
||||||
if (offset().is_percentage()) {
|
|
||||||
auto flipped_percentage = 100 - offset().percentage().value();
|
|
||||||
return Percentage(flipped_percentage).to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Figure out how to get the proper calculation context here
|
// FIXME: Figure out how to get the proper calculation context here
|
||||||
CalculationContext context = {};
|
CalculationContext context {};
|
||||||
|
return resolved_value(context)->offset().to_string();
|
||||||
Vector<NonnullRefPtr<CalculationNode const>> sum_parts;
|
|
||||||
sum_parts.append(NumericCalculationNode::create(Percentage(100), context));
|
|
||||||
if (offset().is_length()) {
|
|
||||||
sum_parts.append(NegateCalculationNode::create(NumericCalculationNode::create(offset().length(), context)));
|
|
||||||
} else {
|
|
||||||
// FIXME: Flip calculated offsets (convert CalculatedStyleValue to CalculationNode, then negate and append)
|
|
||||||
return to_string(CSSStyleValue::SerializationMode::Normal);
|
|
||||||
}
|
|
||||||
auto flipped_absolute = CalculatedStyleValue::create(SumCalculationNode::create(move(sum_parts)), CSSNumericType(CSSNumericType::BaseType::Length, 1), context);
|
|
||||||
return flipped_absolute->to_string(mode);
|
|
||||||
}
|
|
||||||
return offset().to_string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
@ -48,4 +30,27 @@ String EdgeStyleValue::to_string(SerializationMode mode) const
|
||||||
return builder.to_string_without_validation();
|
return builder.to_string_without_validation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValueComparingNonnullRefPtr<EdgeStyleValue const> EdgeStyleValue::resolved_value(CalculationContext context) const
|
||||||
|
{
|
||||||
|
if (edge() == PositionEdge::Right || edge() == PositionEdge::Bottom) {
|
||||||
|
if (offset().is_percentage()) {
|
||||||
|
auto flipped_percentage = 100 - offset().percentage().value();
|
||||||
|
return create({}, Percentage(flipped_percentage));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<NonnullRefPtr<CalculationNode const>> sum_parts;
|
||||||
|
sum_parts.append(NumericCalculationNode::create(Percentage(100), context));
|
||||||
|
if (offset().is_length()) {
|
||||||
|
sum_parts.append(NegateCalculationNode::create(NumericCalculationNode::create(offset().length(), context)));
|
||||||
|
} else {
|
||||||
|
// FIXME: Flip calculated offsets (convert CalculatedStyleValue to CalculationNode, then negate and append)
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto flipped_absolute = CalculatedStyleValue::create(SumCalculationNode::create(move(sum_parts)), CSSNumericType(CSSNumericType::BaseType::Length, 1), context);
|
||||||
|
return create({}, flipped_absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
|
|
||||||
virtual String to_string(SerializationMode) const override;
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
|
||||||
|
ValueComparingNonnullRefPtr<EdgeStyleValue const> resolved_value(CalculationContext context) const;
|
||||||
|
|
||||||
bool properties_equal(EdgeStyleValue const& other) const { return m_properties == other.m_properties; }
|
bool properties_equal(EdgeStyleValue const& other) const { return m_properties == other.m_properties; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue