Serenity Operating System
at master 197 lines 5.0 kB view raw
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/DeprecatedString.h> 10#include <AK/Types.h> 11#include <AK/Utf8View.h> 12#include <AK/Vector.h> 13 14namespace Line { 15 16class Style { 17public: 18 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 bool operator==(Color const&) const = default; 43 44 explicit Color(XtermColor color) 45 : m_xterm_color(color) 46 , m_is_rgb(false) 47 { 48 } 49 Color(u8 r, u8 g, u8 b) 50 : m_rgb_color({ r, g, b }) 51 , m_is_rgb(true) 52 { 53 } 54 55 bool is_default() const 56 { 57 return !m_is_rgb && m_xterm_color == XtermColor::Unchanged; 58 } 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 : Color(color) 68 { 69 } 70 Background(u8 r, u8 g, u8 b) 71 : Color(r, g, b) 72 { 73 } 74 DeprecatedString to_vt_escape() const; 75 }; 76 77 struct Foreground : public Color { 78 explicit Foreground(XtermColor color) 79 : Color(color) 80 { 81 } 82 Foreground(u8 r, u8 g, u8 b) 83 : Color(r, g, b) 84 { 85 } 86 87 DeprecatedString to_vt_escape() const; 88 }; 89 90 struct Hyperlink { 91 bool operator==(Hyperlink const&) const = default; 92 93 explicit Hyperlink(StringView link) 94 : m_link(link) 95 { 96 m_has_link = true; 97 } 98 99 Hyperlink() = default; 100 101 DeprecatedString to_vt_escape(bool starting) const; 102 103 bool is_empty() const { return !m_has_link; } 104 105 DeprecatedString m_link; 106 bool m_has_link { false }; 107 }; 108 109 struct Mask { 110 bool operator==(Mask const& other) const 111 { 112 return other.mode == mode && other.replacement == replacement; 113 } 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 { 124 } 125 126 DeprecatedString 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 : Style(rest...) 140 { 141 set(style_arg); 142 m_is_empty = false; 143 } 144 Style() = default; 145 146 static Style reset_style() 147 { 148 return { Foreground(XtermColor::Default), Background(XtermColor::Default), Hyperlink(""sv) }; 149 } 150 151 Style unified_with(Style const& other, bool prefer_other = true) const 152 { 153 Style style = *this; 154 style.unify_with(other, prefer_other); 155 return style; 156 } 157 158 void unify_with(Style const&, bool prefer_other = false); 159 160 bool underline() const { return m_underline; } 161 bool bold() const { return m_bold; } 162 bool italic() const { return m_italic; } 163 Background background() const { return m_background; } 164 Foreground foreground() const { return m_foreground; } 165 Hyperlink hyperlink() const { return m_hyperlink; } 166 Optional<Mask> mask() const { return m_mask; } 167 168 void unset_mask() const { m_mask = {}; } 169 170 void set(ItalicTag const&) { m_italic = true; } 171 void set(BoldTag const&) { m_bold = true; } 172 void set(UnderlineTag const&) { m_underline = true; } 173 void set(Background const& bg) { m_background = bg; } 174 void set(Foreground const& fg) { m_foreground = fg; } 175 void set(Hyperlink const& link) { m_hyperlink = link; } 176 void set(AnchoredTag const&) { m_is_anchored = true; } 177 void set(Mask const& mask) { m_mask = mask; } 178 179 bool is_anchored() const { return m_is_anchored; } 180 bool is_empty() const { return m_is_empty; } 181 182 DeprecatedString to_deprecated_string() const; 183 184private: 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}