/src/serenity/Userland/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org> |
4 | | * Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org> |
5 | | * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech> |
6 | | * |
7 | | * SPDX-License-Identifier: BSD-2-Clause |
8 | | */ |
9 | | |
10 | | #pragma once |
11 | | |
12 | | #include <AK/Vector.h> |
13 | | #include <LibWeb/CSS/Angle.h> |
14 | | #include <LibWeb/CSS/Percentage.h> |
15 | | #include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h> |
16 | | #include <LibWeb/Painting/GradientPainting.h> |
17 | | |
18 | | namespace Web::CSS { |
19 | | |
20 | | // Note: The sides must be before the corners in this enum (as this order is used in parsing). |
21 | | enum class SideOrCorner { |
22 | | Top, |
23 | | Bottom, |
24 | | Left, |
25 | | Right, |
26 | | TopLeft, |
27 | | TopRight, |
28 | | BottomLeft, |
29 | | BottomRight |
30 | | }; |
31 | | |
32 | | class LinearGradientStyleValue final : public AbstractImageStyleValue { |
33 | | public: |
34 | | using GradientDirection = Variant<Angle, SideOrCorner>; |
35 | | |
36 | | enum class GradientType { |
37 | | Standard, |
38 | | WebKit |
39 | | }; |
40 | | |
41 | | static ValueComparingNonnullRefPtr<LinearGradientStyleValue> create(GradientDirection direction, Vector<LinearColorStopListElement> color_stop_list, GradientType type, GradientRepeating repeating) |
42 | 0 | { |
43 | 0 | VERIFY(color_stop_list.size() >= 2); |
44 | 0 | return adopt_ref(*new (nothrow) LinearGradientStyleValue(direction, move(color_stop_list), type, repeating)); |
45 | 0 | } |
46 | | |
47 | | virtual String to_string() const override; |
48 | 0 | virtual ~LinearGradientStyleValue() override = default; |
49 | | virtual bool equals(CSSStyleValue const& other) const override; |
50 | | |
51 | | Vector<LinearColorStopListElement> const& color_stop_list() const |
52 | 0 | { |
53 | 0 | return m_properties.color_stop_list; |
54 | 0 | } |
55 | | |
56 | 0 | bool is_repeating() const { return m_properties.repeating == GradientRepeating::Yes; } |
57 | | |
58 | | float angle_degrees(CSSPixelSize gradient_size) const; |
59 | | |
60 | | void resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const&, CSSPixelSize) const override; |
61 | | |
62 | 0 | bool is_paintable() const override { return true; } |
63 | | void paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering image_rendering, Vector<Gfx::Path> const& clip_paths = {}) const override; |
64 | | |
65 | | private: |
66 | | LinearGradientStyleValue(GradientDirection direction, Vector<LinearColorStopListElement> color_stop_list, GradientType type, GradientRepeating repeating) |
67 | 0 | : AbstractImageStyleValue(Type::LinearGradient) |
68 | 0 | , m_properties { .direction = direction, .color_stop_list = move(color_stop_list), .gradient_type = type, .repeating = repeating } |
69 | 0 | { |
70 | 0 | } |
71 | | |
72 | | struct Properties { |
73 | | GradientDirection direction; |
74 | | Vector<LinearColorStopListElement> color_stop_list; |
75 | | GradientType gradient_type; |
76 | | GradientRepeating repeating; |
77 | 0 | bool operator==(Properties const&) const = default; |
78 | | } m_properties; |
79 | | |
80 | | struct ResolvedData { |
81 | | Painting::LinearGradientData data; |
82 | | CSSPixelSize size; |
83 | | }; |
84 | | |
85 | | mutable Optional<ResolvedData> m_resolved; |
86 | | }; |
87 | | |
88 | | } |