Branch data Line data Source code
1 : : /* Classes for abstracting ascii vs unicode output.
2 : : Copyright (C) 2023-2025 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
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/>. */
20 : :
21 : : #include "config.h"
22 : : #define INCLUDE_VECTOR
23 : : #include "system.h"
24 : : #include "coretypes.h"
25 : : #include "pretty-print.h"
26 : : #include "selftest.h"
27 : : #include "text-art/selftests.h"
28 : : #include "text-art/ruler.h"
29 : : #include "text-art/theme.h"
30 : :
31 : : using namespace text_art;
32 : :
33 : : /* class theme. */
34 : :
35 : : void
36 : 280 : theme::paint_y_arrow (canvas &canvas,
37 : : int canvas_x,
38 : : canvas::range_t y_range,
39 : : y_arrow_dir dir,
40 : : style::id_t style_id) const
41 : : {
42 : 280 : int canvas_y;
43 : 280 : int delta_y;
44 : 280 : const canvas::cell_t head (get_cppchar (dir == y_arrow_dir::UP
45 : : ? cell_kind::Y_ARROW_UP_HEAD
46 : : : cell_kind::Y_ARROW_DOWN_HEAD),
47 : 514 : false, style_id);
48 : 280 : const canvas::cell_t tail (get_cppchar (dir == y_arrow_dir::UP
49 : : ? cell_kind::Y_ARROW_UP_TAIL
50 : : : cell_kind::Y_ARROW_DOWN_TAIL),
51 : 514 : false, style_id);
52 : 280 : if (dir == y_arrow_dir::UP)
53 : : {
54 : 46 : canvas_y = y_range.get_max ();
55 : 46 : delta_y = -1;
56 : : }
57 : : else
58 : : {
59 : : canvas_y = y_range.get_min ();
60 : : delta_y = 1;
61 : : }
62 : 1120 : for (int len = y_range.get_size (); len; len--)
63 : : {
64 : 840 : const canvas::cell_t cell = (len > 1) ? tail : head;
65 : 840 : canvas.paint (canvas::coord_t (canvas_x, canvas_y), cell);
66 : 840 : canvas_y += delta_y;
67 : 840 : }
68 : 280 : }
69 : :
70 : : /* class ascii_theme : public theme. */
71 : :
72 : : canvas::cell_t
73 : 6202 : ascii_theme::get_line_art (directions line_dirs) const
74 : : {
75 : 6202 : if (line_dirs.m_up
76 : 1515 : && line_dirs.m_down
77 : 1022 : && !(line_dirs.m_left || line_dirs.m_right))
78 : 429 : return canvas::cell_t ('|');
79 : 5773 : if (line_dirs.m_left
80 : 4632 : && line_dirs.m_right
81 : 4336 : && !(line_dirs.m_up || line_dirs.m_down))
82 : 3349 : return canvas::cell_t ('-');
83 : 2424 : if (line_dirs.m_up
84 : 1338 : || line_dirs.m_down
85 : 845 : || line_dirs.m_left
86 : 845 : || line_dirs.m_right)
87 : 1579 : return canvas::cell_t ('+');
88 : 845 : return canvas::cell_t (' ');
89 : : }
90 : :
91 : : cppchar_t
92 : 19437 : ascii_theme::get_cppchar (enum cell_kind kind) const
93 : : {
94 : 19437 : switch (kind)
95 : : {
96 : 0 : default:
97 : 0 : gcc_unreachable ();
98 : : case cell_kind::X_RULER_LEFT_EDGE:
99 : : return '|';
100 : : case cell_kind::X_RULER_MIDDLE:
101 : : return '~';
102 : : case cell_kind::X_RULER_INTERNAL_EDGE:
103 : : return '|';
104 : : case cell_kind::X_RULER_CONNECTOR_TO_LABEL_BELOW:
105 : : case cell_kind::X_RULER_CONNECTOR_TO_LABEL_ABOVE:
106 : : return '+';
107 : : case cell_kind::X_RULER_RIGHT_EDGE:
108 : : return '|';
109 : : case cell_kind::X_RULER_VERTICAL_CONNECTOR:
110 : : return '|';
111 : :
112 : : case cell_kind::TEXT_BORDER_HORIZONTAL:
113 : : return '-';
114 : : case cell_kind::TEXT_BORDER_VERTICAL:
115 : : return '|';
116 : : case cell_kind::TEXT_BORDER_TOP_LEFT:
117 : : case cell_kind::TEXT_BORDER_TOP_RIGHT:
118 : : case cell_kind::TEXT_BORDER_BOTTOM_LEFT:
119 : : case cell_kind::TEXT_BORDER_BOTTOM_RIGHT:
120 : : return '+';
121 : :
122 : : case cell_kind::Y_ARROW_UP_HEAD: return '^';
123 : : case cell_kind::Y_ARROW_DOWN_HEAD: return 'v';
124 : :
125 : : case cell_kind::Y_ARROW_UP_TAIL:
126 : : case cell_kind::Y_ARROW_DOWN_TAIL:
127 : : return '|';
128 : :
129 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_LEFT:
130 : : return '+';
131 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_MIDDLE:
132 : : return '-';
133 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_RIGHT:
134 : : return '>';
135 : : case cell_kind::INTERPROCEDURAL_DEPTH_MARKER:
136 : : return '|';
137 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_LEFT:
138 : : return '<';
139 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_MIDDLE:
140 : : return '-';
141 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_RIGHT:
142 : : return '+';
143 : :
144 : : case cell_kind::CFG_RIGHT:
145 : : return '-';
146 : : case cell_kind::CFG_FROM_RIGHT_TO_DOWN:
147 : : return '+';
148 : : case cell_kind::CFG_DOWN:
149 : : return '|';
150 : : case cell_kind::CFG_FROM_DOWN_TO_LEFT:
151 : : return '+';
152 : : case cell_kind::CFG_LEFT:
153 : : return '-';
154 : : case cell_kind::CFG_FROM_LEFT_TO_DOWN:
155 : : return '+';
156 : : case cell_kind::CFG_FROM_DOWN_TO_RIGHT:
157 : : return '+';
158 : :
159 : : case cell_kind::TREE_CHILD_NON_FINAL:
160 : : return '+';
161 : : case cell_kind::TREE_CHILD_FINAL:
162 : : return '`';
163 : : case cell_kind::TREE_X_CONNECTOR:
164 : : return '-';
165 : : case cell_kind::TREE_Y_CONNECTOR:
166 : : return '|';
167 : : }
168 : : }
169 : :
170 : : /* class unicode_theme : public theme. */
171 : :
172 : : canvas::cell_t
173 : 16538 : unicode_theme::get_line_art (directions line_dirs) const
174 : : {
175 : 16538 : return canvas::cell_t (get_box_drawing_char (line_dirs));
176 : : }
177 : :
178 : : cppchar_t
179 : 9353 : unicode_theme::get_cppchar (enum cell_kind kind) const
180 : : {
181 : 9353 : switch (kind)
182 : : {
183 : 0 : default:
184 : 0 : gcc_unreachable ();
185 : : case cell_kind::X_RULER_LEFT_EDGE:
186 : : return 0x251C; /* "├": U+251C: BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
187 : : case cell_kind::X_RULER_MIDDLE:
188 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
189 : : case cell_kind::X_RULER_INTERNAL_EDGE:
190 : : return 0x253C; /* "┼": U+253C: BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
191 : : case cell_kind::X_RULER_CONNECTOR_TO_LABEL_BELOW:
192 : : return 0x252C; /* "┬": U+252C: BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
193 : : case cell_kind::X_RULER_CONNECTOR_TO_LABEL_ABOVE:
194 : : return 0x2534; /* "┴": U+2534: BOX DRAWINGS LIGHT UP AND HORIZONTAL */
195 : : case cell_kind::X_RULER_RIGHT_EDGE:
196 : : return 0x2524; /* "┤": U+2524: BOX DRAWINGS LIGHT VERTICAL AND LEFT */
197 : : case cell_kind::X_RULER_VERTICAL_CONNECTOR:
198 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
199 : :
200 : : case cell_kind::TEXT_BORDER_HORIZONTAL:
201 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
202 : : case cell_kind::TEXT_BORDER_VERTICAL:
203 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
204 : :
205 : : /* Round corners. */
206 : : case cell_kind::TEXT_BORDER_TOP_LEFT:
207 : : return 0x256D; /* "╭": U+256D BOX DRAWINGS LIGHT ARC DOWN AND RIGHT. */
208 : : case cell_kind::TEXT_BORDER_TOP_RIGHT:
209 : : return 0x256E; /* "╮": U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT. */
210 : : case cell_kind::TEXT_BORDER_BOTTOM_LEFT:
211 : : return 0x2570; /* "╰": U+2570 BOX DRAWINGS LIGHT ARC UP AND RIGHT. */
212 : : case cell_kind::TEXT_BORDER_BOTTOM_RIGHT:
213 : : return 0x256F; /* "╯": U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT. */
214 : :
215 : : case cell_kind::Y_ARROW_UP_HEAD:
216 : : return '^';
217 : : case cell_kind::Y_ARROW_DOWN_HEAD:
218 : : return 'v';
219 : : case cell_kind::Y_ARROW_UP_TAIL:
220 : : case cell_kind::Y_ARROW_DOWN_TAIL:
221 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
222 : :
223 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_LEFT:
224 : : return 0x2514; /* "└": U+2514: BOX DRAWINGS LIGHT UP AND RIGHT */
225 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_MIDDLE:
226 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
227 : : case cell_kind::INTERPROCEDURAL_PUSH_FRAME_RIGHT:
228 : : return '>';
229 : : case cell_kind::INTERPROCEDURAL_DEPTH_MARKER:
230 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
231 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_LEFT:
232 : : return '<';
233 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_MIDDLE:
234 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
235 : : case cell_kind::INTERPROCEDURAL_POP_FRAMES_RIGHT:
236 : : return 0x2518; /* "┘": U+2518: BOX DRAWINGS LIGHT UP AND LEFT. */
237 : :
238 : : case cell_kind::CFG_RIGHT:
239 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
240 : : case cell_kind::CFG_FROM_RIGHT_TO_DOWN:
241 : : return 0x2510; /* "┐": U+2510: BOX DRAWINGS LIGHT DOWN AND LEFT */
242 : : case cell_kind::CFG_DOWN:
243 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
244 : : case cell_kind::CFG_FROM_DOWN_TO_LEFT:
245 : : return 0x2518; /* "┘": U+2518: BOX DRAWINGS LIGHT UP AND LEFT. */
246 : : case cell_kind::CFG_LEFT:
247 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
248 : : case cell_kind::CFG_FROM_LEFT_TO_DOWN:
249 : : return 0x250c; /* "┌" U+250C: BOX DRAWINGS LIGHT DOWN AND RIGHT */
250 : : case cell_kind::CFG_FROM_DOWN_TO_RIGHT:
251 : : return 0x2514; /* "└": U+2514: BOX DRAWINGS LIGHT UP AND RIGHT */
252 : :
253 : : case cell_kind::TREE_CHILD_NON_FINAL:
254 : : return 0x251C; /* "├": U+251C: BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
255 : : case cell_kind::TREE_CHILD_FINAL:
256 : : return 0x2570; /* "╰": U+2570 BOX DRAWINGS LIGHT ARC UP AND RIGHT. */
257 : : case cell_kind::TREE_X_CONNECTOR:
258 : : return 0x2500; /* "─": U+2500: BOX DRAWINGS LIGHT HORIZONTAL */
259 : : case cell_kind::TREE_Y_CONNECTOR:
260 : : return 0x2502; /* "│": U+2502: BOX DRAWINGS LIGHT VERTICAL */
261 : : }
262 : : }
|