ui-style.h 5.8 KB

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