diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp index e9653f6fa..88e532f5f 100644 --- a/src/mbgl/geometry/sprite_atlas.hpp +++ b/src/mbgl/geometry/sprite_atlas.hpp @@ -66,6 +66,7 @@ public: inline float getTextureWidth() const { return width * pixelRatio; } inline float getTextureHeight() const { return height * pixelRatio; } inline float getPixelRatio() const { return pixelRatio; } + inline const uint32_t* getData() const { return data.get(); } const dimension width = 0; const dimension height = 0; diff --git a/test/annotations/sprite_atlas.cpp b/test/annotations/sprite_atlas.cpp new file mode 100644 index 000000000..92091a16c --- /dev/null +++ b/test/annotations/sprite_atlas.cpp @@ -0,0 +1,84 @@ +#include "../fixtures/util.hpp" + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#include +#pragma GCC diagnostic pop + +namespace { + +// from https://gist.github.com/ArtemGr/997887 +uint64_t crc64(const char* data, size_t size) { + boost::crc_optimal<64, 0x04C11DB7, 0, 0, false, false> crc; + crc.process_bytes(data, size); + return crc.checksum(); +} + +} // anonymous namespace + +using namespace mbgl; + +using namespace mbgl; + +TEST(Annotations, SpriteAtlas) { + SpriteStore store; + store.setSprites(parseSprite(util::read_file("test/fixtures/annotations/emerald.png"), + util::read_file("test/fixtures/annotations/emerald.json"))); + + 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_FALSE(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]); + + // 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); + + EXPECT_TRUE(atlas.getData()); + + const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4; + const auto hash = crc64(reinterpret_cast(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())); +} diff --git a/test/test.gypi b/test/test.gypi index 93f1cc81e..f5930867b 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -37,6 +37,7 @@ 'miscellaneous/assert.cpp', + 'annotations/sprite_atlas.cpp', 'annotations/sprite_image.cpp', 'annotations/sprite_store.cpp', 'annotations/sprite_parser.cpp',