[testsuite] [i386] work around fails with --enable-frame-pointer
[official-gcc.git] / gcc / text-art / types.h
blob2b9f8b387c71997f6f611fcffd697a9ee663d4ab
1 /* Types for drawing 2d "text art".
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_TEXT_ART_TYPES_H
22 #define GCC_TEXT_ART_TYPES_H
24 /* This header uses std::vector, but <vector> can't be directly
25 included due to issues with macros. Hence it must be included from
26 system.h by defining INCLUDE_MEMORY in any source file using it. */
28 #ifndef INCLUDE_VECTOR
29 # error "You must define INCLUDE_VECTOR before including system.h to use text-art/types.h"
30 #endif
32 #include "cpplib.h"
33 #include "pretty-print.h"
35 namespace text_art {
37 /* Forward decls. */
39 class canvas;
40 class table;
41 class theme;
43 /* Classes for geometry.
44 We use templates to avoid mixing up e.g. canvas coordinates
45 with table coordinates. */
47 template <typename CoordinateSystem>
48 struct size
50 size (int w_, int h_) : w (w_), h (h_) {}
51 int w;
52 int h;
55 template <typename CoordinateSystem>
56 struct coord
58 coord (int x_, int y_) : x (x_), y (y_) {}
59 int x;
60 int y;
63 template <typename CoordinateSystem>
64 coord<CoordinateSystem> operator+ (coord<CoordinateSystem> a,
65 coord<CoordinateSystem> b)
67 return coord<CoordinateSystem> (a.x + b.x, a.y + b.y);
70 /* A half-open range [start, next) of int. */
72 template <typename CoordinateSystem>
73 struct range
75 range (int start_, int next_)
76 : start (start_), next (next_)
79 int get_min () const { return start; }
80 int get_max () const { return next - 1; }
81 int get_next () const { return next; }
82 int get_size () const { return next - start; }
84 int get_midpoint () const { return get_min () + get_size () / 2; }
86 int start;
87 int next;
90 /* A rectangle area within CoordinateSystem. */
92 template <typename CoordinateSystem>
93 struct rect
95 rect (coord<CoordinateSystem> top_left,
96 size<CoordinateSystem> size)
97 : m_top_left (top_left),
98 m_size (size)
102 rect (range<CoordinateSystem> x_range,
103 range<CoordinateSystem> y_range)
104 : m_top_left (x_range.get_min (), y_range.get_min ()),
105 m_size (x_range.get_size (), y_range.get_size ())
109 int get_min_x () const { return m_top_left.x; }
110 int get_min_y () const { return m_top_left.y; }
111 int get_max_x () const { return m_top_left.x + m_size.w - 1; }
112 int get_max_y () const { return m_top_left.y + m_size.h - 1; }
113 int get_next_x () const { return m_top_left.x + m_size.w; }
114 int get_next_y () const { return m_top_left.y + m_size.h; }
116 range<CoordinateSystem> get_x_range () const
118 return range<CoordinateSystem> (get_min_x (), get_next_x ());
120 range<CoordinateSystem> get_y_range () const
122 return range<CoordinateSystem> (get_min_y (), get_next_y ());
125 int get_width () const { return m_size.w; }
126 int get_height () const { return m_size.h; }
128 coord<CoordinateSystem> m_top_left;
129 size<CoordinateSystem> m_size;
132 template <typename CoordinateSystem>
133 rect<CoordinateSystem> operator+ (rect<CoordinateSystem> r,
134 coord<CoordinateSystem> offset)
136 return rect<CoordinateSystem> (r.m_top_left + offset, r.m_size);
139 template <typename ElementType, typename SizeType, typename CoordType>
140 class array2
142 public:
143 typedef ElementType element_t;
144 typedef SizeType size_t;
145 typedef CoordType coord_t;
147 array2 (size_t sz)
148 : m_size (sz),
149 m_elements (sz.w * sz.h)
152 array2 (array2 &&other)
153 : m_size (other.m_size),
154 m_elements (std::move (other.m_elements))
158 /* Move assignment not implemented or used. */
159 array2 &operator== (array2 &&other) = delete;
161 /* No copy ctor or assignment op. */
162 array2 (const array2 &other) = delete;
163 array2 &operator= (const array2 &other) = delete;
166 const size_t &get_size () const { return m_size; }
168 void add_row (const element_t &element)
170 m_size.h++;
171 m_elements.insert (m_elements.end (), m_size.w, element);
174 const element_t &get (const coord_t &coord) const
176 ::size_t idx = get_idx (coord);
177 return m_elements[idx];
180 void set (const coord_t &coord, const element_t &element)
182 ::size_t idx = get_idx (coord);
183 m_elements[idx] = element;
186 void fill (element_t element)
188 for (int y = 0; y < m_size.h; y++)
189 for (int x = 0; x < m_size.w; x++)
190 set (coord_t (x, y), element);
193 private:
194 ::size_t get_idx (const coord_t &coord) const
196 gcc_assert (coord.x >= 0);
197 gcc_assert (coord.x < m_size.w);
198 gcc_assert (coord.y >= 0);
199 gcc_assert (coord.y < m_size.h);
200 return (coord.y * m_size.w) + coord.x;
203 size_t m_size;
204 std::vector<element_t> m_elements;
207 /* A combination of attributes describing how to style a text cell.
208 We only support those attributes mentioned in invoke.texi:
209 - bold,
210 - underscore,
211 - blink,
212 - inverse,
213 - colors for foreground and background:
214 - default color
215 - named colors
216 - 16-color mode colors (the "bright" variants)
217 - 88-color mode
218 - 256-color mode
219 plus URLs. */
221 struct style
223 typedef unsigned char id_t;
224 static const id_t id_plain = 0;
226 /* Colors. */
227 enum class named_color
229 DEFAULT,
230 // ANSI order
231 BLACK,
232 RED,
233 GREEN,
234 YELLOW,
235 BLUE,
236 MAGENTA,
237 CYAN,
238 WHITE
242 struct color
244 enum class kind
246 NAMED,
247 BITS_8,
248 BITS_24,
249 } m_kind;
251 union
253 struct {
254 enum named_color m_name;
255 bool m_bright;
256 } m_named;
257 uint8_t m_8bit;
258 struct {
259 uint8_t r;
260 uint8_t g;
261 uint8_t b;
262 } m_24bit;
263 } u;
265 /* Constructor for named colors. */
266 color (enum named_color name = named_color::DEFAULT,
267 bool bright = false)
268 : m_kind (kind::NAMED)
270 u.m_named.m_name = name;
271 u.m_named.m_bright = bright;
274 /* Constructor for 8-bit colors. */
275 color (uint8_t col_val)
276 : m_kind (kind::BITS_8)
278 u.m_8bit = col_val;
281 /* Constructor for 24-bit colors. */
282 color (uint8_t r, uint8_t g, uint8_t b)
283 : m_kind (kind::BITS_24)
285 u.m_24bit.r = r;
286 u.m_24bit.g = g;
287 u.m_24bit.b = b;
290 bool operator== (const color &other) const;
291 bool operator!= (const color &other) const
293 return !(*this == other);
296 void print_sgr (pretty_printer *pp, bool fg, bool &need_separator) const;
299 style ()
300 : m_bold (false),
301 m_underscore (false),
302 m_blink (false),
303 m_reverse (false),
304 m_fg_color (named_color::DEFAULT),
305 m_bg_color (named_color::DEFAULT),
306 m_url ()
309 bool operator== (const style &other) const
311 return (m_bold == other.m_bold
312 && m_underscore == other.m_underscore
313 && m_blink == other.m_blink
314 && m_reverse == other.m_reverse
315 && m_fg_color == other.m_fg_color
316 && m_bg_color == other.m_bg_color
317 && m_url == other.m_url);
320 style &set_style_url (const char *url);
322 static void print_changes (pretty_printer *pp,
323 const style &old_style,
324 const style &new_style);
326 bool m_bold;
327 bool m_underscore;
328 bool m_blink;
329 bool m_reverse;
330 color m_fg_color;
331 color m_bg_color;
332 std::vector<cppchar_t> m_url; // empty = no URL
335 extern style get_style_from_color_cap_name (const char *name);
337 /* A class to keep track of all the styles in use in a drawing, so that
338 we can refer to them via the compact style::id_t type, rather than
339 via e.g. pointers. */
341 class style_manager
343 public:
344 style_manager ();
345 style::id_t get_or_create_id (const style &style);
346 const style &get_style (style::id_t id) const
348 return m_styles[id];
350 void print_any_style_changes (pretty_printer *pp,
351 style::id_t old_id,
352 style::id_t new_id) const;
353 unsigned get_num_styles () const { return m_styles.size (); }
355 private:
356 std::vector<style> m_styles;
359 class styled_unichar
361 public:
362 friend class styled_string;
364 explicit styled_unichar ()
365 : m_code (0),
366 m_style_id (style::id_plain)
368 explicit styled_unichar (cppchar_t ch)
369 : m_code (ch),
370 m_emoji_variant_p (false),
371 m_style_id (style::id_plain)
373 explicit styled_unichar (cppchar_t ch, bool emoji, style::id_t style_id)
374 : m_code (ch),
375 m_emoji_variant_p (emoji),
376 m_style_id (style_id)
378 gcc_assert (style_id <= 0x7f);
381 cppchar_t get_code () const { return m_code; }
382 bool emoji_variant_p () const { return m_emoji_variant_p; }
383 style::id_t get_style_id () const { return m_style_id; }
385 bool double_width_p () const
387 int width = cpp_wcwidth (get_code ());
388 gcc_assert (width == 1 || width == 2);
389 return width == 2;
392 bool operator== (const styled_unichar &other) const
394 return (m_code == other.m_code
395 && m_emoji_variant_p == other.m_emoji_variant_p
396 && m_style_id == other.m_style_id);
399 void set_emoji_variant () { m_emoji_variant_p = true; }
401 int get_canvas_width () const
403 return cpp_wcwidth (m_code);
406 void add_combining_char (cppchar_t ch)
408 m_combining_chars.push_back (ch);
411 const std::vector<cppchar_t> get_combining_chars () const
413 return m_combining_chars;
416 private:
417 cppchar_t m_code : 24;
418 bool m_emoji_variant_p : 1;
419 style::id_t m_style_id : 7;
420 std::vector<cppchar_t> m_combining_chars;
423 class styled_string
425 public:
426 explicit styled_string () = default;
427 explicit styled_string (style_manager &sm, const char *str);
428 explicit styled_string (cppchar_t cppchar, bool emoji = false);
430 styled_string (styled_string &&) = default;
431 styled_string &operator= (styled_string &&) = default;
433 /* No copy ctor or assignment op. */
434 styled_string (const styled_string &) = delete;
435 styled_string &operator= (const styled_string &) = delete;
437 /* For the few cases where copying is required, spell it out explicitly. */
438 styled_string copy () const
440 styled_string result;
441 result.m_chars = m_chars;
442 return result;
445 bool operator== (const styled_string &other) const
447 return m_chars == other.m_chars;
450 static styled_string from_fmt (style_manager &sm,
451 printer_fn format_decoder,
452 const char *fmt, ...)
453 ATTRIBUTE_GCC_PPDIAG(3, 4);
454 static styled_string from_fmt_va (style_manager &sm,
455 printer_fn format_decoder,
456 const char *fmt,
457 va_list *args)
458 ATTRIBUTE_GCC_PPDIAG(3, 0);
460 size_t size () const { return m_chars.size (); }
461 styled_unichar operator[] (size_t idx) const { return m_chars[idx]; }
463 std::vector<styled_unichar>::const_iterator begin () const
465 return m_chars.begin ();
467 std::vector<styled_unichar>::const_iterator end () const
469 return m_chars.end ();
472 int calc_canvas_width () const;
474 void append (const styled_string &suffix);
476 void set_url (style_manager &sm, const char *url);
478 private:
479 std::vector<styled_unichar> m_chars;
482 enum class x_align
484 LEFT,
485 CENTER,
486 RIGHT
489 enum class y_align
491 TOP,
492 CENTER,
493 BOTTOM
496 /* A set of cardinal directions within a canvas or table. */
498 struct directions
500 public:
501 directions (bool up, bool down, bool left, bool right)
502 : m_up (up), m_down (down), m_left (left), m_right (right)
506 size_t as_index () const
508 return (m_up << 3) | (m_down << 2) | (m_left << 1) | m_right;
511 bool m_up: 1;
512 bool m_down: 1;
513 bool m_left: 1;
514 bool m_right: 1;
517 } // namespace text_art
519 #endif /* GCC_TEXT_ART_TYPES_H */