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.");
dim=Size2i(0,256);
bit_map.create(dim);
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,512),"We should still have the same dimensions as before, because the new dimension is invalid.");
dim=Size2i(512,0);
bit_map.create(dim);
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,512),"We should still have the same dimensions as before, because the new dimension is invalid.");
dim=Size2i(46341,46341);
bit_map.create(dim);
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).");
}
TEST_CASE("[BitMap] Create bit map from image alpha"){
constSize2idim{256,256};
BitMapbit_map{};
bit_map.create(dim);
constRef<Image>null_img=nullptr;
bit_map.create_from_image_alpha(null_img);
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,256),"Bitmap should have its old values because bitmap creation from a nullptr should fail.");
Ref<Image>empty_img;
empty_img.instantiate();
bit_map.create_from_image_alpha(empty_img);
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,256),"Bitmap should have its old values because bitmap creation from an empty image should fail.");
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.");
bit_map.create_from_image_alpha(img,0.08f);
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.");
bit_map.create_from_image_alpha(img,1);
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.");
}
TEST_CASE("[BitMap] Set bit"){
Size2idim{256,256};
BitMapbit_map{};
// Setting a point before a bit map is created should not crash, because there are checks to see if we are out of bounds.
bit_map.set_bitv(Point2i(128,128),true);
bit_map.create(dim);
CHECK_MESSAGE(bit_map.get_true_bit_count()==0,"All values should be initialized to false.");
bit_map.set_bitv(Point2i(128,128),true);
CHECK_MESSAGE(bit_map.get_true_bit_count()==1,"One bit should be set to true.");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,128))==true,"The bit at (128,128) should be set to true");
bit_map.set_bitv(Point2i(128,128),false);
CHECK_MESSAGE(bit_map.get_true_bit_count()==0,"The bit should now be set to false again");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,128))==false,"The bit at (128,128) should now be set to false again");
bit_map.create(dim);
bit_map.set_bitv(Point2i(512,512),true);
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.");
}
TEST_CASE("[BitMap] Get bit"){
constSize2idim{256,256};
BitMapbit_map{};
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");
bit_map.create(dim);
CHECK(bit_map.get_bitv(Point2i(128,128))==false);
bit_map.set_bit_rect(Rect2i(-1,-1,257,257),true);
// Checking that range is [0, 256).
CHECK(bit_map.get_bitv(Point2i(-1,0))==false);
CHECK(bit_map.get_bitv(Point2i(0,0))==true);
CHECK(bit_map.get_bitv(Point2i(128,128))==true);
CHECK(bit_map.get_bitv(Point2i(255,255))==true);
CHECK(bit_map.get_bitv(Point2i(256,256))==false);
CHECK(bit_map.get_bitv(Point2i(257,257))==false);
}
TEST_CASE("[BitMap] Set bit rect"){
constSize2idim{256,256};
BitMapbit_map{};
// Although we have not setup the BitMap yet, this should not crash because we get an empty intersection inside of the method.
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,256),"Invalid size should not be accepted by create");
bit_map.create(Size2i(256,128));
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,128),"Bitmap should have updated size");
}
TEST_CASE("[BitMap] Resize"){
constSize2idim{128,128};
BitMapbit_map{};
bit_map.resize(dim);
CHECK(bit_map.get_size()==dim);
bit_map.create(dim);
bit_map.set_bit_rect(Rect2i(0,0,10,10),true);
bit_map.set_bit_rect(Rect2i(118,118,10,10),true);
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");
bit_map.resize(Size2i(64,64));
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");
bit_map.create(dim);
bit_map.resize(Size2i(-1,128));
CHECK_MESSAGE(bit_map.get_size()==Size2i(128,128),"When an invalid size is given the bit map will keep its size");
bit_map.create(dim);
bit_map.set_bit_rect(Rect2i(0,0,10,10),true);
bit_map.set_bit_rect(Rect2i(118,118,10,10),true);
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");
bit_map.resize(Size2i(256,256));
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");
CHECK_MESSAGE(bit_map.get_size()==Size2i(256,256),"The bitmap should now be 256x256");
}
TEST_CASE("[BitMap] Grow and shrink mask"){
constSize2idim{256,256};
BitMapbit_map{};
bit_map.grow_mask(100,Rect2i(0,0,128,128));// Check if method does not crash when working with an uninitialised bit map.
CHECK_MESSAGE(bit_map.get_size()==Size2i(0,0),"Size should still be equal to 0x0");
bit_map.create(dim);
bit_map.set_bit_rect(Rect2i(96,96,64,64),true);
CHECK_MESSAGE(bit_map.get_true_bit_count()==4096,"Creating a square of 64x64 should be 4096 bits");
bit_map.grow_mask(0,Rect2i(0,0,256,256));
CHECK_MESSAGE(bit_map.get_true_bit_count()==4096,"Growing with size of 0 should not change any bits");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(96,96,64,64),true);
CHECK_MESSAGE(bit_map.get_bitv(Point2i(95,128))==false,"Bits just outside of the square should not be set");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(160,128))==false,"Bits just outside of the square should not be set");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,95))==false,"Bits just outside of the square should not be set");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,160))==false,"Bits just outside of the square should not be set");
bit_map.grow_mask(1,Rect2i(0,0,256,256));
CHECK_MESSAGE(bit_map.get_true_bit_count()==4352,"We should have 4*64 (perimeter of square) more bits set to true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(95,128))==true,"Bits that were just outside of the square should now be set to true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(160,128))==true,"Bits that were just outside of the square should now be set to true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,95))==true,"Bits that were just outside of the square should now be set to true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(128,160))==true,"Bits that were just outside of the square should now be set to true");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(127,127,1,1),true);
CHECK(bit_map.get_true_bit_count()==1);
bit_map.grow_mask(32,Rect2i(0,0,256,256));
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");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(127,127,1,1),true);
for(inti=0;i<32;i++){
bit_map.grow_mask(1,Rect2i(0,0,256,256));
}
CHECK_MESSAGE(bit_map.get_true_bit_count()==2113,"Creates a diamond around the initial bit with diagonals that are 65 bits long.");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(123,123,10,10),true);
CHECK(bit_map.get_true_bit_count()==100);
bit_map.grow_mask(-11,Rect2i(0,0,256,256));
CHECK_MESSAGE(bit_map.get_true_bit_count()==0,"Shrinking by more than the width of the square should totally remove it.");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(96,96,64,64),true);
CHECK_MESSAGE(bit_map.get_bitv(Point2i(96,129))==true,"Bits on the edge of the square should be true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(159,129))==true,"Bits on the edge of the square should be true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129,96))==true,"Bits on the edge of the square should be true");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(129,159))==true,"Bits on the edge of the square should be true");
bit_map.grow_mask(-1,Rect2i(0,0,256,256));
CHECK_MESSAGE(bit_map.get_true_bit_count()==3844,"Shrinking by 1 should set 4*63=252 bits to false");
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");
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");
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");
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");
reset_bit_map(bit_map);
bit_map.set_bit_rect(Rect2i(125,125,1,6),true);
bit_map.set_bit_rect(Rect2i(130,125,1,6),true);
bit_map.set_bit_rect(Rect2i(125,130,6,1),true);
CHECK(bit_map.get_true_bit_count()==16);
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125,131))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(131,131))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(125,124))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(130,124))==false,"Bits that are on the edge of the shape should be set to false");
bit_map.grow_mask(1,Rect2i(0,0,256,256));
CHECK(bit_map.get_true_bit_count()==48);
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");
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");
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");
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");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(124,124))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(126,124))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(124,131))==false,"Bits that are on the edge of the shape should be set to false");
CHECK_MESSAGE(bit_map.get_bitv(Point2i(131,131))==false,"Bits that are on the edge of the shape should be set to false");
}
TEST_CASE("[BitMap] Blit"){
Point2iblit_pos{128,128};
Point2ibit_map_size{256,256};
Point2iblit_size{32,32};
BitMapbit_map{};
Ref<BitMap>blit_bit_map{};
// Testing null reference to blit bit map.
bit_map.blit(blit_pos,blit_bit_map);
blit_bit_map.instantiate();
// Testing if uninitialised blit bit map and uninitialised bit map does not crash
bit_map.blit(blit_pos,blit_bit_map);
// Testing if uninitialised bit map does not crash
blit_bit_map->create(blit_size);
bit_map.blit(blit_pos,blit_bit_map);
// Testing if uninitialised bit map does not crash
blit_bit_map.unref();
blit_bit_map.instantiate();
CHECK_MESSAGE(blit_bit_map->get_size()==Point2i(0,0),"Size should be cleared by unref and instance calls.");
bit_map.create(bit_map_size);
bit_map.blit(Point2i(128,128),blit_bit_map);
// Testing if both initialised does not crash.
blit_bit_map->create(blit_size);
bit_map.blit(blit_pos,blit_bit_map);
bit_map.set_bit_rect(Rect2i{127,127,3,3},true);
CHECK(bit_map.get_true_bit_count()==9);
bit_map.blit(Point2i(112,112),blit_bit_map);
CHECK_MESSAGE(bit_map.get_true_bit_count()==9,"No bits should have been changed, as the blit bit map only contains falses");