summaryrefslogtreecommitdiff
path: root/src/mbgl/sprite
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-02-14 11:07:54 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-02-14 16:28:12 -0600
commit0351e9c3702b22ba6cbd74fb8b3c4874c93f61f8 (patch)
tree6ae31efaf7a7779d21236c3930a1d805bf3d81ad /src/mbgl/sprite
parentb18a4d6e7804a7f919cd038b50f8a77c748778b1 (diff)
downloadqtlocation-mapboxgl-0351e9c3702b22ba6cbd74fb8b3c4874c93f61f8.tar.gz
[core] Eliminate SpritePatternMode
Diffstat (limited to 'src/mbgl/sprite')
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp54
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp27
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;