From db04b5687d4b15c4f51b3e30e386acb95c7221bd Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 24 Jan 2022 17:38:29 +0000 Subject: [PATCH] LibWeb: Move calc()-resolution code from Length to CalculatedStyleValue The code is unchanged, just moved. --- Userland/Libraries/LibWeb/CSS/Length.cpp | 119 +------------------ Userland/Libraries/LibWeb/CSS/Length.h | 2 - Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 113 ++++++++++++++++++ Userland/Libraries/LibWeb/CSS/StyleValue.h | 1 + 4 files changed, 115 insertions(+), 120 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/Length.cpp b/Userland/Libraries/LibWeb/CSS/Length.cpp index 0f3d873a51..f74bebc9b2 100644 --- a/Userland/Libraries/LibWeb/CSS/Length.cpp +++ b/Userland/Libraries/LibWeb/CSS/Length.cpp @@ -55,7 +55,7 @@ Length Length::resolved(Length const& fallback_for_undefined, Layout::Node const if (is_undefined()) return fallback_for_undefined; if (is_calculated()) - return Length(resolve_calculated_value(layout_node), Type::Px); + return m_calculated_style->resolve_length(layout_node).release_value(); if (is_relative()) return make_px(to_px(layout_node)); return *this; @@ -112,123 +112,6 @@ float Length::to_px(Layout::Node const& layout_node) const return to_px(viewport_rect, layout_node.font().metrics('M'), root_element->layout_node()->font().presentation_size()); } -static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node); -static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const&); -static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node); -static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node); -static float resolve_calc_number_sum(NonnullOwnPtr const&); -static float resolve_calc_number_product(NonnullOwnPtr const&); - -float Length::resolve_calculated_value(Layout::Node const& layout_node) const -{ - if (!m_calculated_style) - return 0.0f; - - auto& expression = m_calculated_style->expression(); - - auto length = resolve_calc_sum(expression, layout_node); - return length; -}; - -static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node) -{ - return calc_value.visit( - [](float value) { return value; }, - [&](Length const& length) { - return length.resolved_or_zero(layout_node).to_px(layout_node); - }, - [&](NonnullOwnPtr const& calc_sum) { - return resolve_calc_sum(calc_sum, layout_node); - }, - [](auto&) { - VERIFY_NOT_REACHED(); - return 0.0f; - }); -} - -static float resolve_calc_number_product(NonnullOwnPtr const& calc_number_product) -{ - auto value = resolve_calc_number_value(calc_number_product->first_calc_number_value); - - for (auto& additional_number_value : calc_number_product->zero_or_more_additional_calc_number_values) { - auto additional_value = resolve_calc_number_value(additional_number_value.value); - if (additional_number_value.op == CalculatedStyleValue::CalcNumberProductPartWithOperator::Multiply) - value *= additional_value; - else if (additional_number_value.op == CalculatedStyleValue::CalcNumberProductPartWithOperator::Divide) - value /= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - -static float resolve_calc_number_sum(NonnullOwnPtr const& calc_number_sum) -{ - auto value = resolve_calc_number_product(calc_number_sum->first_calc_number_product); - - for (auto& additional_product : calc_number_sum->zero_or_more_additional_calc_number_products) { - auto additional_value = resolve_calc_number_product(additional_product.calc_number_product); - if (additional_product.op == CSS::CalculatedStyleValue::CalcNumberSumPartWithOperator::Add) - value += additional_value; - else if (additional_product.op == CSS::CalculatedStyleValue::CalcNumberSumPartWithOperator::Subtract) - value -= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - -static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const& number_value) -{ - return number_value.visit( - [](float number) { return number; }, - [](NonnullOwnPtr const& calc_number_sum) { - return resolve_calc_number_sum(calc_number_sum); - }); -} - -static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node) -{ - auto value = resolve_calc_value(calc_product->first_calc_value, layout_node); - - for (auto& additional_value : calc_product->zero_or_more_additional_calc_values) { - additional_value.value.visit( - [&](CalculatedStyleValue::CalcValue const& calc_value) { - if (additional_value.op != CalculatedStyleValue::CalcProductPartWithOperator::Multiply) - VERIFY_NOT_REACHED(); - auto resolved_value = resolve_calc_value(calc_value, layout_node); - value *= resolved_value; - }, - [&](CalculatedStyleValue::CalcNumberValue const& calc_number_value) { - if (additional_value.op != CalculatedStyleValue::CalcProductPartWithOperator::Divide) - VERIFY_NOT_REACHED(); - auto resolved_calc_number_value = resolve_calc_number_value(calc_number_value); - value /= resolved_calc_number_value; - }); - } - - return value; -} - -static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node) -{ - auto value = resolve_calc_product(calc_sum->first_calc_product, layout_node); - - for (auto& additional_product : calc_sum->zero_or_more_additional_calc_products) { - auto additional_value = resolve_calc_product(additional_product.calc_product, layout_node); - if (additional_product.op == CalculatedStyleValue::CalcSumPartWithOperator::Operation::Add) - value += additional_value; - else if (additional_product.op == CalculatedStyleValue::CalcSumPartWithOperator::Operation::Subtract) - value -= additional_value; - else - VERIFY_NOT_REACHED(); - } - - return value; -} - const char* Length::unit_name() const { switch (m_type) { diff --git a/Userland/Libraries/LibWeb/CSS/Length.h b/Userland/Libraries/LibWeb/CSS/Length.h index ed7335c6a2..3f999b2f04 100644 --- a/Userland/Libraries/LibWeb/CSS/Length.h +++ b/Userland/Libraries/LibWeb/CSS/Length.h @@ -136,8 +136,6 @@ public: float relative_length_to_px(Gfx::IntRect const& viewport_rect, Gfx::FontMetrics const& font_metrics, float root_font_size) const; private: - float resolve_calculated_value(Layout::Node const& layout_node) const; - const char* unit_name() const; Type m_type { Type::Undefined }; diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index 0d13528d84..9bd8639338 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -273,6 +274,118 @@ String BoxShadowStyleValue::to_string() const return String::formatted("{} {} {} {}", m_offset_x.to_string(), m_offset_y.to_string(), m_blur_radius.to_string(), m_color.to_string()); } +static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node); +static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const&); +static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node); +static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node); +static float resolve_calc_number_sum(NonnullOwnPtr const&); +static float resolve_calc_number_product(NonnullOwnPtr const&); + +Optional CalculatedStyleValue::resolve_length(Layout::Node const& layout_node) const +{ + auto length = resolve_calc_sum(m_expression, layout_node); + return Length::make_px(length); +} + +static float resolve_calc_value(CalculatedStyleValue::CalcValue const& calc_value, Layout::Node const& layout_node) +{ + return calc_value.visit( + [](float value) { return value; }, + [&](Length const& length) { + return length.resolved_or_zero(layout_node).to_px(layout_node); + }, + [&](NonnullOwnPtr const& calc_sum) { + return resolve_calc_sum(calc_sum, layout_node); + }, + [](auto&) { + VERIFY_NOT_REACHED(); + return 0.0f; + }); +} + +static float resolve_calc_number_product(NonnullOwnPtr const& calc_number_product) +{ + auto value = resolve_calc_number_value(calc_number_product->first_calc_number_value); + + for (auto& additional_number_value : calc_number_product->zero_or_more_additional_calc_number_values) { + auto additional_value = resolve_calc_number_value(additional_number_value.value); + if (additional_number_value.op == CalculatedStyleValue::CalcNumberProductPartWithOperator::Multiply) + value *= additional_value; + else if (additional_number_value.op == CalculatedStyleValue::CalcNumberProductPartWithOperator::Divide) + value /= additional_value; + else + VERIFY_NOT_REACHED(); + } + + return value; +} + +static float resolve_calc_number_sum(NonnullOwnPtr const& calc_number_sum) +{ + auto value = resolve_calc_number_product(calc_number_sum->first_calc_number_product); + + for (auto& additional_product : calc_number_sum->zero_or_more_additional_calc_number_products) { + auto additional_value = resolve_calc_number_product(additional_product.calc_number_product); + if (additional_product.op == CSS::CalculatedStyleValue::CalcNumberSumPartWithOperator::Add) + value += additional_value; + else if (additional_product.op == CSS::CalculatedStyleValue::CalcNumberSumPartWithOperator::Subtract) + value -= additional_value; + else + VERIFY_NOT_REACHED(); + } + + return value; +} + +static float resolve_calc_number_value(CalculatedStyleValue::CalcNumberValue const& number_value) +{ + return number_value.visit( + [](float number) { return number; }, + [](NonnullOwnPtr const& calc_number_sum) { + return resolve_calc_number_sum(calc_number_sum); + }); +} + +static float resolve_calc_product(NonnullOwnPtr const& calc_product, Layout::Node const& layout_node) +{ + auto value = resolve_calc_value(calc_product->first_calc_value, layout_node); + + for (auto& additional_value : calc_product->zero_or_more_additional_calc_values) { + additional_value.value.visit( + [&](CalculatedStyleValue::CalcValue const& calc_value) { + if (additional_value.op != CalculatedStyleValue::CalcProductPartWithOperator::Multiply) + VERIFY_NOT_REACHED(); + auto resolved_value = resolve_calc_value(calc_value, layout_node); + value *= resolved_value; + }, + [&](CalculatedStyleValue::CalcNumberValue const& calc_number_value) { + if (additional_value.op != CalculatedStyleValue::CalcProductPartWithOperator::Divide) + VERIFY_NOT_REACHED(); + auto resolved_calc_number_value = resolve_calc_number_value(calc_number_value); + value /= resolved_calc_number_value; + }); + } + + return value; +} + +static float resolve_calc_sum(NonnullOwnPtr const& calc_sum, Layout::Node const& layout_node) +{ + auto value = resolve_calc_product(calc_sum->first_calc_product, layout_node); + + for (auto& additional_product : calc_sum->zero_or_more_additional_calc_products) { + auto additional_value = resolve_calc_product(additional_product.calc_product, layout_node); + if (additional_product.op == CalculatedStyleValue::CalcSumPartWithOperator::Operation::Add) + value += additional_value; + else if (additional_product.op == CalculatedStyleValue::CalcSumPartWithOperator::Operation::Subtract) + value -= additional_value; + else + VERIFY_NOT_REACHED(); + } + + return value; +} + // https://www.w3.org/TR/css-color-4/#serializing-sRGB-values String ColorStyleValue::to_string() const { diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 2d70907bf7..ffe91f78c6 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -746,6 +746,7 @@ public: String to_string() const override { return m_expression_string; } NonnullOwnPtr const& expression() const { return m_expression; } + Optional resolve_length(Layout::Node const& layout_node) const; private: explicit CalculatedStyleValue(String const& expression_string, NonnullOwnPtr calc_sum)