summaryrefslogtreecommitdiff
path: root/test/sprite/sprite_atlas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/sprite/sprite_atlas.cpp')
-rw-r--r--test/sprite/sprite_atlas.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/test/sprite/sprite_atlas.cpp b/test/sprite/sprite_atlas.cpp
new file mode 100644
index 0000000000..554ef16da9
--- /dev/null
+++ b/test/sprite/sprite_atlas.cpp
@@ -0,0 +1,173 @@
+#include "../fixtures/util.hpp"
+#include "../fixtures/fixture_log_observer.hpp"
+
+#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/sprite/sprite_store.hpp>
+#include <mbgl/sprite/sprite_parser.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/util/image.hpp>
+
+using namespace mbgl;
+
+TEST(Sprite, SpriteAtlas) {
+ FixtureLog log;
+
+ auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
+ util::read_file("test/fixtures/annotations/emerald.json"));
+
+ SpriteStore store;
+ store.setSprites(spriteParseResult.get<Sprites>());
+
+ SpriteAtlas atlas(63, 112, 1, store);
+
+ EXPECT_EQ(1.0f, atlas.getPixelRatio());
+ EXPECT_EQ(63, atlas.getWidth());
+ EXPECT_EQ(112, atlas.getHeight());
+ EXPECT_EQ(63, atlas.getTextureWidth());
+ EXPECT_EQ(112, atlas.getTextureHeight());
+
+ // Image hasn't been created yet.
+ EXPECT_TRUE(atlas.getData());
+
+ auto metro = atlas.getImage("metro", false);
+ EXPECT_EQ(0, metro.pos.x);
+ EXPECT_EQ(0, metro.pos.y);
+ EXPECT_EQ(20, metro.pos.w);
+ EXPECT_EQ(20, metro.pos.h);
+ EXPECT_EQ(18, metro.pos.originalW);
+ EXPECT_EQ(18, metro.pos.originalH);
+ EXPECT_EQ(18, metro.texture->width);
+ EXPECT_EQ(18, metro.texture->height);
+ EXPECT_EQ(18, metro.texture->pixelWidth);
+ EXPECT_EQ(18, metro.texture->pixelHeight);
+ EXPECT_EQ(1.0f, metro.texture->pixelRatio);
+
+ auto pos = atlas.getPosition("metro", false);
+ EXPECT_DOUBLE_EQ(20, pos.size[0]);
+ EXPECT_DOUBLE_EQ(20, pos.size[1]);
+ EXPECT_DOUBLE_EQ(1.0f / 63, pos.tl[0]);
+ EXPECT_DOUBLE_EQ(1.0f / 112, pos.tl[1]);
+ EXPECT_DOUBLE_EQ(21.0f / 63, pos.br[0]);
+ EXPECT_DOUBLE_EQ(21.0f / 112, pos.br[1]);
+
+
+ auto missing = atlas.getImage("doesnotexist", false);
+ EXPECT_FALSE(missing.pos.hasArea());
+ EXPECT_EQ(0, missing.pos.x);
+ EXPECT_EQ(0, missing.pos.y);
+ EXPECT_EQ(0, missing.pos.w);
+ EXPECT_EQ(0, missing.pos.h);
+ EXPECT_EQ(0, missing.pos.originalW);
+ EXPECT_EQ(0, missing.pos.originalH);
+ EXPECT_FALSE(missing.texture);
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Info,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't find sprite named 'doesnotexist'",
+ }));
+
+ // Different wrapping mode produces different image.
+ auto metro2 = atlas.getImage("metro", true);
+ EXPECT_EQ(20, metro2.pos.x);
+ EXPECT_EQ(0, metro2.pos.y);
+ EXPECT_EQ(20, metro2.pos.w);
+ EXPECT_EQ(20, metro2.pos.h);
+ EXPECT_EQ(18, metro2.pos.originalW);
+ EXPECT_EQ(18, metro2.pos.originalH);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x9875FC0595489A9Fu, hash) << std::hex << hash;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas1.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}
+
+TEST(Sprite, SpriteAtlasSize) {
+ auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
+ util::read_file("test/fixtures/annotations/emerald.json"));
+
+ SpriteStore store;
+ store.setSprites(spriteParseResult.get<Sprites>());
+
+ SpriteAtlas atlas(63, 112, 1.4, store);
+
+ EXPECT_DOUBLE_EQ(1.4f, atlas.getPixelRatio());
+ EXPECT_EQ(63, atlas.getWidth());
+ EXPECT_EQ(112, atlas.getHeight());
+ EXPECT_EQ(89, atlas.getTextureWidth());
+ EXPECT_EQ(157, atlas.getTextureHeight());
+
+ auto metro = atlas.getImage("metro", false);
+ EXPECT_EQ(0, metro.pos.x);
+ EXPECT_EQ(0, metro.pos.y);
+ EXPECT_EQ(20, metro.pos.w);
+ EXPECT_EQ(20, metro.pos.h);
+ EXPECT_EQ(18, metro.pos.originalW);
+ EXPECT_EQ(18, metro.pos.originalH);
+ EXPECT_EQ(18, metro.texture->width);
+ EXPECT_EQ(18, metro.texture->height);
+ EXPECT_EQ(18, metro.texture->pixelWidth);
+ EXPECT_EQ(18, metro.texture->pixelHeight);
+ EXPECT_EQ(1.0f, metro.texture->pixelRatio);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x2CDDA7DBB04D116Du, hash) << std::hex << hash;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas2.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}
+
+TEST(Sprite, SpriteAtlasUpdates) {
+ SpriteStore store;
+
+ SpriteAtlas atlas(32, 32, 1, store);
+
+ EXPECT_EQ(1.0f, atlas.getPixelRatio());
+ EXPECT_EQ(32, atlas.getWidth());
+ EXPECT_EQ(32, atlas.getHeight());
+ EXPECT_EQ(32, atlas.getTextureWidth());
+ EXPECT_EQ(32, atlas.getTextureHeight());
+
+ store.setSprite("one", std::make_shared<SpriteImage>(16, 12, 1, std::string(16 * 12 * 4, '\x00')));
+ auto one = atlas.getImage("one", false);
+ EXPECT_EQ(0, one.pos.x);
+ EXPECT_EQ(0, one.pos.y);
+ EXPECT_EQ(20, one.pos.w);
+ EXPECT_EQ(16, one.pos.h);
+ EXPECT_EQ(16, one.pos.originalW);
+ EXPECT_EQ(12, one.pos.originalH);
+ EXPECT_EQ(16, one.texture->width);
+ EXPECT_EQ(12, one.texture->height);
+ EXPECT_EQ(16, one.texture->pixelWidth);
+ EXPECT_EQ(12, one.texture->pixelHeight);
+ EXPECT_EQ(1.0f, one.texture->pixelRatio);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x0000000000000000u, hash) << std::hex << hash;
+
+ // Update sprite
+ auto newSprite = std::make_shared<SpriteImage>(16, 12, 1, std::string(16 * 12 * 4, '\xFF'));
+ store.setSprite("one", newSprite);
+ ASSERT_EQ(newSprite, store.getSprite("one"));
+
+ // Atlas texture hasn't changed yet.
+ const auto hash2 = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x0000000000000000u, hash2) << std::hex << hash2;
+
+ atlas.updateDirty();
+
+ // Now the atlas texture has changed.
+ const auto hash3 = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x4E6D4900CD2D9149u, hash3) << std::hex << hash3;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas3.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}