/* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause */ #include "CalculatedStyleValue.h" #include #include namespace Web::CSS { static Optional add_the_types(Vector> const& nodes) { Optional left_type; for (auto const& value : nodes) { auto right_type = value->numeric_type(); if (!right_type.has_value()) return {}; if (left_type.has_value()) { left_type = left_type->added_to(right_type.value()); } else { left_type = right_type; } if (!left_type.has_value()) return {}; } return left_type; } static Optional add_the_types(CalculationNode const& a, CalculationNode const& b) { auto a_type = a.numeric_type(); auto b_type = b.numeric_type(); if (!a_type.has_value() || !b_type.has_value()) return {}; return a_type->added_to(*b_type); } static Optional add_the_types(CalculationNode const& a, CalculationNode const& b, CalculationNode const& c) { auto a_type = a.numeric_type(); auto b_type = b.numeric_type(); auto c_type = c.numeric_type(); if (!a_type.has_value() || !b_type.has_value() || !c_type.has_value()) return {}; auto a_and_b_type = a_type->added_to(*b_type); if (!a_and_b_type.has_value()) return {}; return a_and_b_type->added_to(*c_type); } static Optional multiply_the_types(Vector> const& nodes) { // At a * sub-expression, multiply the types of the left and right arguments. // The sub-expression’s type is the returned result. Optional left_type; for (auto const& value : nodes) { auto right_type = value->numeric_type(); if (!right_type.has_value()) return {}; if (left_type.has_value()) { left_type = left_type->multiplied_by(right_type.value()); } else { left_type = right_type; } if (!left_type.has_value()) return {}; } return left_type; } Optional CalculationNode::constant_type_from_string(StringView string) { if (string.equals_ignoring_ascii_case("e"sv)) return CalculationNode::ConstantType::E; if (string.equals_ignoring_ascii_case("pi"sv)) return CalculationNode::ConstantType::Pi; if (string.equals_ignoring_ascii_case("infinity"sv)) return CalculationNode::ConstantType::Infinity; if (string.equals_ignoring_ascii_case("-infinity"sv)) return CalculationNode::ConstantType::MinusInfinity; if (string.equals_ignoring_ascii_case("NaN"sv)) return CalculationNode::ConstantType::NaN; return {}; } CalculationNode::CalculationNode(Type type, Optional numeric_type) : m_type(type) , m_numeric_type(move(numeric_type)) { } CalculationNode::~CalculationNode() = default; static CSSNumericType numeric_type_from_calculated_style_value(CalculatedStyleValue::CalculationResult::Value const& value, CalculationContext const& context) { // https://drafts.csswg.org/css-values-4/#determine-the-type-of-a-calculation // Anything else is a terminal value, whose type is determined based on its CSS type. // (Unless otherwise specified, the type’s associated percent hint is null.) return value.visit( [](Number const&) { // -> // -> // the type is «[ ]» (empty map) return CSSNumericType {}; }, [](Length const&) { // -> // the type is «[ "length" → 1 ]» return CSSNumericType { CSSNumericType::BaseType::Length, 1 }; }, [](Angle const&) { // -> // the type is «[ "angle" → 1 ]» return CSSNumericType { CSSNumericType::BaseType::Angle, 1 }; }, [](Time const&) { // ->