TEST(Annotations, SpriteAtlasSize) { 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.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())); }
void run() { // Squelch logging. Log::setObserver(std::make_unique<Log::NullObserver>()); spriteStore.setObserver(&observer); spriteStore.load("test/fixtures/resources/sprite", fileSource); loop.run(); }
void run(const std::string& url) { // Squelch logging. Log::setObserver(std::make_unique<Log::NullObserver>()); util::ThreadContext::Set(&context); util::ThreadContext::setFileSource(&fileSource); spriteStore.setObserver(&observer); spriteStore.setURL(url); loop.run(); }
TEST(Annotations, 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())); }
bool SymbolBucket::needsDependencies(GlyphStore& glyphStore, SpriteStore& spriteStore) { if (!layout.text.field.value.empty() && !layout.text.font.value.empty() && !glyphStore.hasGlyphRanges(layout.text.font, ranges)) { return true; } if (!layout.icon.image.value.empty() && !spriteStore.isLoaded()) { return true; } return false; }
TEST(Annotations, SpriteAtlas) { FixtureLog log; 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_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())); }