]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/text-art/types.h
VECT: Apply LEN_MASK_{LOAD,STORE} into vectorizer
[thirdparty/gcc.git] / gcc / text-art / types.h
CommitLineData
4f01ae37
DM
1/* Types for drawing 2d "text art".
2 Copyright (C) 2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_TEXT_ART_TYPES_H
22#define GCC_TEXT_ART_TYPES_H
23
24#include "cpplib.h"
25#include "pretty-print.h"
26#include <vector>
27#include <string>
28
29namespace text_art {
30
31/* Forward decls. */
32
33class canvas;
34class table;
35class theme;
36
37/* Classes for geometry.
38 We use templates to avoid mixing up e.g. canvas coordinates
39 with table coordinates. */
40
41template <typename CoordinateSystem>
42struct size
43{
44 size (int w_, int h_) : w (w_), h (h_) {}
45 int w;
46 int h;
47};
48
49template <typename CoordinateSystem>
50struct coord
51{
52 coord (int x_, int y_) : x (x_), y (y_) {}
53 int x;
54 int y;
55};
56
57template <typename CoordinateSystem>
58coord<CoordinateSystem> operator+ (coord<CoordinateSystem> a,
59 coord<CoordinateSystem> b)
60{
61 return coord<CoordinateSystem> (a.x + b.x, a.y + b.y);
62}
63
64/* A half-open range [start, next) of int. */
65
66template <typename CoordinateSystem>
67struct range
68{
69 range (int start_, int next_)
70 : start (start_), next (next_)
71 {}
72
73 int get_min () const { return start; }
74 int get_max () const { return next - 1; }
75 int get_next () const { return next; }
76 int get_size () const { return next - start; }
77
78 int get_midpoint () const { return get_min () + get_size () / 2; }
79
80 int start;
81 int next;
82};
83
84/* A rectangle area within CoordinateSystem. */
85
86template <typename CoordinateSystem>
87struct rect
88{
89 rect (coord<CoordinateSystem> top_left,
90 size<CoordinateSystem> size)
91 : m_top_left (top_left),
92 m_size (size)
93 {
94 }
95
96 rect (range<CoordinateSystem> x_range,
97 range<CoordinateSystem> y_range)
98 : m_top_left (x_range.get_min (), y_range.get_min ()),
99 m_size (x_range.get_size (), y_range.get_size ())
100 {
101 }
102
103 int get_min_x () const { return m_top_left.x; }
104 int get_min_y () const { return m_top_left.y; }
105 int get_max_x () const { return m_top_left.x + m_size.w - 1; }
106 int get_max_y () const { return m_top_left.y + m_size.h - 1; }
107 int get_next_x () const { return m_top_left.x + m_size.w; }
108 int get_next_y () const { return m_top_left.y + m_size.h; }
109
110 range<CoordinateSystem> get_x_range () const
111 {
112 return range<CoordinateSystem> (get_min_x (), get_next_x ());
113 }
114 range<CoordinateSystem> get_y_range () const
115 {
116 return range<CoordinateSystem> (get_min_y (), get_next_y ());
117 }
118
119 int get_width () const { return m_size.w; }
120 int get_height () const { return m_size.h; }
121
122 coord<CoordinateSystem> m_top_left;
123 size<CoordinateSystem> m_size;
124};
125
126template <typename ElementType, typename SizeType, typename CoordType>
127class array2
128{
129 public:
130 typedef ElementType element_t;
131 typedef SizeType size_t;
132 typedef CoordType coord_t;
133
134 array2 (size_t sz)
135 : m_size (sz),
136 m_elements (sz.w * sz.h)
137 {
138 }
139 array2 (array2 &&other)
140 : m_size (other.m_size),
141 m_elements (std::move (other.m_elements))
142 {
143 }
144
145 /* Move assignment not implemented or used. */
146 array2 &operator== (array2 &&other) = delete;
147
148 /* No copy ctor or assignment op. */
149 array2 (const array2 &other) = delete;
150 array2 &operator= (const array2 &other) = delete;
151
152
153 const size_t &get_size () const { return m_size; }
154
155 void add_row (const element_t &element)
156 {
157 m_size.h++;
158 m_elements.insert (m_elements.end (), m_size.w, element);
159 }
160
161 const element_t &get (const coord_t &coord) const
162 {
163 ::size_t idx = get_idx (coord);
164 return m_elements[idx];
165 }
166
167 void set (const coord_t &coord, const element_t &element)
168 {
169 ::size_t idx = get_idx (coord);
170 m_elements[idx] = element;
171 }
172
173 void fill (element_t element)
174 {
175 for (int y = 0; y < m_size.h; y++)
176 for (int x = 0; x < m_size.w; x++)
177 set (coord_t (x, y), element);
178 }
179
180 private:
181 ::size_t get_idx (const coord_t &coord) const
182 {
183 gcc_assert (coord.x >= 0);
184 gcc_assert (coord.x < m_size.w);
185 gcc_assert (coord.y >= 0);
186 gcc_assert (coord.y < m_size.h);
187 return (coord.y * m_size.w) + coord.x;
188 }
189
190 size_t m_size;
191 std::vector<element_t> m_elements;
192};
193
194/* A combination of attributes describing how to style a text cell.
195 We only support those attributes mentioned in invoke.texi:
196 - bold,
197 - underscore,
198 - blink,
199 - inverse,
200 - colors for foreground and background:
201 - default color
202 - named colors
203 - 16-color mode colors (the "bright" variants)
204 - 88-color mode
205 - 256-color mode
206 plus URLs. */
207
208struct style
209{
210 typedef unsigned char id_t;
211 static const id_t id_plain = 0;
212
213 /* Colors. */
214 enum class named_color
215 {
216 DEFAULT,
217 // ANSI order
218 BLACK,
219 RED,
220 GREEN,
221 YELLOW,
222 BLUE,
223 MAGENTA,
224 CYAN,
225 WHITE
226 };
227
228
229 struct color
230 {
231 enum class kind
232 {
233 NAMED,
234 BITS_8,
235 BITS_24,
236 } m_kind;
237
238 union
239 {
240 struct {
241 enum named_color m_name;
242 bool m_bright;
243 } m_named;
244 uint8_t m_8bit;
245 struct {
246 uint8_t r;
247 uint8_t g;
248 uint8_t b;
249 } m_24bit;
250 } u;
251
252 /* Constructor for named colors. */
253 color (enum named_color name = named_color::DEFAULT,
254 bool bright = false)
255 : m_kind (kind::NAMED)
256 {
257 u.m_named.m_name = name;
258 u.m_named.m_bright = bright;
259 }
260
261 /* Constructor for 8-bit colors. */
262 color (uint8_t col_val)
263 : m_kind (kind::BITS_8)
264 {
265 u.m_8bit = col_val;
266 }
267
268 /* Constructor for 24-bit colors. */
269 color (uint8_t r, uint8_t g, uint8_t b)
270 : m_kind (kind::BITS_24)
271 {
272 u.m_24bit.r = r;
273 u.m_24bit.g = g;
274 u.m_24bit.b = b;
275 }
276
277 bool operator== (const color &other) const;
278 bool operator!= (const color &other) const
279 {
280 return !(*this == other);
281 }
282
283 void print_sgr (pretty_printer *pp, bool fg, bool &need_separator) const;
284 };
285
286 style ()
287 : m_bold (false),
288 m_underscore (false),
289 m_blink (false),
290 m_reverse (false),
291 m_fg_color (named_color::DEFAULT),
292 m_bg_color (named_color::DEFAULT),
293 m_url ()
294 {}
295
296 bool operator== (const style &other) const
297 {
298 return (m_bold == other.m_bold
299 && m_underscore == other.m_underscore
300 && m_blink == other.m_blink
301 && m_reverse == other.m_reverse
302 && m_fg_color == other.m_fg_color
303 && m_bg_color == other.m_bg_color
304 && m_url == other.m_url);
305 }
306
307 style &set_style_url (const char *url);
308
309 static void print_changes (pretty_printer *pp,
310 const style &old_style,
311 const style &new_style);
312
313 bool m_bold;
314 bool m_underscore;
315 bool m_blink;
316 bool m_reverse;
317 color m_fg_color;
318 color m_bg_color;
319 std::vector<cppchar_t> m_url; // empty = no URL
320};
321
322/* A class to keep track of all the styles in use in a drawing, so that
323 we can refer to them via the compact style::id_t type, rather than
324 via e.g. pointers. */
325
326class style_manager
327{
328 public:
329 style_manager ();
330 style::id_t get_or_create_id (const style &style);
331 const style &get_style (style::id_t id) const
332 {
333 return m_styles[id];
334 }
335 void print_any_style_changes (pretty_printer *pp,
336 style::id_t old_id,
337 style::id_t new_id) const;
338 unsigned get_num_styles () const { return m_styles.size (); }
339
340private:
341 std::vector<style> m_styles;
342};
343
344class styled_unichar
345{
346 public:
347 friend class styled_string;
348
349 explicit styled_unichar ()
350 : m_code (0),
351 m_style_id (style::id_plain)
352 {}
353 explicit styled_unichar (cppchar_t ch)
354 : m_code (ch),
355 m_emoji_variant_p (false),
356 m_style_id (style::id_plain)
357 {}
358 explicit styled_unichar (cppchar_t ch, bool emoji, style::id_t style_id)
359 : m_code (ch),
360 m_emoji_variant_p (emoji),
361 m_style_id (style_id)
362 {
363 gcc_assert (style_id <= 0x7f);
364 }
365
366 cppchar_t get_code () const { return m_code; }
367 bool emoji_variant_p () const { return m_emoji_variant_p; }
368 style::id_t get_style_id () const { return m_style_id; }
369
370 bool double_width_p () const
371 {
372 int width = cpp_wcwidth (get_code ());
373 gcc_assert (width == 1 || width == 2);
374 return width == 2;
375 }
376
377 bool operator== (const styled_unichar &other) const
378 {
379 return (m_code == other.m_code
380 && m_emoji_variant_p == other.m_emoji_variant_p
381 && m_style_id == other.m_style_id);
382 }
383
384 void set_emoji_variant () { m_emoji_variant_p = true; }
385
386 int get_canvas_width () const
387 {
388 return cpp_wcwidth (m_code);
389 }
390
391 void add_combining_char (cppchar_t ch)
392 {
393 m_combining_chars.push_back (ch);
394 }
395
396 const std::vector<cppchar_t> get_combining_chars () const
397 {
398 return m_combining_chars;
399 }
400
401private:
402 cppchar_t m_code : 24;
403 bool m_emoji_variant_p : 1;
404 style::id_t m_style_id : 7;
405 std::vector<cppchar_t> m_combining_chars;
406};
407
408class styled_string
409{
410 public:
411 explicit styled_string () = default;
412 explicit styled_string (style_manager &sm, const char *str);
413 explicit styled_string (cppchar_t cppchar, bool emoji = false);
414
415 styled_string (styled_string &&) = default;
416 styled_string &operator= (styled_string &&) = default;
417
418 /* No copy ctor or assignment op. */
419 styled_string (const styled_string &) = delete;
420 styled_string &operator= (const styled_string &) = delete;
421
422 /* For the few cases where copying is required, spell it out explicitly. */
423 styled_string copy () const
424 {
425 styled_string result;
426 result.m_chars = m_chars;
427 return result;
428 }
429
430 bool operator== (const styled_string &other) const
431 {
432 return m_chars == other.m_chars;
433 }
434
435 static styled_string from_fmt (style_manager &sm,
436 printer_fn format_decoder,
437 const char *fmt, ...)
438 ATTRIBUTE_GCC_PPDIAG(3, 4);
439 static styled_string from_fmt_va (style_manager &sm,
440 printer_fn format_decoder,
441 const char *fmt,
442 va_list *args)
443 ATTRIBUTE_GCC_PPDIAG(3, 0);
444
445 size_t size () const { return m_chars.size (); }
446 styled_unichar operator[] (size_t idx) const { return m_chars[idx]; }
447
448 std::vector<styled_unichar>::const_iterator begin () const
449 {
450 return m_chars.begin ();
451 }
452 std::vector<styled_unichar>::const_iterator end () const
453 {
454 return m_chars.end ();
455 }
456
457 int calc_canvas_width () const;
458
459 void append (const styled_string &suffix);
460
461 void set_url (style_manager &sm, const char *url);
462
463private:
464 std::vector<styled_unichar> m_chars;
465};
466
467enum class x_align
468{
469 LEFT,
470 CENTER,
471 RIGHT
472};
473
474enum class y_align
475{
476 TOP,
477 CENTER,
478 BOTTOM
479};
480
481/* A set of cardinal directions within a canvas or table. */
482
483struct directions
484{
485public:
486 directions (bool up, bool down, bool left, bool right)
487 : m_up (up), m_down (down), m_left (left), m_right (right)
488 {
489 }
490
491 size_t as_index () const
492 {
493 return (m_up << 3) | (m_down << 2) | (m_left << 1) | m_right;
494 }
495
496 bool m_up: 1;
497 bool m_down: 1;
498 bool m_left: 1;
499 bool m_right: 1;
500};
501
502} // namespace text_art
503
504#endif /* GCC_TEXT_ART_TYPES_H */