From f30b0428902c1b8944853cb95e5bab3f137b9772 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Fri, 24 Mar 2023 16:09:41 +0000 Subject: [PATCH] LibWeb: Split ConicGradientStyleValue out of StyleValue.{h,cpp} --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 1 + Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 50 +---------- Userland/Libraries/LibWeb/CSS/StyleValue.h | 53 ------------ .../StyleValues/ConicGradientStyleValue.cpp | 85 +++++++++++++++++++ .../CSS/StyleValues/ConicGradientStyleValue.h | 69 +++++++++++++++ .../LibWeb/Painting/GradientPainting.cpp | 1 + 7 files changed, 158 insertions(+), 102 deletions(-) create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 6181bfa419a..59b8b5636cb 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -72,6 +72,7 @@ set(SOURCES CSS/StyleValues/BorderRadiusStyleValue.cpp CSS/StyleValues/BorderStyleValue.cpp CSS/StyleValues/ColorStyleValue.cpp + CSS/StyleValues/ConicGradientStyleValue.cpp CSS/StyleValues/ContentStyleValue.cpp CSS/StyleValues/FilterValueListStyleValue.cpp CSS/StyleValues/FlexFlowStyleValue.cpp diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index a01a65df1e5..b199374562e 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index ad48ace59c7..a2adfccbf3b 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1455,55 +1456,6 @@ void RadialGradientStyleValue::paint(PaintContext& context, DevicePixelRect cons context.rounded_device_size(m_resolved->gradient_size.to_type())); } -ErrorOr ConicGradientStyleValue::to_string() const -{ - StringBuilder builder; - if (is_repeating()) - TRY(builder.try_append("repeating-"sv)); - TRY(builder.try_append("conic-gradient("sv)); - bool has_from_angle = false; - bool has_at_position = false; - if ((has_from_angle = m_properties.from_angle.to_degrees() != 0)) - TRY(builder.try_appendff("from {}", TRY(m_properties.from_angle.to_string()))); - if ((has_at_position = m_properties.position != PositionValue::center())) { - if (has_from_angle) - TRY(builder.try_append(' ')); - TRY(builder.try_appendff("at "sv)); - TRY(m_properties.position.serialize(builder)); - } - if (has_from_angle || has_at_position) - TRY(builder.try_append(", "sv)); - TRY(serialize_color_stop_list(builder, m_properties.color_stop_list)); - TRY(builder.try_append(')')); - return builder.to_string(); -} - -void ConicGradientStyleValue::resolve_for_size(Layout::Node const& node, CSSPixelSize size) const -{ - if (!m_resolved.has_value()) - m_resolved = ResolvedData { Painting::resolve_conic_gradient_data(node, *this), {} }; - m_resolved->position = m_properties.position.resolved(node, CSSPixelRect { { 0, 0 }, size }); -} - -void ConicGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const -{ - VERIFY(m_resolved.has_value()); - Painting::paint_conic_gradient(context, dest_rect, m_resolved->data, context.rounded_device_point(m_resolved->position)); -} - -bool ConicGradientStyleValue::equals(StyleValue const& other) const -{ - if (type() != other.type()) - return false; - auto& other_gradient = other.as_conic_gradient(); - return m_properties == other_gradient.m_properties; -} - -float ConicGradientStyleValue::angle_degrees() const -{ - return m_properties.from_angle.to_degrees(); -} - ErrorOr ListStyleStyleValue::to_string() const { return String::formatted("{} {} {}", TRY(m_properties.position->to_string()), TRY(m_properties.image->to_string()), TRY(m_properties.style_type->to_string())); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index 0029f945c0c..036473c7e65 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -759,59 +759,6 @@ private: mutable Optional m_resolved; }; -class ConicGradientStyleValue final : public AbstractImageStyleValue { -public: - static ValueComparingNonnullRefPtr create(Angle from_angle, PositionValue position, Vector color_stop_list, GradientRepeating repeating) - { - VERIFY(color_stop_list.size() >= 2); - return adopt_ref(*new ConicGradientStyleValue(from_angle, position, move(color_stop_list), repeating)); - } - - virtual ErrorOr to_string() const override; - - void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering) const override; - - virtual bool equals(StyleValue const& other) const override; - - Vector const& color_stop_list() const - { - return m_properties.color_stop_list; - } - - float angle_degrees() const; - - bool is_paintable() const override { return true; } - - void resolve_for_size(Layout::Node const&, CSSPixelSize) const override; - - virtual ~ConicGradientStyleValue() override = default; - - bool is_repeating() const { return m_properties.repeating == GradientRepeating::Yes; } - -private: - ConicGradientStyleValue(Angle from_angle, PositionValue position, Vector color_stop_list, GradientRepeating repeating) - : AbstractImageStyleValue(Type::ConicGradient) - , m_properties { .from_angle = from_angle, .position = position, .color_stop_list = move(color_stop_list), .repeating = repeating } - { - } - - struct Properties { - // FIXME: Support - Angle from_angle; - PositionValue position; - Vector color_stop_list; - GradientRepeating repeating; - bool operator==(Properties const&) const = default; - } m_properties; - - struct ResolvedData { - Painting::ConicGradientData data; - CSSPixelPoint position; - }; - - mutable Optional m_resolved; -}; - class LinearGradientStyleValue final : public AbstractImageStyleValue { public: using GradientDirection = Variant; diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp new file mode 100644 index 00000000000..d0248be2189 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp @@ -0,0 +1,85 @@ +/* + * 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 "ConicGradientStyleValue.h" +#include + +namespace Web::CSS { + +// FIXME: Temporary until AbstractImageStyleValue.h exists. (And the Serialize.h include above.) +static ErrorOr serialize_color_stop_list(StringBuilder& builder, auto const& color_stop_list) +{ + bool first = true; + for (auto const& element : color_stop_list) { + if (!first) + TRY(builder.try_append(", "sv)); + + if (element.transition_hint.has_value()) + TRY(builder.try_appendff("{}, "sv, TRY(element.transition_hint->value.to_string()))); + + TRY(serialize_a_srgb_value(builder, element.color_stop.color)); + for (auto position : Array { &element.color_stop.position, &element.color_stop.second_position }) { + if (position->has_value()) + TRY(builder.try_appendff(" {}"sv, TRY((*position)->to_string()))); + } + first = false; + } + return {}; +} + +ErrorOr ConicGradientStyleValue::to_string() const +{ + StringBuilder builder; + if (is_repeating()) + TRY(builder.try_append("repeating-"sv)); + TRY(builder.try_append("conic-gradient("sv)); + bool has_from_angle = false; + bool has_at_position = false; + if ((has_from_angle = m_properties.from_angle.to_degrees() != 0)) + TRY(builder.try_appendff("from {}", TRY(m_properties.from_angle.to_string()))); + if ((has_at_position = m_properties.position != PositionValue::center())) { + if (has_from_angle) + TRY(builder.try_append(' ')); + TRY(builder.try_appendff("at "sv)); + TRY(m_properties.position.serialize(builder)); + } + if (has_from_angle || has_at_position) + TRY(builder.try_append(", "sv)); + TRY(serialize_color_stop_list(builder, m_properties.color_stop_list)); + TRY(builder.try_append(')')); + return builder.to_string(); +} + +void ConicGradientStyleValue::resolve_for_size(Layout::Node const& node, CSSPixelSize size) const +{ + if (!m_resolved.has_value()) + m_resolved = ResolvedData { Painting::resolve_conic_gradient_data(node, *this), {} }; + m_resolved->position = m_properties.position.resolved(node, CSSPixelRect { { 0, 0 }, size }); +} + +void ConicGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const +{ + VERIFY(m_resolved.has_value()); + Painting::paint_conic_gradient(context, dest_rect, m_resolved->data, context.rounded_device_point(m_resolved->position)); +} + +bool ConicGradientStyleValue::equals(StyleValue const& other) const +{ + if (type() != other.type()) + return false; + auto& other_gradient = other.as_conic_gradient(); + return m_properties == other_gradient.m_properties; +} + +float ConicGradientStyleValue::angle_degrees() const +{ + return m_properties.from_angle.to_degrees(); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h new file mode 100644 index 00000000000..82a01d4156f --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h @@ -0,0 +1,69 @@ +/* + * 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 + */ + +#pragma once + +#include + +namespace Web::CSS { + +class ConicGradientStyleValue final : public AbstractImageStyleValue { +public: + static ValueComparingNonnullRefPtr create(Angle from_angle, PositionValue position, Vector color_stop_list, GradientRepeating repeating) + { + VERIFY(color_stop_list.size() >= 2); + return adopt_ref(*new ConicGradientStyleValue(from_angle, position, move(color_stop_list), repeating)); + } + + virtual ErrorOr to_string() const override; + + void paint(PaintContext&, DevicePixelRect const& dest_rect, CSS::ImageRendering) const override; + + virtual bool equals(StyleValue const& other) const override; + + Vector const& color_stop_list() const + { + return m_properties.color_stop_list; + } + + float angle_degrees() const; + + bool is_paintable() const override { return true; } + + void resolve_for_size(Layout::Node const&, CSSPixelSize) const override; + + virtual ~ConicGradientStyleValue() override = default; + + bool is_repeating() const { return m_properties.repeating == GradientRepeating::Yes; } + +private: + ConicGradientStyleValue(Angle from_angle, PositionValue position, Vector color_stop_list, GradientRepeating repeating) + : AbstractImageStyleValue(Type::ConicGradient) + , m_properties { .from_angle = from_angle, .position = position, .color_stop_list = move(color_stop_list), .repeating = repeating } + { + } + + struct Properties { + // FIXME: Support + Angle from_angle; + PositionValue position; + Vector color_stop_list; + GradientRepeating repeating; + bool operator==(Properties const&) const = default; + } m_properties; + + struct ResolvedData { + Painting::ConicGradientData data; + CSSPixelPoint position; + }; + + mutable Optional m_resolved; +}; + +} diff --git a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp index 128f1417ad7..904024a2b26 100644 --- a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Web::Painting {