GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
67 of 206, 0 excluded
32.5%
Functions:
17 of 50, 0 excluded
34.0%
Branches:
10 of 211, 0 excluded
4.7%

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