summaryrefslogtreecommitdiff
path: root/src/mbgl/text/glyph_atlas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/text/glyph_atlas.cpp')
-rw-r--r--src/mbgl/text/glyph_atlas.cpp113
1 files changed, 64 insertions, 49 deletions
diff --git a/src/mbgl/text/glyph_atlas.cpp b/src/mbgl/text/glyph_atlas.cpp
index ade2734ca9..3e8bb0fe9c 100644
--- a/src/mbgl/text/glyph_atlas.cpp
+++ b/src/mbgl/text/glyph_atlas.cpp
@@ -4,6 +4,9 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/platform.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/storage/resource.hpp>
+#include <mbgl/storage/response.hpp>
#include <cassert>
#include <algorithm>
@@ -34,21 +37,15 @@ bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const GlyphRangeSet&
}
return true;
}
-
-bool rangeIsParsed(const std::map<GlyphRange, GlyphPBF>& ranges, const GlyphRange& range) {
- auto rangeIt = ranges.find(range);
- if (rangeIt == ranges.end())
- return false;
-
- return rangeIt->second.isParsed();
+
+bool GlyphAtlas::rangeIsParsed(const std::map<GlyphRange, GlyphRequest>& ranges, const GlyphRange& range) const {
+ auto it = ranges.find(range);
+ return it != ranges.end() && it->second.parsed;
}
-
+
bool GlyphAtlas::hasGlyphRange(const FontStack& fontStack, const GlyphRange& range) const {
- auto entry = entries.find(fontStack);
- if (entry == entries.end())
- return false;
-
- return rangeIsParsed(entry->second.ranges, range);
+ auto it = entries.find(fontStack);
+ return it != entries.end() && rangeIsParsed(it->second.ranges, range);
}
void GlyphAtlas::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDependencies) {
@@ -60,23 +57,19 @@ void GlyphAtlas::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDep
// for that requestor have been fetched, and can notify it of completion.
for (const auto& dependency : *dependencies) {
const FontStack& fontStack = dependency.first;
- const GlyphIDs& glyphIDs = dependency.second;
-
Entry& entry = entries[fontStack];
- GlyphRangeSet processedRanges;
+ const GlyphIDs& glyphIDs = dependency.second;
+ GlyphRangeSet ranges;
for (const auto& glyphID : glyphIDs) {
- GlyphRange range = getGlyphRange(glyphID);
- if (processedRanges.find(range) == processedRanges.end() && !rangeIsParsed(entry.ranges, range)) {
- if (entry.ranges.find(range) == entry.ranges.end()) {
- entry.ranges.emplace(std::piecewise_construct,
- std::forward_as_tuple(range),
- std::forward_as_tuple(this, fontStack, range, this, fileSource));
- }
+ ranges.insert(getGlyphRange(glyphID));
+ }
- entry.ranges.find(range)->second.requestors[&requestor] = dependencies;
+ for (const auto& range : ranges) {
+ if (!rangeIsParsed(entry.ranges, range)) {
+ GlyphRequest& request = requestRange(entry, fontStack, range);
+ request.requestors[&requestor] = dependencies;
}
- processedRanges.insert(range);
}
}
@@ -87,34 +80,56 @@ void GlyphAtlas::getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphDep
}
}
-void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) {
- observer = observer_;
-}
-
-void GlyphAtlas::onGlyphsError(const FontStack& fontStack, const GlyphRange& range, std::exception_ptr err) {
- if (observer) {
- observer->onGlyphsError(fontStack, range, err);
+GlyphAtlas::GlyphRequest& GlyphAtlas::requestRange(Entry& entry, const FontStack& fontStack, const GlyphRange& range) {
+ GlyphRequest& request = entry.ranges[range];
+
+ if (request.req) {
+ return request;
}
-}
-void GlyphAtlas::onGlyphsLoaded(const FontStack& fontStack, const GlyphRange& range) {
- Entry& entry = entries[fontStack];
+ request.req = fileSource.request(Resource::glyphs(glyphURL, fontStack, range),
+ [this, &entry, &request, fontStack, range](Response res) {
+ if (res.error) {
+ observer->onGlyphsError(fontStack, range, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else {
+ if (!res.noContent) {
+ std::vector<SDFGlyph> glyphs;
+
+ try {
+ glyphs = parseGlyphPBF(range, *res.data);
+ } catch (...) {
+ observer->onGlyphsError(fontStack, range, std::current_exception());
+ return;
+ }
+
+ for (auto& glyph : glyphs) {
+ entry.glyphSet.insert(std::move(glyph));
+ }
+ }
+
+ request.parsed = true;
+
+ for (auto& pair : request.requestors) {
+ GlyphRequestor& requestor = *pair.first;
+ const std::shared_ptr<GlyphDependencies>& dependencies = pair.second;
+ if (dependencies.unique()) {
+ addGlyphs(requestor, *dependencies);
+ }
+ }
+
+ request.requestors.clear();
- auto it = entry.ranges.find(range);
- if (it != entry.ranges.end()) {
- for (auto& pair : it->second.requestors) {
- GlyphRequestor& requestor = *pair.first;
- const std::shared_ptr<GlyphDependencies>& dependencies = pair.second;
- if (dependencies.unique()) {
- addGlyphs(requestor, *dependencies);
+ observer->onGlyphsLoaded(fontStack, range);
}
- }
- it->second.requestors.clear();
- }
+ });
- if (observer) {
- observer->onGlyphsLoaded(fontStack, range);
- }
+ return request;
+}
+
+void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) {
+ observer = observer_ ? observer_ : &nullObserver;
}
void GlyphAtlas::addGlyphs(GlyphRequestor& requestor, const GlyphDependencies& glyphDependencies) {
@@ -228,7 +243,7 @@ void GlyphAtlas::removeGlyphValues(GlyphRequestor& requestor, std::map<uint32_t,
}
}
-void GlyphAtlas::removePendingRanges(mbgl::GlyphRequestor &requestor, std::map<GlyphRange, GlyphPBF> &ranges) {
+void GlyphAtlas::removePendingRanges(mbgl::GlyphRequestor& requestor, std::map<GlyphRange, GlyphRequest>& ranges) {
for (auto it = ranges.begin(); it != ranges.end(); it++) {
it->second.requestors.erase(&requestor);
}