]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/text-art/widget.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / text-art / widget.cc
1 /* Hierarchical diagram elements.
2 Copyright (C) 2023-2024 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_MEMORY
23 #define INCLUDE_VECTOR
24 #include "system.h"
25 #include "coretypes.h"
26 #include "pretty-print.h"
27 #include "selftest.h"
28 #include "make-unique.h"
29 #include "text-art/selftests.h"
30 #include "text-art/widget.h"
31
32 using namespace text_art;
33
34 /* class text_art::widget. */
35
36 canvas
37 widget::to_canvas (const style_manager &style_mgr)
38 {
39 const canvas::size_t req_size = get_req_size ();
40
41 /* For now we don't constrain the allocation; we give
42 the widget the full size it requested, and widgets
43 assume they got their full size request. */
44 const canvas::size_t alloc_size = req_size;
45
46 set_alloc_rect (canvas::rect_t (canvas::coord_t (0, 0), alloc_size));
47 canvas c (alloc_size, style_mgr);
48 paint_to_canvas (c);
49 return c;
50 }
51
52 /* class text_art::vbox_widget : public text_art::container_widget. */
53
54 const char *
55 vbox_widget::get_desc () const
56 {
57 return "vbox_widget";
58 }
59
60 canvas::size_t
61 vbox_widget::calc_req_size ()
62 {
63 canvas::size_t result (0, 0);
64 for (auto &child : m_children)
65 {
66 canvas::size_t child_req_size = child->get_req_size();
67 result.h += child_req_size.h;
68 result.w = std::max (result.w, child_req_size.w);
69 }
70 return result;
71 }
72
73 void
74 vbox_widget::update_child_alloc_rects ()
75 {
76 const int x = get_min_x ();
77 int y = get_min_y ();
78 for (auto &child : m_children)
79 {
80 child->set_alloc_rect
81 (canvas::rect_t (canvas::coord_t (x, y),
82 canvas::size_t (get_alloc_w (),
83 child->get_req_h ())));
84 y += child->get_req_h ();
85 }
86 }
87
88 /* class text_art::text_widget : public text_art::leaf_widget. */
89
90 const char *
91 text_widget::get_desc () const
92 {
93 return "text_widget";
94 }
95
96 canvas::size_t
97 text_widget::calc_req_size ()
98 {
99 return canvas::size_t (m_str.size (), 1);
100 }
101
102 void
103 text_widget::paint_to_canvas (canvas &canvas)
104 {
105 canvas.paint_text (get_top_left (), m_str);
106 }
107
108 /* class text_art::canvas_widget : public text_art::leaf_widget. */
109
110 const char *
111 canvas_widget::get_desc () const
112 {
113 return "canvas_widget";
114 }
115
116 canvas::size_t
117 canvas_widget::calc_req_size ()
118 {
119 return m_canvas.get_size ();
120 }
121
122 void
123 canvas_widget::paint_to_canvas (canvas &canvas)
124 {
125 for (int y = 0; y < m_canvas.get_size ().h; y++)
126 for (int x = 0; x < m_canvas.get_size ().w; x++)
127 {
128 canvas::coord_t rel_xy (x, y);
129 canvas.paint (get_top_left () + rel_xy,
130 m_canvas.get (rel_xy));
131 }
132 }
133
134 #if CHECKING_P
135
136 namespace selftest {
137
138 /* Concrete widget subclass for writing selftests.
139 Requests a hard-coded size, and fills its allocated rectangle
140 with a specific character. */
141
142 class test_widget : public leaf_widget
143 {
144 public:
145 test_widget (canvas::size_t size, char ch)
146 : m_test_size (size), m_ch (ch)
147 {}
148
149 const char *get_desc () const final override
150 {
151 return "test_widget";
152 }
153 canvas::size_t calc_req_size () final override
154 {
155 return m_test_size;
156 }
157 void paint_to_canvas (canvas &canvas) final override
158 {
159 canvas.fill (get_alloc_rect (), canvas::cell_t (m_ch));
160 }
161
162 private:
163 canvas::size_t m_test_size;
164 char m_ch;
165 };
166
167 static void
168 test_test_widget ()
169 {
170 style_manager sm;
171 test_widget w (canvas::size_t (3, 3), 'A');
172 canvas c (w.to_canvas (sm));
173 ASSERT_CANVAS_STREQ
174 (c, false,
175 ("AAA\n"
176 "AAA\n"
177 "AAA\n"));
178 }
179
180 static void
181 test_text_widget ()
182 {
183 style_manager sm;
184 text_widget w (styled_string (sm, "hello world"));
185 canvas c (w.to_canvas (sm));
186 ASSERT_CANVAS_STREQ
187 (c, false,
188 ("hello world\n"));
189 }
190
191 static void
192 test_wrapper_widget ()
193 {
194 style_manager sm;
195 wrapper_widget w (::make_unique<test_widget> (canvas::size_t (3, 3), 'B'));
196 canvas c (w.to_canvas (sm));
197 ASSERT_CANVAS_STREQ
198 (c, false,
199 ("BBB\n"
200 "BBB\n"
201 "BBB\n"));
202 }
203
204 static void
205 test_vbox_1 ()
206 {
207 style_manager sm;
208 vbox_widget w;
209 for (int i = 0; i < 5; i++)
210 w.add_child
211 (::make_unique <text_widget>
212 (styled_string::from_fmt (sm, nullptr,
213 "this is line %i", i)));
214 canvas c (w.to_canvas (sm));
215 ASSERT_CANVAS_STREQ
216 (c, false,
217 ("this is line 0\n"
218 "this is line 1\n"
219 "this is line 2\n"
220 "this is line 3\n"
221 "this is line 4\n"));
222 }
223
224 static void
225 test_vbox_2 ()
226 {
227 style_manager sm;
228 vbox_widget w;
229 w.add_child (::make_unique<test_widget> (canvas::size_t (1, 3), 'A'));
230 w.add_child (::make_unique<test_widget> (canvas::size_t (4, 1), 'B'));
231 w.add_child (::make_unique<test_widget> (canvas::size_t (1, 2), 'C'));
232 canvas c (w.to_canvas (sm));
233 ASSERT_CANVAS_STREQ
234 (c, false,
235 ("AAAA\n"
236 "AAAA\n"
237 "AAAA\n"
238 "BBBB\n"
239 "CCCC\n"
240 "CCCC\n"));
241 }
242
243 static void
244 test_canvas_widget ()
245 {
246 style_manager sm;
247 canvas inner_canvas (canvas::size_t (5, 3), sm);
248 inner_canvas.fill (canvas::rect_t (canvas::coord_t (0, 0),
249 canvas::size_t (5, 3)),
250 canvas::cell_t ('a'));
251 canvas_widget cw (std::move (inner_canvas));
252 canvas c (cw.to_canvas (sm));
253 ASSERT_CANVAS_STREQ
254 (c, false,
255 ("aaaaa\n"
256 "aaaaa\n"
257 "aaaaa\n"));
258 }
259
260 /* Run all selftests in this file. */
261
262 void
263 text_art_widget_cc_tests ()
264 {
265 test_test_widget ();
266 test_text_widget ();
267 test_wrapper_widget ();
268 test_vbox_1 ();
269 test_vbox_2 ();
270 test_canvas_widget ();
271 }
272
273 } // namespace selftest
274
275
276 #endif /* #if CHECKING_P */