libstdc++: Prefer posix_memalign for aligned-new [PR113258]
[official-gcc.git] / gcc / text-art / widget.cc
blob38df5ad540c24a603036e8e1c76f5e0e9f695b33
1 /* Hierarchical diagram elements.
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 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.
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.
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 #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"
32 using namespace text_art;
34 /* class text_art::widget. */
36 canvas
37 widget::to_canvas (const style_manager &style_mgr)
39 const canvas::size_t req_size = get_req_size ();
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;
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;
52 /* class text_art::vbox_widget : public text_art::container_widget. */
54 const char *
55 vbox_widget::get_desc () const
57 return "vbox_widget";
60 canvas::size_t
61 vbox_widget::calc_req_size ()
63 canvas::size_t result (0, 0);
64 for (auto &child : m_children)
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);
70 return result;
73 void
74 vbox_widget::update_child_alloc_rects ()
76 const int x = get_min_x ();
77 int y = get_min_y ();
78 for (auto &child : m_children)
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 ();
88 /* class text_art::text_widget : public text_art::leaf_widget. */
90 const char *
91 text_widget::get_desc () const
93 return "text_widget";
96 canvas::size_t
97 text_widget::calc_req_size ()
99 return canvas::size_t (m_str.size (), 1);
102 void
103 text_widget::paint_to_canvas (canvas &canvas)
105 canvas.paint_text (get_top_left (), m_str);
108 /* class text_art::canvas_widget : public text_art::leaf_widget. */
110 const char *
111 canvas_widget::get_desc () const
113 return "canvas_widget";
116 canvas::size_t
117 canvas_widget::calc_req_size ()
119 return m_canvas.get_size ();
122 void
123 canvas_widget::paint_to_canvas (canvas &canvas)
125 for (int y = 0; y < m_canvas.get_size ().h; y++)
126 for (int x = 0; x < m_canvas.get_size ().w; x++)
128 canvas::coord_t rel_xy (x, y);
129 canvas.paint (get_top_left () + rel_xy,
130 m_canvas.get (rel_xy));
134 #if CHECKING_P
136 namespace selftest {
138 /* Concrete widget subclass for writing selftests.
139 Requests a hard-coded size, and fills its allocated rectangle
140 with a specific character. */
142 class test_widget : public leaf_widget
144 public:
145 test_widget (canvas::size_t size, char ch)
146 : m_test_size (size), m_ch (ch)
149 const char *get_desc () const final override
151 return "test_widget";
153 canvas::size_t calc_req_size () final override
155 return m_test_size;
157 void paint_to_canvas (canvas &canvas) final override
159 canvas.fill (get_alloc_rect (), canvas::cell_t (m_ch));
162 private:
163 canvas::size_t m_test_size;
164 char m_ch;
167 static void
168 test_test_widget ()
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"));
180 static void
181 test_text_widget ()
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"));
191 static void
192 test_wrapper_widget ()
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"));
204 static void
205 test_vbox_1 ()
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"));
224 static void
225 test_vbox_2 ()
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"));
243 static void
244 test_canvas_widget ()
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"));
260 /* Run all selftests in this file. */
262 void
263 text_art_widget_cc_tests ()
265 test_test_widget ();
266 test_text_widget ();
267 test_wrapper_widget ();
268 test_vbox_1 ();
269 test_vbox_2 ();
270 test_canvas_widget ();
273 } // namespace selftest
276 #endif /* #if CHECKING_P */