diff options
author | Ansis Brammanis <brammanis@gmail.com> | 2015-02-03 13:17:26 -0800 |
---|---|---|
committer | Ansis Brammanis <brammanis@gmail.com> | 2015-02-03 13:17:26 -0800 |
commit | 23dd403a25938f3257b63e3b6a8721d62afaa4ce (patch) | |
tree | fb656c1b51a81a152a64a8cfb5b26d7c8041b8e8 | |
parent | 33f611cdf8d22aacdb252dee7f262a644af10882 (diff) | |
download | qtlocation-mapboxgl-23dd403a25938f3257b63e3b6a8721d62afaa4ce.tar.gz |
add wrapped padding to sprite for repeating images
fixes #798
js: e732e784e41bef35bd40de27fdbfa3e8f9588038
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.cpp | 37 | ||||
-rw-r--r-- | src/mbgl/geometry/sprite_atlas.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 2 |
3 files changed, 28 insertions, 15 deletions
diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp index 35365c7e4d..7b6184ae73 100644 --- a/src/mbgl/geometry/sprite_atlas.cpp +++ b/src/mbgl/geometry/sprite_atlas.cpp @@ -67,12 +67,24 @@ bool SpriteAtlas::resize(const float newRatio) { void copy_bitmap(const uint32_t *src, const int src_stride, const int src_x, const int src_y, uint32_t *dst, const int dst_stride, const int dst_x, const int dst_y, - const int width, const int height) { - src += src_y * src_stride + src_x; + const int width, const int height, const bool wrap) { dst += dst_y * dst_stride + dst_x; - for (int y = 0; y < height; y++, src += src_stride, dst += dst_stride) { - for (int x = 0; x < width; x++) { - dst[x] = src[x]; + if (wrap) { + dst -= dst_stride; + int srcI; + // add 1 pixel wrapped padding on each side of the image + for (int y = 0; y < height; y++, srcI = (((y + height) % height) + src_y) * src_stride + src_x, dst += dst_stride) { + for (int x = -1; x <= width; x++) { + dst[x] = src[srcI + ((x + width) % width)]; + } + } + + } else { + src += src_y * src_stride + src_x; + for (int y = 0; y < height; y++, src += src_stride, dst += dst_stride) { + for (int x = 0; x < width; x++) { + dst[x] = src[x]; + } } } } @@ -97,7 +109,7 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width return rect; } -Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name) { +Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name, const bool wrap) { std::lock_guard<std::recursive_mutex> lock(mtx); auto rect_it = images.find(name); @@ -120,7 +132,7 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name) { images.emplace(name, rect); - copy(rect, pos); + copy(rect, pos, wrap); return rect; } @@ -128,7 +140,7 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::getImage(const std::string& name) { SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repeating) { std::lock_guard<std::recursive_mutex> lock(mtx); - Rect<dimension> rect = getImage(name); + Rect<dimension> rect = getImage(name, repeating); if (repeating) { // When the image is repeating, get the correct position of the image, rather than the // one rounded up to 4 pixels. @@ -157,7 +169,7 @@ void SpriteAtlas::allocate() { } } -void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src) { +void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src, const bool wrap) { if (!sprite->raster) return; const uint32_t *src_img = reinterpret_cast<const uint32_t *>(sprite->raster->getData()); if (!src_img) return; @@ -174,7 +186,8 @@ void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src) { /* dest x */ dst.x * pixelRatio, /* dest y */ dst.y * pixelRatio, /* icon dimension */ src.width, - /* icon dimension */ src.height + /* icon dimension */ src.height, + /* wrap padding */ wrap ); dirty = true; @@ -188,7 +201,7 @@ void SpriteAtlas::setSprite(util::ptr<Sprite> sprite_) { if (!sprite->isLoaded()) return; util::erase_if(uninitialized, [this](const std::string &name) { - Rect<dimension> dst = getImage(name); + Rect<dimension> dst = getImage(name, false); const SpritePosition& src = sprite->getSpritePosition(name); if (!src) { if (debug::spriteWarnings) { @@ -198,7 +211,7 @@ void SpriteAtlas::setSprite(util::ptr<Sprite> sprite_) { } if (src.width == dst.w * pixelRatio && src.height == dst.h * pixelRatio && src.pixelRatio == pixelRatio) { - copy(dst, src); + copy(dst, src, false); return true; } else { if (debug::spriteWarnings) { diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp index ebfd69edf5..079c15cefd 100644 --- a/src/mbgl/geometry/sprite_atlas.hpp +++ b/src/mbgl/geometry/sprite_atlas.hpp @@ -46,7 +46,7 @@ public: // This getter attempts to read the image from the sprite if it is already loaded. // In that case, it copies it into the sprite atlas and returns the dimensions. // Otherwise, it returns a 0/0/0/0 rect. - Rect<dimension> getImage(const std::string& name); + Rect<dimension> getImage(const std::string& name, const bool wrap); SpriteAtlasPosition getPosition(const std::string& name, bool repeating = false); @@ -66,7 +66,7 @@ public: private: void allocate(); Rect<SpriteAtlas::dimension> allocateImage(size_t width, size_t height); - void copy(const Rect<dimension>& dst, const SpritePosition& src); + void copy(const Rect<dimension>& dst, const SpritePosition& src, const bool wrap); std::recursive_mutex mtx; float pixelRatio = 1.0f; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index c6a7c8c4e1..a5043a3739 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -195,7 +195,7 @@ void SymbolBucket::addFeatures(const VectorTileLayer &layer, const FilterExpress // if feature has icon, get sprite atlas position if (feature.sprite.length()) { sprite.waitUntilLoaded(); - image = spriteAtlas.getImage(feature.sprite); + image = spriteAtlas.getImage(feature.sprite, false); if (sprite.getSpritePosition(feature.sprite).sdf) { sdfIcons = true; |