/* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen * Copyright (c) 2021-2023, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause */ #include "CalculatedStyleValue.h" #include namespace Web::CSS { void CalculatedStyleValue::CalculationResult::add(CalculationResult const& other, Layout::Node const* layout_node, PercentageBasis const& percentage_basis) { add_or_subtract_internal(SumOperation::Add, other, layout_node, percentage_basis); } void CalculatedStyleValue::CalculationResult::subtract(CalculationResult const& other, Layout::Node const* layout_node, PercentageBasis const& percentage_basis) { add_or_subtract_internal(SumOperation::Subtract, other, layout_node, percentage_basis); } void CalculatedStyleValue::CalculationResult::add_or_subtract_internal(SumOperation op, CalculationResult const& other, Layout::Node const* layout_node, PercentageBasis const& percentage_basis) { // We know from validation when resolving the type, that "both sides have the same type, or that one side is a and the other is an ". // Though, having the same type may mean that one side is a and the other a . // Note: This is almost identical to ::add() m_value.visit( [&](Number const& number) { auto other_number = other.m_value.get(); if (op == SumOperation::Add) { m_value = number + other_number; } else { m_value = number - other_number; } }, [&](Angle const& angle) { auto this_degrees = angle.to_degrees(); if (other.m_value.has()) { auto other_degrees = other.m_value.get().to_degrees(); if (op == SumOperation::Add) m_value = Angle::make_degrees(this_degrees + other_degrees); else m_value = Angle::make_degrees(this_degrees - other_degrees); } else { VERIFY(percentage_basis.has()); auto other_degrees = percentage_basis.get().percentage_of(other.m_value.get()).to_degrees(); if (op == SumOperation::Add) m_value = Angle::make_degrees(this_degrees + other_degrees); else m_value = Angle::make_degrees(this_degrees - other_degrees); } }, [&](Frequency const& frequency) { auto this_hertz = frequency.to_hertz(); if (other.m_value.has()) { auto other_hertz = other.m_value.get().to_hertz(); if (op == SumOperation::Add) m_value = Frequency::make_hertz(this_hertz + other_hertz); else m_value = Frequency::make_hertz(this_hertz - other_hertz); } else { VERIFY(percentage_basis.has()); auto other_hertz = percentage_basis.get().percentage_of(other.m_value.get()).to_hertz(); if (op == SumOperation::Add) m_value = Frequency::make_hertz(this_hertz + other_hertz); else m_value = Frequency::make_hertz(this_hertz - other_hertz); } }, [&](Length const& length) { auto this_px = length.to_px(*layout_node); if (other.m_value.has()) { auto other_px = other.m_value.get().to_px(*layout_node); if (op == SumOperation::Add) m_value = Length::make_px(this_px + other_px); else m_value = Length::make_px(this_px - other_px); } else { VERIFY(percentage_basis.has()); auto other_px = percentage_basis.get().percentage_of(other.m_value.get()).to_px(*layout_node); if (op == SumOperation::Add) m_value = Length::make_px(this_px + other_px); else m_value = Length::make_px(this_px - other_px); } }, [&](Time const& time) { auto this_seconds = time.to_seconds(); if (other.m_value.has