1 /* Styling for ui_file 2 Copyright (C) 2018-2019 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #ifndef UI_STYLE_H 20 #define UI_STYLE_H 21 22 /* Styles that can be applied to a ui_file. */ 23 struct ui_file_style 24 { 25 /* One of the basic colors that can be handled by ANSI 26 terminals. */ 27 enum basic_color 28 { 29 NONE = -1, 30 BLACK, 31 RED, 32 GREEN, 33 YELLOW, 34 BLUE, 35 MAGENTA, 36 CYAN, 37 WHITE 38 }; 39 40 /* Representation of a terminal color. */ 41 class color 42 { 43 public: 44 45 color (basic_color c) 46 : m_simple (true), 47 m_value (c) 48 { 49 } 50 51 color (int c) 52 : m_simple (true), 53 m_value (c) 54 { 55 gdb_assert (c >= -1 && c <= 255); 56 } 57 58 color (uint8_t r, uint8_t g, uint8_t b) 59 : m_simple (false), 60 m_red (r), 61 m_green (g), 62 m_blue (b) 63 { 64 } 65 66 bool operator== (const color &other) const 67 { 68 if (m_simple != other.m_simple) 69 return false; 70 if (m_simple) 71 return m_value == other.m_value; 72 return (m_red == other.m_red && m_green == other.m_green 73 && m_blue == other.m_blue); 74 } 75 76 bool operator< (const color &other) const 77 { 78 if (m_simple != other.m_simple) 79 return m_simple < other.m_simple; 80 if (m_simple) 81 return m_value < other.m_value; 82 if (m_red < other.m_red) 83 return true; 84 if (m_red == other.m_red) 85 { 86 if (m_green < other.m_green) 87 return true; 88 if (m_green == other.m_green) 89 return m_blue < other.m_blue; 90 } 91 return false; 92 } 93 94 /* Return true if this is the "NONE" color, false otherwise. */ 95 bool is_none () const 96 { 97 return m_simple && m_value == NONE; 98 } 99 100 /* Return true if this is one of the basic colors, false 101 otherwise. */ 102 bool is_basic () const 103 { 104 return m_simple && m_value >= BLACK && m_value <= WHITE; 105 } 106 107 /* Return the value of a basic color. */ 108 int get_value () const 109 { 110 gdb_assert (is_basic ()); 111 return m_value; 112 } 113 114 /* Fill in RGB with the red/green/blue values for this color. 115 This may not be called for basic colors or for the "NONE" 116 color. */ 117 void get_rgb (uint8_t *rgb) const; 118 119 /* Append the ANSI terminal escape sequence for this color to STR. 120 IS_FG indicates whether this is a foreground or background 121 color. Returns true if any characters were written; returns 122 false otherwise (which can only happen for the "NONE" 123 color). */ 124 bool append_ansi (bool is_fg, std::string *str) const; 125 126 private: 127 128 bool m_simple; 129 int m_value; 130 uint8_t m_red, m_green, m_blue; 131 }; 132 133 /* Intensity settings that are available. */ 134 enum intensity 135 { 136 NORMAL = 0, 137 BOLD, 138 DIM 139 }; 140 141 ui_file_style () = default; 142 143 ui_file_style (color f, color b, intensity i = NORMAL) 144 : m_foreground (f), 145 m_background (b), 146 m_intensity (i) 147 { 148 } 149 150 bool operator== (const ui_file_style &other) const 151 { 152 return (m_foreground == other.m_foreground 153 && m_background == other.m_background 154 && m_intensity == other.m_intensity 155 && m_reverse == other.m_reverse); 156 } 157 158 bool operator!= (const ui_file_style &other) const 159 { 160 return !(*this == other); 161 } 162 163 /* Return the ANSI escape sequence for this style. */ 164 std::string to_ansi () const; 165 166 /* Return true if this style is the default style; false 167 otherwise. */ 168 bool is_default () const 169 { 170 return (m_foreground == NONE 171 && m_background == NONE 172 && m_intensity == NORMAL 173 && !m_reverse); 174 } 175 176 /* Return true if this style specified reverse display; false 177 otherwise. */ 178 bool is_reverse () const 179 { 180 return m_reverse; 181 } 182 183 /* Set/clear the reverse display flag. */ 184 void set_reverse (bool reverse) 185 { 186 m_reverse = reverse; 187 } 188 189 /* Return the foreground color of this style. */ 190 const color &get_foreground () const 191 { 192 return m_foreground; 193 } 194 195 /* Set the foreground color of this style. */ 196 void set_fg (color c) 197 { 198 m_foreground = c; 199 } 200 201 /* Return the background color of this style. */ 202 const color &get_background () const 203 { 204 return m_background; 205 } 206 207 /* Set the background color of this style. */ 208 void set_bg (color c) 209 { 210 m_background = c; 211 } 212 213 /* Return the intensity of this style. */ 214 intensity get_intensity () const 215 { 216 return m_intensity; 217 } 218 219 /* Parse an ANSI escape sequence in BUF, modifying this style. BUF 220 must begin with an ESC character. Return true if an escape 221 sequence was successfully parsed; false otherwise. In either 222 case, N_READ is updated to reflect the number of chars read from 223 BUF. */ 224 bool parse (const char *buf, size_t *n_read); 225 226 private: 227 228 color m_foreground = NONE; 229 color m_background = NONE; 230 intensity m_intensity = NORMAL; 231 bool m_reverse = false; 232 }; 233 234 /* Skip an ANSI escape sequence in BUF. BUF must begin with an ESC 235 character. Return true if an escape sequence was successfully 236 skipped; false otherwise. In either case, N_READ is updated to 237 reflect the number of chars read from BUF. */ 238 239 extern bool skip_ansi_escape (const char *buf, int *n_read); 240 241 #endif /* UI_STYLE_H */ 242