LibWeb: Use CSS::Number for CalculatedStyleValue numbers

This commit is contained in:
Sam Atkins 2022-03-21 21:03:17 +00:00 committed by Andreas Kling
parent fe372cd073
commit c0d3f1a5e4
3 changed files with 25 additions and 47 deletions

View file

@ -4647,11 +4647,7 @@ Optional<CalculatedStyleValue::CalcValue> Parser::parse_calc_value(TokenStream<S
}
if (current_token.is(Token::Type::Number))
return CalculatedStyleValue::CalcValue {
CalculatedStyleValue::Number {
.is_integer = current_token.token().number_type() == Token::NumberType::Integer,
.value = static_cast<float>(current_token.token().number_value()) }
};
return CalculatedStyleValue::CalcValue { current_token.token().number() };
if (current_token.is(Token::Type::Dimension) || current_token.is(Token::Type::Percentage)) {
auto maybe_dimension = parse_dimension(current_token);
@ -4684,7 +4680,7 @@ OwnPtr<CalculatedStyleValue::CalcProductPartWithOperator> Parser::parse_calc_pro
// Note: The default value is not used or passed around.
auto product_with_operator = make<CalculatedStyleValue::CalcProductPartWithOperator>(
CalculatedStyleValue::ProductOperation::Multiply,
CalculatedStyleValue::CalcNumberValue { CalculatedStyleValue::Number { false, 0 } });
CalculatedStyleValue::CalcNumberValue { Number {} });
tokens.skip_whitespace();
@ -4723,7 +4719,7 @@ OwnPtr<CalculatedStyleValue::CalcNumberProductPartWithOperator> Parser::parse_ca
// Note: The default value is not used or passed around.
auto number_product_with_operator = make<CalculatedStyleValue::CalcNumberProductPartWithOperator>(
CalculatedStyleValue::ProductOperation::Multiply,
CalculatedStyleValue::CalcNumberValue { CalculatedStyleValue::Number { false, 0 } });
CalculatedStyleValue::CalcNumberValue { Number {} });
tokens.skip_whitespace();
@ -4756,7 +4752,7 @@ OwnPtr<CalculatedStyleValue::CalcNumberProductPartWithOperator> Parser::parse_ca
OwnPtr<CalculatedStyleValue::CalcNumberProduct> Parser::parse_calc_number_product(TokenStream<StyleComponentValueRule>& tokens)
{
auto calc_number_product = make<CalculatedStyleValue::CalcNumberProduct>(
CalculatedStyleValue::CalcNumberValue { CalculatedStyleValue::Number { false, 0 } },
CalculatedStyleValue::CalcNumberValue { Number {} },
NonnullOwnPtrVector<CalculatedStyleValue::CalcNumberProductPartWithOperator> {});
auto first_calc_number_value_or_error = parse_calc_number_value(tokens);
@ -4834,17 +4830,13 @@ Optional<CalculatedStyleValue::CalcNumberValue> Parser::parse_calc_number_value(
return {};
tokens.next_token();
return CalculatedStyleValue::CalcNumberValue {
CalculatedStyleValue::Number {
.is_integer = first.token().number_type() == Token::NumberType::Integer,
.value = static_cast<float>(first.token().number_value()) }
};
return CalculatedStyleValue::CalcNumberValue { first.token().number() };
}
OwnPtr<CalculatedStyleValue::CalcProduct> Parser::parse_calc_product(TokenStream<StyleComponentValueRule>& tokens)
{
auto calc_product = make<CalculatedStyleValue::CalcProduct>(
CalculatedStyleValue::CalcValue { CalculatedStyleValue::Number { false, 0 } },
CalculatedStyleValue::CalcValue { Number {} },
NonnullOwnPtrVector<CalculatedStyleValue::CalcProductPartWithOperator> {});
auto first_calc_value_or_error = parse_calc_value(tokens);

View file

@ -324,15 +324,9 @@ void CalculatedStyleValue::CalculationResult::add_or_subtract_internal(SumOperat
[&](Number const& number) {
auto other_number = other.m_value.get<Number>();
if (op == SumOperation::Add) {
m_value = Number {
.is_integer = number.is_integer && other_number.is_integer,
.value = number.value + other_number.value
};
m_value = number + other_number;
} else {
m_value = Number {
.is_integer = number.is_integer && other_number.is_integer,
.value = number.value - other_number.value
};
m_value = number - other_number;
}
},
[&](Angle const& angle) {
@ -437,11 +431,7 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
m_value.visit(
[&](Number const& number) {
if (other_is_number) {
auto other_number = other.m_value.get<Number>();
m_value = Number {
.is_integer = number.is_integer && other_number.is_integer,
.value = number.value * other_number.value
};
m_value = number * other.m_value.get<Number>();
} else {
// Avoid duplicating all the logic by swapping `this` and `other`.
CalculationResult new_value = other;
@ -450,20 +440,20 @@ void CalculatedStyleValue::CalculationResult::multiply_by(CalculationResult cons
}
},
[&](Angle const& angle) {
m_value = Angle::make_degrees(angle.to_degrees() * other.m_value.get<Number>().value);
m_value = Angle::make_degrees(angle.to_degrees() * other.m_value.get<Number>().value());
},
[&](Frequency const& frequency) {
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value);
m_value = Frequency::make_hertz(frequency.to_hertz() * other.m_value.get<Number>().value());
},
[&](Length const& length) {
VERIFY(layout_node);
m_value = Length::make_px(length.to_px(*layout_node) * other.m_value.get<Number>().value);
m_value = Length::make_px(length.to_px(*layout_node) * other.m_value.get<Number>().value());
},
[&](Time const& time) {
m_value = Time::make_seconds(time.to_seconds() * other.m_value.get<Number>().value);
m_value = Time::make_seconds(time.to_seconds() * other.m_value.get<Number>().value());
},
[&](Percentage const& percentage) {
m_value = Percentage { percentage.value() * other.m_value.get<Number>().value };
m_value = Percentage { percentage.value() * other.m_value.get<Number>().value() };
});
}
@ -471,15 +461,15 @@ void CalculatedStyleValue::CalculationResult::divide_by(CalculationResult const&
{
// We know from validation when resolving the type, that `other` must be a <number> or <integer>.
// Both of these are represented as a Number.
auto denominator = other.m_value.get<Number>().value;
auto denominator = other.m_value.get<Number>().value();
// FIXME: Dividing by 0 is invalid, and should be caught during parsing.
VERIFY(denominator != 0.0f);
m_value.visit(
[&](Number const& number) {
m_value = Number {
.is_integer = false,
.value = number.value / denominator
Number::Type::Number,
number.value() / denominator
};
},
[&](Angle const& angle) {
@ -508,14 +498,14 @@ String CalculatedStyleValue::to_string() const
String CalculatedStyleValue::CalcNumberValue::to_string() const
{
return value.visit(
[](Number const& number) { return String::number(number.value); },
[](Number const& number) { return String::number(number.value()); },
[](NonnullOwnPtr<CalcNumberSum> const& sum) { return String::formatted("({})", sum->to_string()); });
}
String CalculatedStyleValue::CalcValue::to_string() const
{
return value.visit(
[](Number const& number) { return String::number(number.value); },
[](Number const& number) { return String::number(number.value()); },
[](NonnullOwnPtr<CalcSum> const& sum) { return String::formatted("({})", sum->to_string()); },
[](auto const& v) { return v.to_string(); });
}
@ -691,7 +681,7 @@ Optional<float> CalculatedStyleValue::resolve_number()
{
auto result = m_expression->resolve(nullptr, {});
if (result.value().has<Number>())
return result.value().get<Number>().value;
return result.value().get<Number>().value();
return {};
}
@ -699,7 +689,7 @@ Optional<i64> CalculatedStyleValue::resolve_integer()
{
auto result = m_expression->resolve(nullptr, {});
if (result.value().has<Number>())
return lroundf(result.value().get<Number>().value);
return result.value().get<Number>().integer_value();
return {};
}
@ -860,7 +850,7 @@ Optional<CalculatedStyleValue::ResolvedType> CalculatedStyleValue::CalcValue::re
{
return value.visit(
[](Number const& number) -> Optional<CalculatedStyleValue::ResolvedType> {
return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number };
return { number.is_integer() ? ResolvedType::Integer : ResolvedType::Number };
},
[](Angle const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Angle }; },
[](Frequency const&) -> Optional<CalculatedStyleValue::ResolvedType> { return { ResolvedType::Frequency }; },
@ -874,7 +864,7 @@ Optional<CalculatedStyleValue::ResolvedType> CalculatedStyleValue::CalcNumberVal
{
return value.visit(
[](Number const& number) -> Optional<CalculatedStyleValue::ResolvedType> {
return { number.is_integer ? ResolvedType::Integer : ResolvedType::Number };
return { number.is_integer() ? ResolvedType::Integer : ResolvedType::Number };
},
[](NonnullOwnPtr<CalcNumberSum> const& sum) { return sum->resolved_type(); });
}
@ -952,7 +942,7 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcProduct::resol
VERIFY(additional_value.op == CalculatedStyleValue::ProductOperation::Divide);
auto resolved_calc_number_value = calc_number_value.resolve(layout_node, percentage_basis);
// FIXME: Checking for division by 0 should happen during parsing.
VERIFY(resolved_calc_number_value.value().get<Number>().value != 0.0f);
VERIFY(resolved_calc_number_value.value().get<Number>().value() != 0.0f);
value.divide_by(resolved_calc_number_value, layout_node);
});
}

View file

@ -27,6 +27,7 @@
#include <LibWeb/CSS/Display.h>
#include <LibWeb/CSS/Frequency.h>
#include <LibWeb/CSS/Length.h>
#include <LibWeb/CSS/Number.h>
#include <LibWeb/CSS/Parser/StyleComponentValueRule.h>
#include <LibWeb/CSS/Percentage.h>
#include <LibWeb/CSS/PropertyID.h>
@ -808,11 +809,6 @@ public:
Divide,
};
struct Number {
bool is_integer;
float value;
};
using PercentageBasis = Variant<Empty, Angle, Frequency, Length, Time>;
class CalculationResult {