Coverage Report

Created: 2025-09-05 06:52

/src/serenity/Userland/Libraries/LibLine/Style.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2020-2022, the SerenityOS developers.
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/ByteString.h>
10
#include <AK/Types.h>
11
#include <AK/Utf8View.h>
12
#include <AK/Vector.h>
13
14
namespace Line {
15
16
class Style {
17
public:
18
0
    bool operator==(Style const&) const = default;
19
20
    enum class XtermColor : int {
21
        Default = 9,
22
        Black = 0,
23
        Red,
24
        Green,
25
        Yellow,
26
        Blue,
27
        Magenta,
28
        Cyan,
29
        White,
30
        Unchanged,
31
    };
32
33
    struct AnchoredTag {
34
    };
35
    struct UnderlineTag {
36
    };
37
    struct BoldTag {
38
    };
39
    struct ItalicTag {
40
    };
41
    struct Color {
42
0
        bool operator==(Color const&) const = default;
43
44
        explicit Color(XtermColor color)
45
0
            : m_xterm_color(color)
46
0
            , m_is_rgb(false)
47
0
        {
48
0
        }
49
        Color(u8 r, u8 g, u8 b)
50
0
            : m_rgb_color({ r, g, b })
51
0
            , m_is_rgb(true)
52
0
        {
53
0
        }
54
55
        bool is_default() const
56
0
        {
57
0
            return !m_is_rgb && m_xterm_color == XtermColor::Unchanged;
58
0
        }
59
60
        XtermColor m_xterm_color { XtermColor::Unchanged };
61
        Vector<int, 3> m_rgb_color;
62
        bool m_is_rgb { false };
63
    };
64
65
    struct Background : public Color {
66
        explicit Background(XtermColor color)
67
0
            : Color(color)
68
0
        {
69
0
        }
70
        Background(u8 r, u8 g, u8 b)
71
            : Color(r, g, b)
72
0
        {
73
0
        }
74
        ByteString to_vt_escape() const;
75
    };
76
77
    struct Foreground : public Color {
78
        explicit Foreground(XtermColor color)
79
0
            : Color(color)
80
0
        {
81
0
        }
82
        Foreground(u8 r, u8 g, u8 b)
83
0
            : Color(r, g, b)
84
0
        {
85
0
        }
86
87
        ByteString to_vt_escape() const;
88
    };
89
90
    struct Hyperlink {
91
0
        bool operator==(Hyperlink const&) const = default;
92
93
        explicit Hyperlink(StringView link)
94
0
            : m_link(link)
95
0
        {
96
0
            m_has_link = true;
97
0
        }
98
99
0
        Hyperlink() = default;
100
101
        ByteString to_vt_escape(bool starting) const;
102
103
0
        bool is_empty() const { return !m_has_link; }
104
105
        ByteString m_link;
106
        bool m_has_link { false };
107
    };
108
109
    struct Mask {
110
        bool operator==(Mask const& other) const
111
0
        {
112
0
            return other.mode == mode && other.replacement == replacement;
113
0
        }
114
115
        enum class Mode {
116
            ReplaceEntireSelection,
117
            ReplaceEachCodePointInSelection,
118
        };
119
        explicit Mask(StringView replacement, Mode mode = Mode::ReplaceEntireSelection)
120
            : replacement(replacement)
121
            , replacement_view(this->replacement)
122
            , mode(mode)
123
0
        {
124
0
        }
125
126
        ByteString replacement;
127
        mutable Utf8View replacement_view;
128
        Mode mode;
129
    };
130
131
    static constexpr UnderlineTag Underline {};
132
    static constexpr BoldTag Bold {};
133
    static constexpr ItalicTag Italic {};
134
    static constexpr AnchoredTag Anchored {};
135
136
    // Prepare for the horror of templates.
137
    template<typename T, typename... Rest>
138
    Style(T const& style_arg, Rest... rest)
139
0
        : Style(rest...)
140
0
    {
141
0
        set(style_arg);
142
0
        m_is_empty = false;
143
0
    }
Unexecuted instantiation: Line::Style::Style<Line::Style::BoldTag>(Line::Style::BoldTag const&)
Unexecuted instantiation: Line::Style::Style<Line::Style::Foreground>(Line::Style::Foreground const&)
Unexecuted instantiation: Line::Style::Style<Line::Style::Foreground, Line::Style::ItalicTag>(Line::Style::Foreground const&, Line::Style::ItalicTag)
Unexecuted instantiation: Line::Style::Style<Line::Style::ItalicTag>(Line::Style::ItalicTag const&)
Unexecuted instantiation: Line::Style::Style<Line::Style::Foreground, Line::Style::BoldTag>(Line::Style::Foreground const&, Line::Style::BoldTag)
Unexecuted instantiation: Line::Style::Style<Line::Style::Hyperlink>(Line::Style::Hyperlink const&)
Unexecuted instantiation: Line::Style::Style<Line::Style::Foreground, Line::Style::Background, Line::Style::Hyperlink>(Line::Style::Foreground const&, Line::Style::Background, Line::Style::Hyperlink)
Unexecuted instantiation: Line::Style::Style<Line::Style::Background, Line::Style::Hyperlink>(Line::Style::Background const&, Line::Style::Hyperlink)
Unexecuted instantiation: Line::Style::Style<Line::Style::Background>(Line::Style::Background const&)
144
0
    Style() = default;
145
146
    static Style reset_style()
147
0
    {
148
0
        return { Foreground(XtermColor::Default), Background(XtermColor::Default), Hyperlink(""sv) };
149
0
    }
150
151
    Style unified_with(Style const& other, bool prefer_other = true) const
152
0
    {
153
0
        Style style = *this;
154
0
        style.unify_with(other, prefer_other);
155
0
        return style;
156
0
    }
157
158
    void unify_with(Style const&, bool prefer_other = false);
159
160
0
    bool underline() const { return m_underline; }
161
0
    bool bold() const { return m_bold; }
162
0
    bool italic() const { return m_italic; }
163
0
    Background background() const { return m_background; }
164
0
    Foreground foreground() const { return m_foreground; }
165
0
    Hyperlink hyperlink() const { return m_hyperlink; }
166
0
    Optional<Mask> mask() const { return m_mask; }
167
168
0
    void unset_mask() const { m_mask = {}; }
169
170
0
    void set(ItalicTag const&) { m_italic = true; }
171
0
    void set(BoldTag const&) { m_bold = true; }
172
0
    void set(UnderlineTag const&) { m_underline = true; }
173
0
    void set(Background const& bg) { m_background = bg; }
174
0
    void set(Foreground const& fg) { m_foreground = fg; }
175
0
    void set(Hyperlink const& link) { m_hyperlink = link; }
176
0
    void set(AnchoredTag const&) { m_is_anchored = true; }
177
0
    void set(Mask const& mask) { m_mask = mask; }
178
179
0
    bool is_anchored() const { return m_is_anchored; }
180
0
    bool is_empty() const { return m_is_empty; }
181
182
    ByteString to_byte_string() const;
183
184
private:
185
    bool m_underline { false };
186
    bool m_bold { false };
187
    bool m_italic { false };
188
    Background m_background { XtermColor::Unchanged };
189
    Foreground m_foreground { XtermColor::Unchanged };
190
    Hyperlink m_hyperlink;
191
    mutable Optional<Mask> m_mask;
192
193
    bool m_is_anchored { false };
194
195
    bool m_is_empty { true };
196
};
197
}