Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/scene/test_bit_map.h
10277 views
1
/**************************************************************************/
2
/* test_bit_map.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/os/memory.h"
34
#include "scene/resources/bit_map.h"
35
#include "tests/test_macros.h"
36
37
namespace TestBitmap {
38
39
void reset_bit_map(BitMap &p_bm) {
40
Size2i size = p_bm.get_size();
41
p_bm.set_bit_rect(Rect2i(0, 0, size.width, size.height), false);
42
}
43
44
TEST_CASE("[BitMap] Create bit map") {
45
Size2i dim{ 256, 512 };
46
BitMap bit_map{};
47
bit_map.create(dim);
48
CHECK(bit_map.get_size() == Size2i(256, 512));
49
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "This will go through the entire bitmask inside of bitmap, thus hopefully checking if the bitmask was correctly set up.");
50
51
ERR_PRINT_OFF
52
53
dim = Size2i(0, 256);
54
bit_map.create(dim);
55
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is invalid.");
56
57
dim = Size2i(512, 0);
58
bit_map.create(dim);
59
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is invalid.");
60
61
dim = Size2i(46341, 46341);
62
bit_map.create(dim);
63
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 512), "We should still have the same dimensions as before, because the new dimension is too large (46341*46341=2147488281).");
64
65
ERR_PRINT_ON
66
}
67
68
TEST_CASE("[BitMap] Create bit map from image alpha") {
69
const Size2i dim{ 256, 256 };
70
BitMap bit_map{};
71
bit_map.create(dim);
72
73
ERR_PRINT_OFF
74
75
const Ref<Image> null_img = nullptr;
76
bit_map.create_from_image_alpha(null_img);
77
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because bitmap creation from a nullptr should fail.");
78
79
Ref<Image> empty_img;
80
empty_img.instantiate();
81
bit_map.create_from_image_alpha(empty_img);
82
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because bitmap creation from an empty image should fail.");
83
84
Ref<Image> wrong_format_img = Image::create_empty(3, 3, false, Image::Format::FORMAT_DXT1);
85
bit_map.create_from_image_alpha(wrong_format_img);
86
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Bitmap should have its old values because converting from a compressed image should fail.");
87
88
ERR_PRINT_ON
89
90
Ref<Image> img = Image::create_empty(3, 3, false, Image::Format::FORMAT_RGBA8);
91
img->set_pixel(0, 0, Color(0, 0, 0, 0));
92
img->set_pixel(0, 1, Color(0, 0, 0, 0.09f));
93
img->set_pixel(0, 2, Color(0, 0, 0, 0.25f));
94
img->set_pixel(1, 0, Color(0, 0, 0, 0.5f));
95
img->set_pixel(1, 1, Color(0, 0, 0, 0.75f));
96
img->set_pixel(1, 2, Color(0, 0, 0, 0.99f));
97
img->set_pixel(2, 0, Color(0, 0, 0, 1.f));
98
99
// Check different threshold values.
100
bit_map.create_from_image_alpha(img);
101
CHECK_MESSAGE(bit_map.get_true_bit_count() == 5, "There are 5 values in the image that are smaller than the default threshold of 0.1.");
102
103
bit_map.create_from_image_alpha(img, 0.08f);
104
CHECK_MESSAGE(bit_map.get_true_bit_count() == 6, "There are 6 values in the image that are smaller than the threshold of 0.08.");
105
106
bit_map.create_from_image_alpha(img, 1);
107
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "There are no values in the image that are smaller than the threshold of 1, there is one value equal to 1, but we check for inequality only.");
108
}
109
110
TEST_CASE("[BitMap] Set bit") {
111
Size2i dim{ 256, 256 };
112
BitMap bit_map{};
113
114
// Setting a point before a bit map is created should not crash, because there are checks to see if we are out of bounds.
115
ERR_PRINT_OFF
116
117
bit_map.set_bitv(Point2i(128, 128), true);
118
119
bit_map.create(dim);
120
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "All values should be initialized to false.");
121
bit_map.set_bitv(Point2i(128, 128), true);
122
CHECK_MESSAGE(bit_map.get_true_bit_count() == 1, "One bit should be set to true.");
123
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == true, "The bit at (128,128) should be set to true");
124
125
bit_map.set_bitv(Point2i(128, 128), false);
126
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "The bit should now be set to false again");
127
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == false, "The bit at (128,128) should now be set to false again");
128
129
bit_map.create(dim);
130
bit_map.set_bitv(Point2i(512, 512), true);
131
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Nothing should change as we were trying to edit a bit outside of the correct range.");
132
133
ERR_PRINT_ON
134
}
135
136
TEST_CASE("[BitMap] Get bit") {
137
const Size2i dim{ 256, 256 };
138
BitMap bit_map{};
139
140
ERR_PRINT_OFF
141
142
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 128)) == false, "Trying to access a bit outside of the BitMap's range should always return false");
143
144
bit_map.create(dim);
145
CHECK(bit_map.get_bitv(Point2i(128, 128)) == false);
146
147
bit_map.set_bit_rect(Rect2i(-1, -1, 257, 257), true);
148
149
// Checking that range is [0, 256).
150
CHECK(bit_map.get_bitv(Point2i(-1, 0)) == false);
151
CHECK(bit_map.get_bitv(Point2i(0, 0)) == true);
152
CHECK(bit_map.get_bitv(Point2i(128, 128)) == true);
153
CHECK(bit_map.get_bitv(Point2i(255, 255)) == true);
154
CHECK(bit_map.get_bitv(Point2i(256, 256)) == false);
155
CHECK(bit_map.get_bitv(Point2i(257, 257)) == false);
156
157
ERR_PRINT_ON
158
}
159
160
TEST_CASE("[BitMap] Set bit rect") {
161
const Size2i dim{ 256, 256 };
162
BitMap bit_map{};
163
164
// Although we have not setup the BitMap yet, this should not crash because we get an empty intersection inside of the method.
165
bit_map.set_bit_rect(Rect2i{ 0, 0, 128, 128 }, true);
166
167
bit_map.create(dim);
168
CHECK(bit_map.get_true_bit_count() == 0);
169
170
bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, true);
171
CHECK(bit_map.get_true_bit_count() == 65536);
172
173
reset_bit_map(bit_map);
174
175
// Checking out of bounds handling.
176
177
ERR_PRINT_OFF
178
179
bit_map.set_bit_rect(Rect2i{ 128, 128, 256, 256 }, true);
180
CHECK(bit_map.get_true_bit_count() == 16384);
181
182
reset_bit_map(bit_map);
183
184
bit_map.set_bit_rect(Rect2i{ -128, -128, 256, 256 }, true);
185
CHECK(bit_map.get_true_bit_count() == 16384);
186
187
reset_bit_map(bit_map);
188
189
bit_map.set_bit_rect(Rect2i{ -128, -128, 512, 512 }, true);
190
CHECK(bit_map.get_true_bit_count() == 65536);
191
192
ERR_PRINT_ON
193
}
194
195
TEST_CASE("[BitMap] Get true bit count") {
196
const Size2i dim{ 256, 256 };
197
BitMap bit_map{};
198
199
CHECK(bit_map.get_true_bit_count() == 0);
200
201
bit_map.create(dim);
202
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Uninitialized bit map should have no true bits");
203
bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, true);
204
CHECK(bit_map.get_true_bit_count() == 65536);
205
bit_map.set_bitv(Point2i{ 0, 0 }, false);
206
CHECK(bit_map.get_true_bit_count() == 65535);
207
bit_map.set_bit_rect(Rect2i{ 0, 0, 256, 256 }, false);
208
CHECK(bit_map.get_true_bit_count() == 0);
209
}
210
211
TEST_CASE("[BitMap] Get size") {
212
const Size2i dim{ 256, 256 };
213
BitMap bit_map{};
214
215
CHECK_MESSAGE(bit_map.get_size() == Size2i(0, 0), "Uninitialized bit map should have a size of 0x0");
216
217
bit_map.create(dim);
218
CHECK(bit_map.get_size() == Size2i(256, 256));
219
220
ERR_PRINT_OFF
221
bit_map.create(Size2i(-1, 0));
222
ERR_PRINT_ON
223
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "Invalid size should not be accepted by create");
224
225
bit_map.create(Size2i(256, 128));
226
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 128), "Bitmap should have updated size");
227
}
228
229
TEST_CASE("[BitMap] Resize") {
230
const Size2i dim{ 128, 128 };
231
BitMap bit_map{};
232
233
bit_map.resize(dim);
234
CHECK(bit_map.get_size() == dim);
235
236
bit_map.create(dim);
237
bit_map.set_bit_rect(Rect2i(0, 0, 10, 10), true);
238
bit_map.set_bit_rect(Rect2i(118, 118, 10, 10), true);
239
CHECK_MESSAGE(bit_map.get_true_bit_count() == 200, "There should be 100 bits in the top left corner, and 100 bits in the bottom right corner");
240
bit_map.resize(Size2i(64, 64));
241
CHECK_MESSAGE(bit_map.get_true_bit_count() == 50, "There should be 25 bits in the top left corner, and 25 bits in the bottom right corner");
242
243
bit_map.create(dim);
244
ERR_PRINT_OFF
245
bit_map.resize(Size2i(-1, 128));
246
ERR_PRINT_ON
247
CHECK_MESSAGE(bit_map.get_size() == Size2i(128, 128), "When an invalid size is given the bit map will keep its size");
248
249
bit_map.create(dim);
250
bit_map.set_bit_rect(Rect2i(0, 0, 10, 10), true);
251
bit_map.set_bit_rect(Rect2i(118, 118, 10, 10), true);
252
CHECK_MESSAGE(bit_map.get_true_bit_count() == 200, "There should be 100 bits in the top left corner, and 100 bits in the bottom right corner");
253
bit_map.resize(Size2i(256, 256));
254
CHECK_MESSAGE(bit_map.get_true_bit_count() == 800, "There should still be 100 bits in the bottom right corner, and all new bits should be initialized to false");
255
CHECK_MESSAGE(bit_map.get_size() == Size2i(256, 256), "The bitmap should now be 256x256");
256
}
257
258
TEST_CASE("[BitMap] Grow and shrink mask") {
259
const Size2i dim{ 256, 256 };
260
BitMap bit_map{};
261
ERR_PRINT_OFF
262
bit_map.grow_mask(100, Rect2i(0, 0, 128, 128)); // Check if method does not crash when working with an uninitialized bit map.
263
ERR_PRINT_ON
264
CHECK_MESSAGE(bit_map.get_size() == Size2i(0, 0), "Size should still be equal to 0x0");
265
266
bit_map.create(dim);
267
268
bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true);
269
270
CHECK_MESSAGE(bit_map.get_true_bit_count() == 4096, "Creating a square of 64x64 should be 4096 bits");
271
bit_map.grow_mask(0, Rect2i(0, 0, 256, 256));
272
CHECK_MESSAGE(bit_map.get_true_bit_count() == 4096, "Growing with size of 0 should not change any bits");
273
274
reset_bit_map(bit_map);
275
276
bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true);
277
278
CHECK_MESSAGE(bit_map.get_bitv(Point2i(95, 128)) == false, "Bits just outside of the square should not be set");
279
CHECK_MESSAGE(bit_map.get_bitv(Point2i(160, 128)) == false, "Bits just outside of the square should not be set");
280
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 95)) == false, "Bits just outside of the square should not be set");
281
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 160)) == false, "Bits just outside of the square should not be set");
282
bit_map.grow_mask(1, Rect2i(0, 0, 256, 256));
283
CHECK_MESSAGE(bit_map.get_true_bit_count() == 4352, "We should have 4*64 (perimeter of square) more bits set to true");
284
CHECK_MESSAGE(bit_map.get_bitv(Point2i(95, 128)) == true, "Bits that were just outside of the square should now be set to true");
285
CHECK_MESSAGE(bit_map.get_bitv(Point2i(160, 128)) == true, "Bits that were just outside of the square should now be set to true");
286
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 95)) == true, "Bits that were just outside of the square should now be set to true");
287
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128, 160)) == true, "Bits that were just outside of the square should now be set to true");
288
289
reset_bit_map(bit_map);
290
291
bit_map.set_bit_rect(Rect2i(127, 127, 1, 1), true);
292
293
CHECK(bit_map.get_true_bit_count() == 1);
294
bit_map.grow_mask(32, Rect2i(0, 0, 256, 256));
295
CHECK_MESSAGE(bit_map.get_true_bit_count() == 3209, "Creates a circle around the initial bit with a radius of 32 bits. Any bit that has a distance within this radius will be set to true");
296
297
reset_bit_map(bit_map);
298
299
bit_map.set_bit_rect(Rect2i(127, 127, 1, 1), true);
300
for (int i = 0; i < 32; i++) {
301
bit_map.grow_mask(1, Rect2i(0, 0, 256, 256));
302
}
303
CHECK_MESSAGE(bit_map.get_true_bit_count() == 2113, "Creates a diamond around the initial bit with diagonals that are 65 bits long.");
304
305
reset_bit_map(bit_map);
306
307
bit_map.set_bit_rect(Rect2i(123, 123, 10, 10), true);
308
309
CHECK(bit_map.get_true_bit_count() == 100);
310
bit_map.grow_mask(-11, Rect2i(0, 0, 256, 256));
311
CHECK_MESSAGE(bit_map.get_true_bit_count() == 0, "Shrinking by more than the width of the square should totally remove it.");
312
313
reset_bit_map(bit_map);
314
bit_map.set_bit_rect(Rect2i(96, 96, 64, 64), true);
315
316
CHECK_MESSAGE(bit_map.get_bitv(Point2i(96, 129)) == true, "Bits on the edge of the square should be true");
317
CHECK_MESSAGE(bit_map.get_bitv(Point2i(159, 129)) == true, "Bits on the edge of the square should be true");
318
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 96)) == true, "Bits on the edge of the square should be true");
319
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 159)) == true, "Bits on the edge of the square should be true");
320
bit_map.grow_mask(-1, Rect2i(0, 0, 256, 256));
321
CHECK_MESSAGE(bit_map.get_true_bit_count() == 3844, "Shrinking by 1 should set 4*63=252 bits to false");
322
CHECK_MESSAGE(bit_map.get_bitv(Point2i(96, 129)) == false, "Bits that were on the edge of the square should now be set to false");
323
CHECK_MESSAGE(bit_map.get_bitv(Point2i(159, 129)) == false, "Bits that were on the edge of the square should now be set to false");
324
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 96)) == false, "Bits that were on the edge of the square should now be set to false");
325
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129, 159)) == false, "Bits that were on the edge of the square should now be set to false");
326
327
reset_bit_map(bit_map);
328
329
bit_map.set_bit_rect(Rect2i(125, 125, 1, 6), true);
330
bit_map.set_bit_rect(Rect2i(130, 125, 1, 6), true);
331
bit_map.set_bit_rect(Rect2i(125, 130, 6, 1), true);
332
333
CHECK(bit_map.get_true_bit_count() == 16);
334
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 131)) == false, "Bits that are on the edge of the shape should be set to false");
335
CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 131)) == false, "Bits that are on the edge of the shape should be set to false");
336
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 124)) == false, "Bits that are on the edge of the shape should be set to false");
337
CHECK_MESSAGE(bit_map.get_bitv(Point2i(130, 124)) == false, "Bits that are on the edge of the shape should be set to false");
338
bit_map.grow_mask(1, Rect2i(0, 0, 256, 256));
339
CHECK(bit_map.get_true_bit_count() == 48);
340
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 131)) == true, "Bits that were on the edge of the shape should now be set to true");
341
CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 130)) == true, "Bits that were on the edge of the shape should now be set to true");
342
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125, 124)) == true, "Bits that were on the edge of the shape should now be set to true");
343
CHECK_MESSAGE(bit_map.get_bitv(Point2i(130, 124)) == true, "Bits that were on the edge of the shape should now be set to true");
344
345
CHECK_MESSAGE(bit_map.get_bitv(Point2i(124, 124)) == false, "Bits that are on the edge of the shape should be set to false");
346
CHECK_MESSAGE(bit_map.get_bitv(Point2i(126, 124)) == false, "Bits that are on the edge of the shape should be set to false");
347
CHECK_MESSAGE(bit_map.get_bitv(Point2i(124, 131)) == false, "Bits that are on the edge of the shape should be set to false");
348
CHECK_MESSAGE(bit_map.get_bitv(Point2i(131, 131)) == false, "Bits that are on the edge of the shape should be set to false");
349
}
350
351
TEST_CASE("[BitMap] Blit") {
352
Point2i blit_pos{ 128, 128 };
353
Point2i bit_map_size{ 256, 256 };
354
Point2i blit_size{ 32, 32 };
355
356
BitMap bit_map{};
357
Ref<BitMap> blit_bit_map{};
358
359
// Testing null reference to blit bit map.
360
ERR_PRINT_OFF
361
bit_map.blit(blit_pos, blit_bit_map);
362
ERR_PRINT_ON
363
364
blit_bit_map.instantiate();
365
366
// Testing if uninitialized blit bit map and uninitialized bit map does not crash
367
bit_map.blit(blit_pos, blit_bit_map);
368
369
// Testing if uninitialized bit map does not crash
370
blit_bit_map->create(blit_size);
371
bit_map.blit(blit_pos, blit_bit_map);
372
373
// Testing if uninitialized bit map does not crash
374
blit_bit_map.unref();
375
blit_bit_map.instantiate();
376
CHECK_MESSAGE(blit_bit_map->get_size() == Point2i(0, 0), "Size should be cleared by unref and instance calls.");
377
bit_map.create(bit_map_size);
378
bit_map.blit(Point2i(128, 128), blit_bit_map);
379
380
// Testing if both initialized does not crash.
381
blit_bit_map->create(blit_size);
382
bit_map.blit(blit_pos, blit_bit_map);
383
384
bit_map.set_bit_rect(Rect2i{ 127, 127, 3, 3 }, true);
385
CHECK(bit_map.get_true_bit_count() == 9);
386
bit_map.blit(Point2i(112, 112), blit_bit_map);
387
CHECK_MESSAGE(bit_map.get_true_bit_count() == 9, "No bits should have been changed, as the blit bit map only contains falses");
388
389
bit_map.create(bit_map_size);
390
blit_bit_map->create(blit_size);
391
blit_bit_map->set_bit_rect(Rect2i(15, 15, 3, 3), true);
392
CHECK(blit_bit_map->get_true_bit_count() == 9);
393
394
CHECK(bit_map.get_true_bit_count() == 0);
395
bit_map.blit(Point2i(112, 112), blit_bit_map);
396
CHECK_MESSAGE(bit_map.get_true_bit_count() == 9, "All true bits should have been moved to the bit map");
397
for (int x = 127; x < 129; ++x) {
398
for (int y = 127; y < 129; ++y) {
399
CHECK_MESSAGE(bit_map.get_bitv(Point2i(x, y)) == true, "All true bits should have been moved to the bit map");
400
}
401
}
402
}
403
404
TEST_CASE("[BitMap] Convert to image") {
405
const Size2i dim{ 256, 256 };
406
BitMap bit_map{};
407
Ref<Image> img;
408
409
ERR_PRINT_OFF
410
img = bit_map.convert_to_image();
411
ERR_PRINT_ON
412
CHECK_MESSAGE(img.is_valid(), "We should receive a valid Image Object even if BitMap is not created yet");
413
CHECK_MESSAGE(img->get_format() == Image::FORMAT_L8, "We should receive a valid Image Object even if BitMap is not created yet");
414
CHECK_MESSAGE(img->get_size() == (Size2i(0, 0)), "Image should have no width or height, because BitMap has not yet been created");
415
416
bit_map.create(dim);
417
img = bit_map.convert_to_image();
418
CHECK_MESSAGE(img->get_size() == dim, "Image should have the same dimensions as the BitMap");
419
CHECK_MESSAGE(img->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0)), "BitMap is initialized to all 0's, so Image should be all black");
420
421
reset_bit_map(bit_map);
422
bit_map.set_bit_rect(Rect2i(0, 0, 128, 128), true);
423
img = bit_map.convert_to_image();
424
CHECK_MESSAGE(img->get_pixel(0, 0).is_equal_approx(Color(1, 1, 1)), "BitMap's top-left quadrant is all 1's, so Image should be white");
425
CHECK_MESSAGE(img->get_pixel(255, 255).is_equal_approx(Color(0, 0, 0)), "All other quadrants were 0's, so these should be black");
426
}
427
428
TEST_CASE("[BitMap] Clip to polygon") {
429
const Size2i dim{ 256, 256 };
430
BitMap bit_map{};
431
Vector<Vector<Vector2>> polygons;
432
433
ERR_PRINT_OFF
434
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128));
435
ERR_PRINT_ON
436
CHECK_MESSAGE(polygons.size() == 0, "We should have no polygons, because the BitMap was not initialized");
437
438
bit_map.create(dim);
439
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128));
440
CHECK_MESSAGE(polygons.size() == 0, "We should have no polygons, because the BitMap was all 0's");
441
442
reset_bit_map(bit_map);
443
bit_map.set_bit_rect(Rect2i(0, 0, 64, 64), true);
444
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128));
445
CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon");
446
CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points");
447
448
reset_bit_map(bit_map);
449
bit_map.set_bit_rect(Rect2i(0, 0, 32, 32), true);
450
bit_map.set_bit_rect(Rect2i(64, 64, 32, 32), true);
451
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128));
452
CHECK_MESSAGE(polygons.size() == 2, "We should have exactly 2 polygons");
453
CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points");
454
CHECK_MESSAGE(polygons[1].size() == 4, "The polygon should have exactly 4 points");
455
456
reset_bit_map(bit_map);
457
bit_map.set_bit_rect(Rect2i(124, 112, 8, 32), true);
458
bit_map.set_bit_rect(Rect2i(112, 124, 32, 8), true);
459
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 256, 256));
460
CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon");
461
CHECK_MESSAGE(polygons[0].size() == 12, "The polygon should have exactly 12 points");
462
463
reset_bit_map(bit_map);
464
bit_map.set_bit_rect(Rect2i(124, 112, 8, 32), true);
465
bit_map.set_bit_rect(Rect2i(112, 124, 32, 8), true);
466
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 128, 128));
467
CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon");
468
CHECK_MESSAGE(polygons[0].size() == 6, "The polygon should have exactly 6 points");
469
470
reset_bit_map(bit_map);
471
bit_map.set_bit_rect(Rect2i(0, 0, 64, 64), true);
472
bit_map.set_bit_rect(Rect2i(64, 64, 64, 64), true);
473
bit_map.set_bit_rect(Rect2i(192, 128, 64, 64), true);
474
bit_map.set_bit_rect(Rect2i(128, 192, 64, 64), true);
475
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 256, 256));
476
CHECK_MESSAGE(polygons.size() == 4, "We should have exactly 4 polygons");
477
CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points");
478
CHECK_MESSAGE(polygons[1].size() == 4, "The polygon should have exactly 4 points");
479
CHECK_MESSAGE(polygons[2].size() == 4, "The polygon should have exactly 4 points");
480
CHECK_MESSAGE(polygons[3].size() == 4, "The polygon should have exactly 4 points");
481
482
reset_bit_map(bit_map);
483
bit_map.set_bit(0, 0, true);
484
bit_map.set_bit(2, 0, true);
485
bit_map.set_bit_rect(Rect2i(1, 1, 1, 2), true);
486
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 3, 3));
487
CHECK_MESSAGE(polygons.size() == 3, "We should have exactly 3 polygons");
488
CHECK_MESSAGE(polygons[0].size() == 4, "The polygon should have exactly 4 points");
489
CHECK_MESSAGE(polygons[1].size() == 4, "The polygon should have exactly 4 points");
490
CHECK_MESSAGE(polygons[2].size() == 4, "The polygon should have exactly 4 points");
491
492
reset_bit_map(bit_map);
493
bit_map.set_bit_rect(Rect2i(0, 0, 2, 1), true);
494
bit_map.set_bit_rect(Rect2i(0, 2, 3, 1), true);
495
bit_map.set_bit(0, 1, true);
496
bit_map.set_bit(2, 1, true);
497
polygons = bit_map.clip_opaque_to_polygons(Rect2i(0, 0, 4, 4));
498
CHECK_MESSAGE(polygons.size() == 1, "We should have exactly 1 polygon");
499
CHECK_MESSAGE(polygons[0].size() == 6, "The polygon should have exactly 6 points");
500
}
501
502
} // namespace TestBitmap
503
504