Coverage Report

Created: 2025-11-02 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}