1 | /* Classes for printing labelled rulers. |
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 |
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. |
11 | |
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. |
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 | #ifndef GCC_TEXT_ART_RULER_H |
22 | #define GCC_TEXT_ART_RULER_H |
23 | |
24 | #include "text-art/canvas.h" |
25 | |
26 | namespace text_art { |
27 | |
28 | /* A way to annotate a series of ranges of canvas coordinates |
29 | with text labels either above or, in this example, below: |
30 | ├───────┬───────┼───────┬───────┼───────┬───────┤ |
31 | │ │ │ |
32 | label A label B label C |
33 | with logic to ensure that the text labels don't overlap |
34 | when printed. */ |
35 | |
36 | class x_ruler |
37 | { |
38 | public: |
39 | enum class label_dir { ABOVE, BELOW }; |
40 | enum class label_kind |
41 | { |
42 | TEXT, |
43 | TEXT_WITH_BORDER |
44 | }; |
45 | |
46 | x_ruler (label_dir dir) |
47 | : m_label_dir (dir), |
48 | m_size (canvas::size_t (0, 0)), |
49 | m_has_layout (false) |
50 | {} |
51 | |
52 | void add_label (const canvas::range_t &r, |
53 | styled_string text, |
54 | style::id_t style_id, |
55 | label_kind kind = label_kind::TEXT); |
56 | |
57 | canvas::size_t get_size () |
58 | { |
59 | ensure_layout (); |
60 | return m_size; |
61 | } |
62 | |
63 | void paint_to_canvas (canvas &canvas, |
64 | canvas::coord_t offset, |
65 | const theme &theme); |
66 | |
67 | void debug (const style_manager &sm); |
68 | |
69 | private: |
70 | /* A particular label within an x_ruler. |
71 | Consider e.g.: |
72 | |
73 | # x: 01234567890123456789012345678901234567890123456789 |
74 | # y: 0: ├───────┬───────┼───────┬───────┼───────┬───────┤ |
75 | # 1: │ │ │ |
76 | # 2: label A label B label C |
77 | # |
78 | |
79 | Then "label A" is: |
80 | |
81 | # m_connector_x == 8 |
82 | # V |
83 | # x: 0123456789012 |
84 | # y: 0: ┬ |
85 | # 1: │ |
86 | # 2: label A |
87 | # x: 0123456789012 |
88 | # ^ |
89 | # m_text_coord.x == 6 |
90 | |
91 | and m_text_coord is (2, 6). |
92 | The y cooordinates are stored with respect to label_dir::BELOW; |
93 | for label_dir::ABOVE we flip them when painting the ruler. */ |
94 | class label |
95 | { |
96 | friend class x_ruler; |
97 | public: |
98 | label (const canvas::range_t &range, styled_string text, style::id_t style_id, |
99 | label_kind kind); |
100 | |
101 | bool operator< (const label &other) const; |
102 | |
103 | private: |
104 | canvas::range_t m_range; |
105 | styled_string m_text; |
106 | style::id_t m_style_id; |
107 | label_kind m_kind; |
108 | canvas::rect_t m_text_rect; // includes any border |
109 | int m_connector_x; |
110 | }; |
111 | |
112 | void ensure_layout (); |
113 | void update_layout (); |
114 | int get_canvas_y (int rel_y) const; |
115 | |
116 | label_dir m_label_dir; |
117 | std::vector<label> m_labels; |
118 | canvas::size_t m_size; |
119 | bool m_has_layout = false; |
120 | |
121 | }; |
122 | |
123 | } // namespace text_art |
124 | |
125 | #endif /* GCC_TEXT_ART_RULER_H */ |
126 | |