GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
57 of 195, 0 excluded
29.2%
Functions:
15 of 48, 0 excluded
31.2%
Branches:
8 of 189, 0 excluded
4.2%

libs/base/src/eu/base/rect.cc
Line Branch Exec Source
1 #include "eu/base/rect.h"
2
3 namespace eu
4 {
5
6 Rect::Rect()
7 : left(0)
8 , right(0)
9 , top(0)
10 , bottom(0)
11 {
12 }
13
14 [[nodiscard]] Rect
15 32 Rect::from_left_right_top_bottom(float left_side, float right_side, float top_side, float bottom_side)
16 {
17
1/10
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 17 taken 32 times.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 38 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 36 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 44 not taken.
32 ASSERTX(left_side <= right_side, left_side, right_side);
18
1/10
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 32 taken 32 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 54 not taken.
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 52 not taken.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 60 not taken.
32 ASSERTX(top_side >= bottom_side, top_side, bottom_side);
19 32 return {left_side, right_side, top_side, bottom_side};
20 }
21
22 [[nodiscard]] Rect
23 16 Rect::from_bottom_left_size(const v2& bl, const v2& size)
24 {
25
1/6
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 9 taken 16 times.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 9 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 19 not taken.
16 ASSERT(size.x >= 0);
26
1/6
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 16 taken 16 times.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 16 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 22 not taken.
16 ASSERT(size.y >= 0);
27 return from_left_right_top_bottom
28 16 (
29 16 bl.x, bl.x + size.x,
30 16 bl.y + size.y, bl.y
31 16 );
32 }
33
34 [[nodiscard]] Rect
35 Rect::from_top_left_size(const v2& tl, const v2& size)
36 {
37 ASSERT(size.x >= 0);
38 ASSERT(size.y >= 0);
39 return from_left_right_top_bottom
40 (
41 tl.x, tl.x + size.x,
42 tl.y, tl.y - size.y
43 );
44 }
45
46 [[nodiscard]] Rect
47 Rect::from_size(const v2& size)
48 {
49 ASSERTX(size.x >= 0, size.x);
50 ASSERTX(size.y >= 0, size.y);
51 return from_left_right_bottom_top(0, size.x, 0, size.y);
52 }
53
54 [[nodiscard]] Rect
55 Rect::from_point(const v2& point)
56 {
57 return from_top_left_size(point, {0.0f, 0.0f});
58 }
59
60 v2
61 Rect::get_bottom_left() const
62 {
63 return {left, bottom};
64 }
65
66 Rect
67 Rect::from_center_inside_other(const Rect& self, const Rect& other)
68 {
69 const auto size = self.get_size();
70 const auto lower_left = other.get_center_pos() - self.get_relative_center_pos();
71 return Rect::from_top_left_size
72 (
73 {lower_left.x, lower_left.y + size.y}, size
74 );
75 }
76
77 Rect
78 Rect::from_scaled(const Rect& self, float scale)
79 {
80 const auto s = self.get_size();
81 const auto ns = s * scale;
82 return self.with_inset
83 ({
84 (s.x - ns.x) / 2,
85 (s.y - ns.y) / 2
86 });
87 }
88
89 v2
90 Rect::get_relative_center_pos() const
91 {
92 const auto size = get_size();
93 const auto cx = size.x / 2;
94 const auto cy = size.y / 2;
95 return {cx, cy};
96 }
97
98 v2
99 Rect::get_center_pos() const
100 {
101 const auto rc = get_relative_center_pos();
102 const auto cx = left + rc.x;
103 const auto cy = bottom + rc.y;
104 return {cx, cy};
105 }
106
107 bool
108 Rect::contains_exclusive(const Rect& r) const
109 {
110 ASSERT(is_valid());
111 ASSERT(r.is_valid());
112
113 return left < r.left
114 && right > r.right
115 && top > r.top
116 && bottom < r.bottom
117 ;
118 }
119
120 void
121 Rect::inset(const Lrtb& lrtb)
122 {
123 left += lrtb.left;
124 right -= lrtb.right;
125 top -= lrtb.top;
126 bottom += lrtb.bottom;
127 }
128
129 Rect
130 Rect::with_inset(const Lrtb& lrtb) const
131 {
132 Rect ret = *this;
133 ret.inset(lrtb);
134 return ret;
135 }
136
137 void
138 Rect::extend(const Rect& o)
139 {
140 left = min(left, o.left);
141 right = max(right, o.right);
142 top = max(top, o.top);
143 bottom = min(bottom, o.bottom);
144 }
145
146
147 [[nodiscard]] bool
148 Rect::is_empty() const
149 {
150 return left >= right || top <= bottom;
151 }
152
153
154 [[nodiscard]] bool
155 Rect::is_valid() const
156 {
157 const auto size = get_size();
158 return size.x >= 0 && size.y >= 0;
159 }
160
161
162 void
163 Rect::translate(const v2& d)
164 {
165 left += d.x;
166 right += d.x;
167 top += d.y;
168 bottom += d.y;
169 }
170
171 Rect
172 Rect::with_translate(const v2& d) const
173 {
174 Rect ret = *this;
175 ret.translate(d);
176 return ret;
177 }
178
179
180 Rect
181 Rect::with_top_left_at(const v2& p) const
182 {
183 return from_top_left_size
184 (
185 p,
186 get_size()
187 );
188 }
189
190 Rect
191 Rect::with_bottom_left_at(const v2& p) const
192 {
193 const auto size = get_size();
194 return from_top_left_size
195 (
196 v2{p.x, p.y + size.y},
197 size
198 );
199 }
200
201 [[nodiscard]] Rect
202 Rect::with_offset(const v2& p) const
203 {
204 return from_top_left_size(get_top_left() + p, get_size());
205 }
206
207
208 [[nodiscard]] Rect
209 Rect::with_scale(float hor, float vert) const
210 {
211 return from_left_right_top_bottom(left * hor, right * hor, top * vert, bottom * vert);
212 }
213
214 void
215 Rect::set_empty()
216 {
217 left = right = top = bottom = 0;
218 }
219
220
221 v2
222 Rect::get_size() const
223 {
224 const auto height = top - bottom;
225 const auto width = right - left;
226 return { width, height };
227 }
228
229
230 R<float>
231 Rect::get_range_y() const
232 {
233 return {bottom, top};
234 }
235
236 R<float>
237 Rect::get_range_x() const
238 {
239 return {left, right};
240 }
241
242 [[nodiscard]] v2
243 Rect::get_top_left() const
244 {
245 return {left, top};
246 }
247
248 [[nodiscard]] v2
249 Rect::get_top_right() const
250 {
251 return {right, top};
252 }
253
254 [[nodiscard]] v2
255 Rect::get_bottom_right() const
256 {
257 return {right, bottom};
258 }
259
260 Rect Rect::cut(RectCut side, float amount, float spacing)
261 {
262 switch (side)
263 {
264 case RectCut::left: return cut_left(amount, spacing);
265 case RectCut::right: return cut_right(amount, spacing);
266 case RectCut::top: return cut_top(amount, spacing);
267 case RectCut::bottom: return cut_bottom(amount, spacing);
268 default:
269 DIE("invalid rectcut");
270 return cut_left(amount);
271 }
272 }
273
274 16 Rect lbrt(float l, float b, float r, float t)
275 {
276 16 return Rect::from_left_right_top_bottom(l, r, t, b);
277 }
278
279 2 Rect Rect::cut_top(float amount, float v_spacing)
280 {
281 2 const float old_max_y = top;
282 2 top = std::max(left, top - amount);
283
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 6 not taken.
2 Rect area = lbrt(left, top, right, old_max_y);
284 2 top -= v_spacing;
285 2 return area;
286 }
287
288 2 Rect Rect::cut_right(float amount, float h_spacing)
289 {
290 2 const float old_max_x = right;
291 2 right = std::max(left, right - amount);
292
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 6 not taken.
2 Rect area = lbrt(right, bottom, old_max_x, top);
293 2 right -= h_spacing;
294 2 return area;
295 }
296
297 2 Rect Rect::cut_bottom(float amount, float v_spacing)
298 {
299 2 const float old_min_y = bottom;
300 2 bottom = std::min(top, bottom + amount);
301
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 6 not taken.
2 Rect area = lbrt(left, old_min_y, right, bottom);
302 2 bottom += v_spacing;
303 2 return area;
304 }
305
306 2 Rect Rect::cut_left(float amount, float h_spacing)
307 {
308 2 const float old_min_x = left;
309 2 left = std::min(right, left + amount);
310
1/2
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 6 not taken.
2 Rect area = lbrt(old_min_x, bottom, left, top);
311 2 left += h_spacing;
312 2 return area;
313 }
314
315 1 Rect Rect::get_top(float amount) const
316 {
317 1 const float new_min_y = std::max(bottom, top - amount);
318 1 return lbrt(left, new_min_y, right, top);
319 }
320
321 1 Rect Rect::get_right(float amount) const
322 {
323 1 const float new_min_x = std::max(left, right - amount);
324 1 return lbrt(new_min_x, bottom, right, top);
325 }
326
327 1 Rect Rect::get_bottom(float amount) const
328 {
329 1 const float new_max_y = std::min(top, bottom + amount);
330 1 return lbrt(left, bottom, right, new_max_y);
331 }
332
333 1 Rect Rect::get_left(float amount) const
334 {
335 1 const float new_max_x = std::min(right, left + amount);
336 1 return lbrt(left, bottom, new_max_x, top);
337 }
338
339 1 Rect Rect::add_top(float amount) const
340 {
341 1 return lbrt(left, top, right, top + amount);
342 }
343
344 1 Rect Rect::add_right(float amount) const
345 {
346 1 return lbrt(right, bottom, right + amount, top);
347 }
348
349 1 Rect Rect::add_bottom(float amount) const
350 {
351 1 return lbrt(left, bottom - amount, right, bottom);
352 }
353
354 1 Rect Rect::add_left(float amount) const
355 {
356 1 return lbrt(left - amount, bottom, left, top);
357 }
358
359
360 ///////////////////////////////////////////////////////////////////////////
361
362
363 [[nodiscard]] v2
364 to_01(const Rect& r, const v2& from)
365 {
366 const auto x = to01(make_range(r.left, r.right), from.x);
367 const auto y = to01(make_range(r.bottom, r.top), from.y);
368 return {x, y};
369 }
370
371 [[nodiscard]] v2
372 from_01(const Rect& r, const v2& from)
373 {
374 const auto x = from_01(make_range(r.left, r.right), from.x);
375 const auto y = from_01(make_range(r.bottom, r.top), from.y);
376 return {x, y};
377 }
378
379 bool
380 is_within(const v2& p, const Rect& r)
381 {
382 ASSERT(r.is_valid());
383 return r.left <= p.x && p.x <= r.right
384 && r.bottom <= p.y && p.y <= r.top
385 ;
386 }
387
388 std::string to_string(const Rect& r)
389 {
390 const auto size = r.get_size();
391 return fmt::format("({}, {} / {} x {})", r.left, r.bottom, size.x, size.y);
392 }
393 }
394