summaryrefslogtreecommitdiff
path: root/src/mbgl/sprite
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/sprite')
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp340
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp140
-rw-r--r--src/mbgl/sprite/sprite_atlas_observer.hpp15
-rw-r--r--src/mbgl/sprite/sprite_loader.cpp104
-rw-r--r--src/mbgl/sprite/sprite_loader.hpp44
-rw-r--r--src/mbgl/sprite/sprite_loader_observer.hpp21
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.cpp (renamed from src/mbgl/sprite/sprite_atlas_worker.cpp)12
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.hpp (renamed from src/mbgl/sprite/sprite_atlas_worker.hpp)8
-rw-r--r--src/mbgl/sprite/sprite_parser.cpp25
-rw-r--r--src/mbgl/sprite/sprite_parser.hpp24
10 files changed, 202 insertions, 531 deletions
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
deleted file mode 100644
index fed8451aed..0000000000
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/sprite/sprite_atlas_worker.hpp>
-#include <mbgl/sprite/sprite_atlas_observer.hpp>
-#include <mbgl/sprite/sprite_parser.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/util/logging.hpp>
-#include <mbgl/util/platform.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/std.hpp>
-#include <mbgl/util/constants.hpp>
-#include <mbgl/util/exception.hpp>
-#include <mbgl/storage/file_source.hpp>
-#include <mbgl/storage/resource.hpp>
-#include <mbgl/storage/response.hpp>
-#include <mbgl/util/run_loop.hpp>
-#include <mbgl/actor/actor.hpp>
-
-#include <cassert>
-#include <cmath>
-#include <algorithm>
-
-namespace mbgl {
-
-static SpriteAtlasObserver nullObserver;
-
-struct SpriteAtlas::Loader {
- Loader(Scheduler& scheduler, SpriteAtlas& spriteAtlas)
- : mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())),
- worker(scheduler, ActorRef<SpriteAtlas>(spriteAtlas, mailbox)) {
- }
-
- std::shared_ptr<const std::string> image;
- std::shared_ptr<const std::string> json;
- std::unique_ptr<AsyncRequest> jsonRequest;
- std::unique_ptr<AsyncRequest> spriteRequest;
- std::shared_ptr<Mailbox> mailbox;
- Actor<SpriteAtlasWorker> worker;
-};
-
-SpriteAtlasElement::SpriteAtlasElement(Rect<uint16_t> rect_,
- const style::Image& image,
- Size size_, float pixelRatio)
- : pos(std::move(rect_)),
- sdf(image.sdf),
- relativePixelRatio(image.pixelRatio / pixelRatio),
- width(image.getWidth()),
- height(image.getHeight()) {
-
- const float padding = 1;
-
- const float w = image.getWidth() * relativePixelRatio;
- const float h = image.getHeight() * relativePixelRatio;
-
- size = {{ float(image.getWidth()), image.getHeight() }};
- tl = {{ float(pos.x + padding) / size_.width, float(pos.y + padding) / size_.height }};
- br = {{ float(pos.x + padding + w) / size_.width, float(pos.y + padding + h) / size_.height }};
-}
-
-SpriteAtlas::SpriteAtlas(Size size_, float pixelRatio_)
- : size(std::move(size_)),
- pixelRatio(pixelRatio_),
- observer(&nullObserver),
- bin(size.width, size.height),
- dirty(true) {
-}
-
-SpriteAtlas::~SpriteAtlas() = default;
-
-void SpriteAtlas::load(const std::string& url, Scheduler& scheduler, FileSource& fileSource) {
- if (url.empty()) {
- // Treat a non-existent sprite as a successfully loaded empty sprite.
- markAsLoaded();
- return;
- }
-
- loader = std::make_unique<Loader>(scheduler, *this);
-
- loader->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
- if (res.error) {
- observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- loader->json = std::make_shared<const std::string>();
- emitSpriteLoadedIfComplete();
- } else {
- // Only trigger a sprite loaded event we got new data.
- loader->json = res.data;
- emitSpriteLoadedIfComplete();
- }
- });
-
- loader->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
- if (res.error) {
- observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- loader->image = std::make_shared<const std::string>();
- emitSpriteLoadedIfComplete();
- } else {
- loader->image = res.data;
- emitSpriteLoadedIfComplete();
- }
- });
-}
-
-void SpriteAtlas::emitSpriteLoadedIfComplete() {
- assert(loader);
-
- if (!loader->image || !loader->json) {
- return;
- }
-
- loader->worker.invoke(&SpriteAtlasWorker::parse, loader->image, loader->json);
- // TODO: delete the loader?
-}
-
-void SpriteAtlas::onParsed(Images&& result) {
- markAsLoaded();
- for (auto& pair : result) {
- addImage(pair.first, std::move(pair.second));
- }
- observer->onSpriteLoaded();
- for (auto requestor : requestors) {
- requestor->onIconsAvailable(buildIconMap());
- }
- requestors.clear();
-}
-
-void SpriteAtlas::onError(std::exception_ptr err) {
- observer->onSpriteError(err);
-}
-
-void SpriteAtlas::setObserver(SpriteAtlasObserver* observer_) {
- observer = observer_;
-}
-
-void SpriteAtlas::dumpDebugLogs() const {
- Log::Info(Event::General, "SpriteAtlas::loaded: %d", loaded);
-}
-
-void SpriteAtlas::addImage(const std::string& id, std::unique_ptr<style::Image> image_) {
- icons.clear();
-
- auto it = entries.find(id);
- if (it == entries.end()) {
- entries.emplace(id, Entry { std::move(image_), {}, {} });
- return;
- }
-
- Entry& entry = it->second;
-
- // There is already a sprite with that name in our store.
- if (entry.image->image.size != image_->image.size) {
- Log::Warning(Event::Sprite, "Can't change sprite dimensions for '%s'", id.c_str());
- return;
- }
-
- entry.image = std::move(image_);
-
- if (entry.iconRect) {
- copy(entry, &Entry::iconRect);
- }
-
- if (entry.patternRect) {
- copy(entry, &Entry::patternRect);
- }
-}
-
-void SpriteAtlas::removeImage(const std::string& id) {
- icons.clear();
-
- auto it = entries.find(id);
- if (it == entries.end()) {
- return;
- }
-
- Entry& entry = it->second;
-
- if (entry.iconRect) {
- bin.release(*entry.iconRect);
- }
-
- if (entry.patternRect) {
- bin.release(*entry.patternRect);
- }
-
- entries.erase(it);
-}
-
-const style::Image* SpriteAtlas::getImage(const std::string& id) const {
- const auto it = entries.find(id);
- if (it != entries.end()) {
- return it->second.image.get();
- }
- if (!entries.empty()) {
- Log::Info(Event::Sprite, "Can't find sprite named '%s'", id.c_str());
- }
- return nullptr;
-}
-
-void SpriteAtlas::getIcons(IconRequestor& requestor) {
- if (isLoaded()) {
- requestor.onIconsAvailable(buildIconMap());
- } else {
- requestors.insert(&requestor);
- }
-}
-
-void SpriteAtlas::removeRequestor(IconRequestor& requestor) {
- requestors.erase(&requestor);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getIcon(const std::string& id) {
- return getImage(id, &Entry::iconRect);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getPattern(const std::string& id) {
- return getImage(id, &Entry::patternRect);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& id,
- optional<Rect<uint16_t>> Entry::*entryRect) {
-
- auto it = entries.find(id);
- if (it == entries.end()) {
- if (!entries.empty()) {
- Log::Info(Event::Sprite, "Can't find sprite named '%s'", id.c_str());
- }
- return {};
- }
-
- Entry& entry = it->second;
-
- if (entry.*entryRect) {
- assert(entry.image.get());
- return SpriteAtlasElement {
- *(entry.*entryRect),
- *entry.image,
- size,
- pixelRatio
- };
- }
-
- const uint16_t pixelWidth = std::ceil(entry.image->image.size.width / pixelRatio);
- const uint16_t pixelHeight = std::ceil(entry.image->image.size.height / pixelRatio);
-
- // Increase to next number divisible by 4, but at least 1.
- // This is so we can scale down the texture coordinates and pack them
- // into 2 bytes rather than 4 bytes.
- const uint16_t packWidth = (pixelWidth + 1) + (4 - (pixelWidth + 1) % 4);
- const uint16_t packHeight = (pixelHeight + 1) + (4 - (pixelHeight + 1) % 4);
-
- // We have to allocate a new area in the bin, and store an empty image in it.
- Rect<uint16_t> rect = bin.allocate(packWidth, packHeight);
- if (rect.w == 0) {
- if (debug::spriteWarnings) {
- Log::Warning(Event::Sprite, "sprite atlas bitmap overflow");
- }
- return {};
- }
-
- entry.*entryRect = rect;
- copy(entry, entryRect);
-
- return SpriteAtlasElement {
- rect,
- *entry.image,
- size,
- pixelRatio
- };
-}
-
-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);
- }
-
- const PremultipliedImage& src = entry.image->image;
- const Rect<uint16_t>& rect = *(entry.*entryRect);
-
- const uint32_t padding = 1;
- 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 (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
- PremultipliedImage::copy(src, image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
- PremultipliedImage::copy(src, image, { 0, 0 }, { x + w, y }, { 1, h }); // R
- }
-
- dirty = true;
-}
-
-IconMap SpriteAtlas::buildIconMap() {
- if (icons.empty()) {
- for (const auto& entry : entries) {
- icons.emplace(std::piecewise_construct,
- std::forward_as_tuple(entry.first),
- std::forward_as_tuple(*getIcon(entry.first)));
-
- }
- }
- return icons;
-}
-
-void SpriteAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- if (!texture) {
- texture = context.createTexture(image, unit);
- } else if (dirty) {
- context.updateTexture(*texture, image, unit);
- }
-
-#if not MBGL_USE_GLES2
-// if (dirty) {
-// platform::showColorDebugImage("Sprite Atlas",
-// reinterpret_cast<const char*>(image.data.get()), size.width,
-// size.height, image.size.width, image.size.height);
-// }
-#endif // MBGL_USE_GLES2
-
- dirty = false;
-}
-
-void SpriteAtlas::bind(bool linear, gl::Context& context, gl::TextureUnit unit) {
- upload(context, unit);
- context.bindTexture(*texture, unit,
- linear ? gl::TextureFilter::Linear : gl::TextureFilter::Nearest);
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
deleted file mode 100644
index c3efeff44b..0000000000
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/binpack.hpp>
-#include <mbgl/gl/texture.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-#include <mbgl/style/image.hpp>
-
-#include <string>
-#include <map>
-#include <set>
-#include <unordered_map>
-#include <array>
-#include <memory>
-
-namespace mbgl {
-
-class Scheduler;
-class FileSource;
-class SpriteAtlasObserver;
-
-namespace gl {
-class Context;
-} // namespace gl
-
-class SpriteAtlasElement {
-public:
- SpriteAtlasElement(Rect<uint16_t>, const style::Image&, Size size, float pixelRatio);
-
- Rect<uint16_t> pos;
- bool sdf;
-
- float relativePixelRatio;
- std::array<float, 2> size;
- std::array<float, 2> tl;
- std::array<float, 2> br;
- float width;
- float height;
-};
-
-typedef std::map<std::string, SpriteAtlasElement> IconMap;
-typedef std::set<std::string> IconDependencies;
-
-class IconRequestor {
-public:
- virtual ~IconRequestor() = default;
- virtual void onIconsAvailable(IconMap) = 0;
-};
-
-class SpriteAtlas : public util::noncopyable {
-public:
- using Images = std::map<std::string, std::unique_ptr<style::Image>>;
-
- SpriteAtlas(Size, float pixelRatio);
- ~SpriteAtlas();
-
- void load(const std::string& url, Scheduler&, FileSource&);
-
- void markAsLoaded() {
- loaded = true;
- }
-
- bool isLoaded() const {
- return loaded;
- }
-
- void dumpDebugLogs() const;
-
- void setObserver(SpriteAtlasObserver*);
-
- const style::Image* getImage(const std::string&) const;
- void addImage(const std::string&, std::unique_ptr<style::Image>);
- void removeImage(const std::string&);
-
- void getIcons(IconRequestor& requestor);
- void removeRequestor(IconRequestor& requestor);
-
- 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);
-
- // Uploads the texture to the GPU to be available when we need it. This is a lazy operation;
- // the texture is only bound when the data is out of date (=dirty).
- void upload(gl::Context&, gl::TextureUnit unit);
-
- Size getSize() const { return size; }
- float getPixelRatio() const { return pixelRatio; }
-
- // Only for use in tests.
- const PremultipliedImage& getAtlasImage() const {
- return image;
- }
-
-private:
- void emitSpriteLoadedIfComplete();
-
- // Invoked by SpriteAtlasWorker
- friend class SpriteAtlasWorker;
- void onParsed(Images&& result);
- void onError(std::exception_ptr);
-
- const Size size;
- const float pixelRatio;
-
- struct Loader;
- std::unique_ptr<Loader> loader;
-
- bool loaded = false;
-
- SpriteAtlasObserver* observer = nullptr;
-
- struct Entry {
- std::unique_ptr<style::Image> image;
-
- // 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);
-
- IconMap buildIconMap();
-
- std::unordered_map<std::string, Entry> entries;
- BinPack<uint16_t> bin;
- PremultipliedImage image;
- mbgl::optional<gl::Texture> texture;
- bool dirty;
-
- std::set<IconRequestor*> requestors;
- IconMap icons;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_atlas_observer.hpp b/src/mbgl/sprite/sprite_atlas_observer.hpp
deleted file mode 100644
index 263c95b0e8..0000000000
--- a/src/mbgl/sprite/sprite_atlas_observer.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <exception>
-
-namespace mbgl {
-
-class SpriteAtlasObserver {
-public:
- virtual ~SpriteAtlasObserver() = default;
-
- virtual void onSpriteLoaded() {}
- virtual void onSpriteError(std::exception_ptr) {}
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp
new file mode 100644
index 0000000000..93d6dfd9ae
--- /dev/null
+++ b/src/mbgl/sprite/sprite_loader.cpp
@@ -0,0 +1,104 @@
+#include <mbgl/sprite/sprite_loader.hpp>
+#include <mbgl/sprite/sprite_loader_worker.hpp>
+#include <mbgl/sprite/sprite_loader_observer.hpp>
+#include <mbgl/sprite/sprite_parser.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/std.hpp>
+#include <mbgl/util/constants.hpp>
+#include <mbgl/util/exception.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/actor/actor.hpp>
+#include <mbgl/actor/scheduler.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+
+static SpriteLoaderObserver nullObserver;
+
+struct SpriteLoader::Loader {
+ Loader(Scheduler& scheduler, SpriteLoader& imageManager)
+ : mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
+ worker(scheduler, ActorRef<SpriteLoader>(imageManager, mailbox)) {
+ }
+
+ std::shared_ptr<const std::string> image;
+ std::shared_ptr<const std::string> json;
+ std::unique_ptr<AsyncRequest> jsonRequest;
+ std::unique_ptr<AsyncRequest> spriteRequest;
+ std::shared_ptr<Mailbox> mailbox;
+ Actor<SpriteLoaderWorker> worker;
+};
+
+SpriteLoader::SpriteLoader(float pixelRatio_)
+ : pixelRatio(pixelRatio_)
+ , observer(&nullObserver) {
+}
+
+SpriteLoader::~SpriteLoader() = default;
+
+void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource& fileSource) {
+ if (url.empty()) {
+ // Treat a non-existent sprite as a successfully loaded empty sprite.
+ observer->onSpriteLoaded({});
+ return;
+ }
+
+ loader = std::make_unique<Loader>(scheduler, *this);
+
+ loader->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
+ if (res.error) {
+ observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ loader->json = std::make_shared<const std::string>();
+ emitSpriteLoadedIfComplete();
+ } else {
+ // Only trigger a sprite loaded event we got new data.
+ loader->json = res.data;
+ emitSpriteLoadedIfComplete();
+ }
+ });
+
+ loader->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
+ if (res.error) {
+ observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ loader->image = std::make_shared<const std::string>();
+ emitSpriteLoadedIfComplete();
+ } else {
+ loader->image = res.data;
+ emitSpriteLoadedIfComplete();
+ }
+ });
+}
+
+void SpriteLoader::emitSpriteLoadedIfComplete() {
+ assert(loader);
+
+ if (!loader->image || !loader->json) {
+ return;
+ }
+
+ loader->worker.invoke(&SpriteLoaderWorker::parse, loader->image, loader->json);
+}
+
+void SpriteLoader::onParsed(std::vector<std::unique_ptr<style::Image>>&& result) {
+ observer->onSpriteLoaded(std::move(result));
+}
+
+void SpriteLoader::onError(std::exception_ptr err) {
+ observer->onSpriteError(err);
+}
+
+void SpriteLoader::setObserver(SpriteLoaderObserver* observer_) {
+ observer = observer_;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader.hpp b/src/mbgl/sprite/sprite_loader.hpp
new file mode 100644
index 0000000000..0daf46be9c
--- /dev/null
+++ b/src/mbgl/sprite/sprite_loader.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/style/image.hpp>
+
+#include <string>
+#include <map>
+#include <set>
+#include <vector>
+#include <array>
+#include <memory>
+
+namespace mbgl {
+
+class Scheduler;
+class FileSource;
+class SpriteLoaderObserver;
+
+class SpriteLoader : public util::noncopyable {
+public:
+ SpriteLoader(float pixelRatio);
+ ~SpriteLoader();
+
+ void load(const std::string& url, Scheduler&, FileSource&);
+
+ void setObserver(SpriteLoaderObserver*);
+
+private:
+ void emitSpriteLoadedIfComplete();
+
+ // Invoked by SpriteAtlasWorker
+ friend class SpriteLoaderWorker;
+ void onParsed(std::vector<std::unique_ptr<style::Image>>&&);
+ void onError(std::exception_ptr);
+
+ const float pixelRatio;
+
+ struct Loader;
+ std::unique_ptr<Loader> loader;
+
+ SpriteLoaderObserver* observer = nullptr;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader_observer.hpp b/src/mbgl/sprite/sprite_loader_observer.hpp
new file mode 100644
index 0000000000..c730549c2c
--- /dev/null
+++ b/src/mbgl/sprite/sprite_loader_observer.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <exception>
+#include <memory>
+#include <vector>
+
+namespace mbgl {
+
+namespace style {
+class Image;
+} // namespace style
+
+class SpriteLoaderObserver {
+public:
+ virtual ~SpriteLoaderObserver() = default;
+
+ virtual void onSpriteLoaded(std::vector<std::unique_ptr<style::Image>>&&) {}
+ virtual void onSpriteError(std::exception_ptr) {}
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_atlas_worker.cpp b/src/mbgl/sprite/sprite_loader_worker.cpp
index da507aabab..4bded33d53 100644
--- a/src/mbgl/sprite/sprite_atlas_worker.cpp
+++ b/src/mbgl/sprite/sprite_loader_worker.cpp
@@ -1,14 +1,14 @@
-#include <mbgl/sprite/sprite_atlas_worker.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/sprite/sprite_loader_worker.hpp>
+#include <mbgl/sprite/sprite_loader.hpp>
#include <mbgl/sprite/sprite_parser.hpp>
namespace mbgl {
-SpriteAtlasWorker::SpriteAtlasWorker(ActorRef<SpriteAtlasWorker>, ActorRef<SpriteAtlas> parent_)
+SpriteLoaderWorker::SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<SpriteLoader> parent_)
: parent(std::move(parent_)) {
}
-void SpriteAtlasWorker::parse(std::shared_ptr<const std::string> image,
+void SpriteLoaderWorker::parse(std::shared_ptr<const std::string> image,
std::shared_ptr<const std::string> json) {
try {
if (!image) {
@@ -20,9 +20,9 @@ void SpriteAtlasWorker::parse(std::shared_ptr<const std::string> image,
throw std::runtime_error("missing sprite metadata");
}
- parent.invoke(&SpriteAtlas::onParsed, parseSprite(*image, *json));
+ parent.invoke(&SpriteLoader::onParsed, parseSprite(*image, *json));
} catch (...) {
- parent.invoke(&SpriteAtlas::onError, std::current_exception());
+ parent.invoke(&SpriteLoader::onError, std::current_exception());
}
}
diff --git a/src/mbgl/sprite/sprite_atlas_worker.hpp b/src/mbgl/sprite/sprite_loader_worker.hpp
index 70ca0d52e5..d61e07d14f 100644
--- a/src/mbgl/sprite/sprite_atlas_worker.hpp
+++ b/src/mbgl/sprite/sprite_loader_worker.hpp
@@ -8,16 +8,16 @@
namespace mbgl {
-class SpriteAtlas;
+class SpriteLoader;
-class SpriteAtlasWorker {
+class SpriteLoaderWorker {
public:
- SpriteAtlasWorker(ActorRef<SpriteAtlasWorker>, ActorRef<SpriteAtlas>);
+ SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<SpriteLoader>);
void parse(std::shared_ptr<const std::string> image, std::shared_ptr<const std::string> json);
private:
- ActorRef<SpriteAtlas> parent;
+ ActorRef<SpriteLoader> parent;
};
} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp
index c3ed20d03f..1a36e3e990 100644
--- a/src/mbgl/sprite/sprite_parser.cpp
+++ b/src/mbgl/sprite/sprite_parser.cpp
@@ -13,13 +13,14 @@
namespace mbgl {
-std::unique_ptr<style::Image> createStyleImage(const PremultipliedImage& image,
- const uint32_t srcX,
- const uint32_t srcY,
- const uint32_t width,
- const uint32_t height,
- const double ratio,
- const bool sdf) {
+std::unique_ptr<style::Image> createStyleImage(const std::string& id,
+ const PremultipliedImage& image,
+ const uint32_t srcX,
+ const uint32_t srcY,
+ const uint32_t width,
+ const uint32_t height,
+ const double ratio,
+ const bool sdf) {
// Disallow invalid parameter configurations.
if (width <= 0 || height <= 0 || width > 1024 || height > 1024 ||
ratio <= 0 || ratio > 10 ||
@@ -37,7 +38,7 @@ std::unique_ptr<style::Image> createStyleImage(const PremultipliedImage& image,
// Copy from the source image into our individual sprite image
PremultipliedImage::copy(image, dstImage, { srcX, srcY }, { 0, 0 }, { width, height });
- return std::make_unique<style::Image>(std::move(dstImage), ratio, sdf);
+ return std::make_unique<style::Image>(id, std::move(dstImage), ratio, sdf);
}
namespace {
@@ -84,7 +85,7 @@ bool getBoolean(const JSValue& value, const char* name, const bool def = false)
} // namespace
-Images parseSprite(const std::string& encodedImage, const std::string& json) {
+std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& encodedImage, const std::string& json) {
const PremultipliedImage raster = decodeImage(encodedImage);
JSDocument doc;
@@ -96,7 +97,7 @@ Images parseSprite(const std::string& encodedImage, const std::string& json) {
} else if (!doc.IsObject()) {
throw std::runtime_error("Sprite JSON root must be an object");
} else {
- Images images;
+ std::vector<std::unique_ptr<style::Image>> images;
for (const auto& property : doc.GetObject()) {
const std::string name = { property.name.GetString(), property.name.GetStringLength() };
const JSValue& value = property.value;
@@ -109,9 +110,9 @@ Images parseSprite(const std::string& encodedImage, const std::string& json) {
const double pixelRatio = getDouble(value, "pixelRatio", 1);
const bool sdf = getBoolean(value, "sdf", false);
- auto image = createStyleImage(raster, x, y, width, height, pixelRatio, sdf);
+ auto image = createStyleImage(name, raster, x, y, width, height, pixelRatio, sdf);
if (image) {
- images.emplace(name, std::move(image));
+ images.push_back(std::move(image));
}
}
}
diff --git a/src/mbgl/sprite/sprite_parser.hpp b/src/mbgl/sprite/sprite_parser.hpp
index 5be8435ebb..f602818d3b 100644
--- a/src/mbgl/sprite/sprite_parser.hpp
+++ b/src/mbgl/sprite/sprite_parser.hpp
@@ -1,13 +1,10 @@
#pragma once
#include <mbgl/util/image.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/variant.hpp>
-#include <mbgl/util/geo.hpp>
#include <string>
#include <memory>
-#include <map>
+#include <vector>
namespace mbgl {
@@ -16,17 +13,16 @@ class Image;
} // namespace style
// Extracts an individual image from a spritesheet from the given location.
-std::unique_ptr<style::Image> createStyleImage(const PremultipliedImage&,
- uint32_t srcX,
- uint32_t srcY,
- uint32_t srcWidth,
- uint32_t srcHeight,
- double ratio,
- bool sdf);
-
-using Images = std::map<std::string, std::unique_ptr<style::Image>>;
+std::unique_ptr<style::Image> createStyleImage(const std::string& id,
+ const PremultipliedImage&,
+ uint32_t srcX,
+ uint32_t srcY,
+ uint32_t srcWidth,
+ uint32_t srcHeight,
+ double ratio,
+ bool sdf);
// Parses an image and an associated JSON file and returns the sprite objects.
-Images parseSprite(const std::string& image, const std::string& json);
+std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& image, const std::string& json);
} // namespace mbgl