diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2017-02-14 11:07:54 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-02-14 16:28:12 -0600 |
commit | 0351e9c3702b22ba6cbd74fb8b3c4874c93f61f8 (patch) | |
tree | 6ae31efaf7a7779d21236c3930a1d805bf3d81ad /src/mbgl/sprite | |
parent | b18a4d6e7804a7f919cd038b50f8a77c748778b1 (diff) | |
download | qtlocation-mapboxgl-0351e9c3702b22ba6cbd74fb8b3c4874c93f61f8.tar.gz |
[core] Eliminate SpritePatternMode
Diffstat (limited to 'src/mbgl/sprite')
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.cpp | 54 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.hpp | 27 |
2 files changed, 37 insertions, 44 deletions
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 81a8013e86..2bf8a3095a 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -153,6 +153,11 @@ void SpriteAtlas::removeSprite(const std::string& name) { void SpriteAtlas::_setSprite(const std::string& name, const std::shared_ptr<const SpriteImage>& sprite) { + if (!sprite->image.valid()) { + Log::Warning(Event::Sprite, "invalid sprite image '%s'", name.c_str()); + return; + } + auto it = entries.find(name); if (it == entries.end()) { entries.emplace(name, Entry { sprite, {}, {} }); @@ -170,11 +175,11 @@ void SpriteAtlas::_setSprite(const std::string& name, entry.spriteImage = sprite; if (entry.iconRect) { - copy(entry.spriteImage->image, *entry.iconRect, SpritePatternMode::Single); + copy(entry, &Entry::iconRect); } if (entry.patternRect) { - copy(entry.spriteImage->image, *entry.patternRect, SpritePatternMode::Repeating); + copy(entry, &Entry::patternRect); } } @@ -191,8 +196,16 @@ std::shared_ptr<const SpriteImage> SpriteAtlas::getSprite(const std::string& nam } } +optional<SpriteAtlasElement> SpriteAtlas::getIcon(const std::string& name) { + return getImage(name, &Entry::iconRect); +} + +optional<SpriteAtlasElement> SpriteAtlas::getPattern(const std::string& name) { + return getImage(name, &Entry::patternRect); +} + optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, - const SpritePatternMode mode) { + optional<Rect<uint16_t>> Entry::*entryRect) { std::lock_guard<std::mutex> lock(mutex); auto it = entries.find(name); @@ -205,18 +218,9 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, Entry& entry = it->second; - if (mode == SpritePatternMode::Single && entry.iconRect) { + if (entry.*entryRect) { return SpriteAtlasElement { - *entry.iconRect, - entry.spriteImage, - size, - pixelRatio - }; - } - - if (mode == SpritePatternMode::Repeating && entry.patternRect) { - return SpriteAtlasElement { - *entry.patternRect, + *(entry.*entryRect), entry.spriteImage, size, pixelRatio @@ -241,13 +245,8 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, return {}; } - copy(entry.spriteImage->image, rect, mode); - - if (mode == SpritePatternMode::Single) { - entry.iconRect = rect; - } else { - entry.patternRect = rect; - } + entry.*entryRect = rect; + copy(entry, entryRect); return SpriteAtlasElement { rect, @@ -257,26 +256,25 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name, }; } -void SpriteAtlas::copy(const PremultipliedImage& src, Rect<uint16_t> pos, const SpritePatternMode mode) { +void SpriteAtlas::copy(const Entry& entry, optional<Rect<uint16_t>> Entry::*entryRect) { if (!image.valid()) { image = PremultipliedImage({ static_cast<uint32_t>(std::ceil(size.width * pixelRatio)), static_cast<uint32_t>(std::ceil(size.height * pixelRatio)) }); image.fill(0); } - if (!src.valid()) { - return; - } + const PremultipliedImage& src = entry.spriteImage->image; + const Rect<uint16_t>& rect = *(entry.*entryRect); const uint32_t padding = 1; - const uint32_t x = (pos.x + padding) * pixelRatio; - const uint32_t y = (pos.y + padding) * pixelRatio; + const uint32_t x = (rect.x + padding) * pixelRatio; + const uint32_t y = (rect.y + padding) * pixelRatio; const uint32_t w = src.size.width; const uint32_t h = src.size.height; PremultipliedImage::copy(src, image, { 0, 0 }, { x, y }, { w, h }); - if (mode == SpritePatternMode::Repeating) { + if (entryRect == &Entry::patternRect) { // Add 1 pixel wrapped padding on each side of the image. PremultipliedImage::copy(src, image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T PremultipliedImage::copy(src, image, { 0, 0 }, { x, y + h }, { w, 1 }); // B diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index 10ef2ddaa9..c7b266376b 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -36,11 +36,6 @@ public: std::array<float, 2> br; }; -enum class SpritePatternMode : bool { - Single = false, - Repeating = true, -}; - class SpriteAtlas : public util::noncopyable { public: using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>; @@ -58,21 +53,13 @@ public: void setObserver(SpriteAtlasObserver*); - // Adds/replaces a Sprite image. void setSprite(const std::string&, std::shared_ptr<const SpriteImage>); - - // Adds/replaces mutliple Sprite images. - void setSprites(const Sprites& sprites); - - // Removes a Sprite. void removeSprite(const std::string&); - // Obtains a Sprite image. std::shared_ptr<const SpriteImage> getSprite(const std::string&); - // If the sprite is loaded, copies the requsted image from it into the atlas and returns - // the resulting icon measurements. If not, returns an empty optional. - optional<SpriteAtlasElement> getImage(const std::string& name, SpritePatternMode mode); + optional<SpriteAtlasElement> getIcon(const std::string& name); + optional<SpriteAtlasElement> getPattern(const std::string& name); // Binds the atlas texture to the GPU, and uploads data if it is out of date. void bind(bool linear, gl::Context&, gl::TextureUnit unit); @@ -85,6 +72,7 @@ public: float getPixelRatio() const { return pixelRatio; } // Only for use in tests. + void setSprites(const Sprites& sprites); const PremultipliedImage& getAtlasImage() const { return image; } @@ -93,7 +81,6 @@ private: void _setSprite(const std::string&, const std::shared_ptr<const SpriteImage>& = nullptr); void emitSpriteLoadedIfComplete(); - void copy(const PremultipliedImage&, Rect<uint16_t>, SpritePatternMode); const Size size; const float pixelRatio; @@ -107,10 +94,18 @@ private: struct Entry { std::shared_ptr<const SpriteImage> spriteImage; + + // One sprite image might be used as both an icon image and a pattern image. If so, + // it must have two distinct entries in the texture. The one for the icon image has + // a single pixel transparent border, and the one for the pattern image has a single + // pixel border wrapped from the opposite side. optional<Rect<uint16_t>> iconRect; optional<Rect<uint16_t>> patternRect; }; + optional<SpriteAtlasElement> getImage(const std::string& name, optional<Rect<uint16_t>> Entry::*rect); + void copy(const Entry&, optional<Rect<uint16_t>> Entry::*rect); + std::mutex mutex; std::unordered_map<std::string, Entry> entries; BinPack<uint16_t> bin; |