libstdc++: Implement C++23 <print> header [PR107760]
[official-gcc.git] / gcc / text-art / table.h
blob5d5d4bdde1f701853e0e9a14986c22403c8f0754
1 /* Support for tabular/grid-based content.
2 Copyright (C) 2023 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_TABLE_H
22 #define GCC_TEXT_ART_TABLE_H
24 #include "text-art/canvas.h"
25 #include "text-art/theme.h"
27 namespace text_art {
29 class table;
30 class table_geometry;
32 /* A class representing the content of a particular table cell,
33 or of a span of table cells. */
35 class table_cell_content
37 public:
38 table_cell_content () : m_str (), m_size (0, 0) {}
39 table_cell_content (styled_string &&s);
41 bool operator== (const table_cell_content &other) const
43 return m_str == other.m_str;
46 canvas::size_t get_canvas_size () const { return m_size; }
48 void paint_to_canvas (canvas &canvas,
49 canvas::coord_t top_left) const;
51 private:
52 styled_string m_str;
53 canvas::size_t m_size;
56 /* A list of required sizes of table rows or columns
57 in canvas units (row heights or column widths). */
59 struct table_dimension_sizes
61 table_dimension_sizes (unsigned num);
63 void require (unsigned idx, int amount)
65 m_requirements[idx] = std::max (m_requirements[idx], amount);
68 std::vector<int> m_requirements;
71 /* A 2D grid of cells. Instances of table_cell_content can be assigned
72 to individual table cells, and to rectangular spans of cells. Such
73 assignments do not have to fully cover the 2D grid, but they must not
74 overlap. */
76 class table
78 public:
79 typedef size<class table> size_t;
80 typedef coord<class table> coord_t;
81 typedef range<class table> range_t;
82 typedef rect<class table> rect_t;
84 /* A record of how a table_cell_content was placed at a table::rect_t
85 with a certain alignment. */
86 class cell_placement
88 public:
89 cell_placement (rect_t rect,
90 table_cell_content &&content,
91 x_align x_align,
92 y_align y_align)
93 : m_rect (rect),
94 m_content (std::move (content)),
95 m_x_align (x_align),
96 m_y_align (y_align)
100 bool one_by_one_p () const
102 return m_rect.m_size.w == 1 && m_rect.m_size.h == 1;
105 canvas::size_t get_min_canvas_size () const
107 // Doesn't include border
108 return m_content.get_canvas_size ();
111 void paint_cell_contents_to_canvas(canvas &canvas,
112 canvas::coord_t offset,
113 const table_geometry &tg) const;
115 const table_cell_content &get_content () const { return m_content; }
117 private:
118 friend class table;
119 friend class table_cell_sizes;
120 rect_t m_rect;
121 table_cell_content m_content;
122 x_align m_x_align;
123 y_align m_y_align;
126 table (size_t size);
127 ~table () = default;
128 table (table &&) = default;
129 table (const table &) = delete;
130 table &operator= (const table &) = delete;
132 const size_t &get_size () const { return m_size; }
134 int add_rows (unsigned num)
136 int topmost_new_row = m_size.h;
137 m_size.h += num;
138 for (unsigned i = 0; i < num; i++)
139 m_occupancy.add_row (-1);
140 return topmost_new_row;
143 int add_row ()
145 return add_rows (1);
148 void set_cell (coord_t coord,
149 table_cell_content &&content,
150 enum x_align x_align = x_align::CENTER,
151 enum y_align y_align = y_align::CENTER);
153 void set_cell_span (rect_t span,
154 table_cell_content &&content,
155 enum x_align x_align = x_align::CENTER,
156 enum y_align y_align = y_align::CENTER);
158 void maybe_set_cell_span (rect_t span,
159 table_cell_content &&content,
160 enum x_align x_align = x_align::CENTER,
161 enum y_align y_align = y_align::CENTER);
163 canvas to_canvas (const theme &theme, const style_manager &sm) const;
165 void paint_to_canvas(canvas &canvas,
166 canvas::coord_t offset,
167 const table_geometry &tg,
168 const theme &theme) const;
170 void debug () const;
172 void add_other_table (table &&other, table::coord_t offset);
174 /* Self-test support. */
175 const cell_placement *get_placement_at (coord_t coord) const;
177 private:
178 int get_occupancy_safe (coord_t coord) const;
179 directions get_connections (int table_x, int table_y) const;
180 void paint_cell_borders_to_canvas(canvas &canvas,
181 canvas::coord_t offset,
182 const table_geometry &tg,
183 const theme &theme) const;
184 void paint_cell_contents_to_canvas(canvas &canvas,
185 canvas::coord_t offset,
186 const table_geometry &tg) const;
188 friend class table_cell_sizes;
190 size_t m_size;
191 std::vector<cell_placement> m_placements;
192 array2<int, size_t, coord_t> m_occupancy; /* indices into the m_placements vec. */
195 /* A workspace for computing the row heights and column widths
196 of a table (in canvas units).
197 The col_widths and row_heights could be shared between multiple
198 instances, for aligning multiple tables vertically or horizontally. */
200 class table_cell_sizes
202 public:
203 table_cell_sizes (table_dimension_sizes &col_widths,
204 table_dimension_sizes &row_heights)
205 : m_col_widths (col_widths),
206 m_row_heights (row_heights)
210 void pass_1 (const table &table);
211 void pass_2 (const table &table);
213 canvas::size_t get_canvas_size (const table::rect_t &rect) const;
215 table_dimension_sizes &m_col_widths;
216 table_dimension_sizes &m_row_heights;
219 /* A class responsible for mapping from table cell coords
220 to canvas coords, handling column widths.
221 It's the result of solving "how big are all the table cells and where
222 do they go?"
223 The cell_sizes are passed in, for handling aligning multiple tables,
224 sharing column widths or row heights. */
226 class table_geometry
228 public:
229 table_geometry (const table &table, table_cell_sizes &cell_sizes);
231 void recalc_coords ();
233 const canvas::size_t get_canvas_size () const { return m_canvas_size; }
235 canvas::coord_t table_to_canvas (table::coord_t table_coord) const;
236 int table_x_to_canvas_x (int table_x) const;
237 int table_y_to_canvas_y (int table_y) const;
239 int get_col_width (int table_x) const
241 return m_cell_sizes.m_col_widths.m_requirements[table_x];
244 canvas::size_t get_canvas_size (const table::rect_t &rect) const
246 return m_cell_sizes.get_canvas_size (rect);
249 private:
250 table_cell_sizes &m_cell_sizes;
251 canvas::size_t m_canvas_size;
253 /* Start canvas column of table cell, including leading border. */
254 std::vector<int> m_col_start_x;
256 /* Start canvas row of table cell, including leading border. */
257 std::vector<int> m_row_start_y;
260 /* Helper class for handling the simple case of a single table
261 that doesn't need to be aligned with respect to anything else. */
263 struct simple_table_geometry
265 simple_table_geometry (const table &table);
267 table_dimension_sizes m_col_widths;
268 table_dimension_sizes m_row_heights;
269 table_cell_sizes m_cell_sizes;
270 table_geometry m_tg;
273 } // namespace text_art
275 #endif /* GCC_TEXT_ART_TABLE_H */