summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/style.js2
-rw-r--r--config/constants.cpp2
-rw-r--r--include/llmr/map/source.hpp3
-rw-r--r--include/llmr/style/style.hpp1
-rw-r--r--include/llmr/style/style_parser.hpp8
-rw-r--r--include/llmr/text/glyph_store.hpp7
-rw-r--r--include/llmr/util/constants.hpp2
-rw-r--r--src/map/map.cpp11
-rw-r--r--src/map/source.cpp3
-rw-r--r--src/map/tile_parser.cpp6
-rw-r--r--src/style/style.cpp1
-rw-r--r--src/style/style_parser.cpp14
-rw-r--r--src/text/glyph_store.cpp16
13 files changed, 58 insertions, 18 deletions
diff --git a/bin/style.js b/bin/style.js
index c5d98180f7..b3e692904b 100644
--- a/bin/style.js
+++ b/bin/style.js
@@ -3,6 +3,7 @@
module.exports = {
"version": 3,
"sprite": "http://mapbox-kkaefer.s3.amazonaws.com/static/outdoors-gl/sprite",
+ "glyphs": "http://mapbox.s3.amazonaws.com/gl-glyphs-256/{{fontstack}}/{{range}}.pbf",
"constants": {
"@land": "#eee",
"@water": "#999",
@@ -19,7 +20,6 @@ module.exports = {
"mapbox.mapbox-streets-v5": {
"type": "vector",
"url": "mapbox://mapbox.mapbox-streets-v5",
- "glyphs": "http://mapbox.s3.amazonaws.com/gl-glyphs-256/{fontstack}/{range}.pbf",
"maxZoom": 14
}
},
diff --git a/config/constants.cpp b/config/constants.cpp
index 5be91a9fae..36f51559e2 100644
--- a/config/constants.cpp
+++ b/config/constants.cpp
@@ -1,7 +1,5 @@
#include <llmr/util/constants.hpp>
-const char *llmr::kGlyphURL = "http://mapbox.s3.amazonaws.com/gl-glyphs-256/%s/%d-%d.pbf";
-
const float llmr::util::tileSize = 512.0f;
#if defined(DEBUG)
diff --git a/include/llmr/map/source.hpp b/include/llmr/map/source.hpp
index 0d6ef864f9..2937a8f690 100644
--- a/include/llmr/map/source.hpp
+++ b/include/llmr/map/source.hpp
@@ -22,7 +22,7 @@ class Texturepool;
class Source : public std::enable_shared_from_this<Source>, private util::noncopyable {
public:
- Source(SourceType type = SourceType::Vector, const std::string &url = "", const std::string &glyphs = "",
+ Source(SourceType type = SourceType::Vector, const std::string &url = "",
uint32_t tile_size = 512, uint32_t min_zoom = 0, uint32_t max_zoom = 22);
bool update(Map &map);
@@ -40,7 +40,6 @@ public:
public:
const SourceType type;
const std::string url;
- const std::string glyphs;
const uint32_t tile_size;
const int32_t min_zoom;
const int32_t max_zoom;
diff --git a/include/llmr/style/style.hpp b/include/llmr/style/style.hpp
index fca18a7c9f..47539fb0b0 100644
--- a/include/llmr/style/style.hpp
+++ b/include/llmr/style/style.hpp
@@ -51,6 +51,7 @@ public:
std::shared_ptr<StyleLayer> background;
std::vector<std::string> appliedClasses;
std::string sprite_url;
+ std::string glyph_url;
private:
void updateSources();
diff --git a/include/llmr/style/style_parser.hpp b/include/llmr/style/style_parser.hpp
index c0570eae7e..777a8934da 100644
--- a/include/llmr/style/style_parser.hpp
+++ b/include/llmr/style/style_parser.hpp
@@ -34,6 +34,10 @@ public:
return sprite;
}
+ std::string getGlyphURL() const {
+ return glyph_url;
+ }
+
private:
void parseConstants(JSVal value);
JSVal replaceConstant(JSVal value);
@@ -51,6 +55,7 @@ private:
void parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer);
void parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer);
void parseSprite(JSVal value);
+ void parseGlyphURL(JSVal value);
// Parses optional properties into a render bucket.
template<typename T>
@@ -94,6 +99,9 @@ private:
// Base URL of the sprite image.
std::string sprite;
+
+ // URL template for glyph PBFs.
+ std::string glyph_url;
};
}
diff --git a/include/llmr/text/glyph_store.hpp b/include/llmr/text/glyph_store.hpp
index e44b94fe08..a1d1046b7f 100644
--- a/include/llmr/text/glyph_store.hpp
+++ b/include/llmr/text/glyph_store.hpp
@@ -51,7 +51,7 @@ private:
class GlyphPBF {
public:
- GlyphPBF(const std::string &fontStack, GlyphRange glyphRange);
+ GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange);
void parse(FontStack &stack);
@@ -67,6 +67,8 @@ private:
// Manages Glyphrange PBF loading.
class GlyphStore {
public:
+ GlyphStore(const std::string &glyphURL);
+
// Block until all specified GlyphRanges of the specified font stack are loaded.
void waitForGlyphRanges(const std::string &fontStack, const std::set<GlyphRange> &glyphRanges);
@@ -78,6 +80,9 @@ private:
FontStack &createFontStack(const std::string &fontStack);
+public:
+ const std::string glyphURL;
+
private:
std::unordered_map<std::string, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>> ranges;
std::unordered_map<std::string, std::unique_ptr<FontStack>> stacks;
diff --git a/include/llmr/util/constants.hpp b/include/llmr/util/constants.hpp
index 49f7a5f4b9..999ef05fcc 100644
--- a/include/llmr/util/constants.hpp
+++ b/include/llmr/util/constants.hpp
@@ -7,8 +7,6 @@
namespace llmr {
-extern const char *kGlyphURL;
-
namespace util {
extern const float tileSize;
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 703cdf1400..50c172caaa 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -24,7 +24,6 @@ Map::Map(View& view)
transform(),
style(std::make_shared<Style>()),
glyphAtlas(std::make_shared<GlyphAtlas>(1024, 1024)),
- glyphStore(std::make_shared<GlyphStore>()),
spriteAtlas(std::make_shared<SpriteAtlas>(512, 512)),
texturepool(std::make_shared<Texturepool>()),
painter(*this),
@@ -439,6 +438,16 @@ void Map::prepare() {
spriteAtlas->resize(state.getPixelRatio());
}
+ // Create a new glyph store object in case the glyph URL changed.
+ // TODO: Move this to a less frequently called place; we only need to do this when the
+ // stylesheet changes.
+ if (glyphStore && glyphStore->glyphURL != style->glyph_url) {
+ glyphStore.reset();
+ }
+ if (!glyphStore && style->glyph_url.size()) {
+ glyphStore = std::make_shared<GlyphStore>(style->glyph_url);
+ }
+
if (pixelRatioChanged || dimensionsChanged) {
painter.clearFramebuffers();
}
diff --git a/src/map/source.cpp b/src/map/source.cpp
index 6f7bb811fd..c3c5e89fd4 100644
--- a/src/map/source.cpp
+++ b/src/map/source.cpp
@@ -17,11 +17,10 @@
namespace llmr {
-Source::Source(SourceType type, const std::string &url, const std::string &glyphs,
+Source::Source(SourceType type, const std::string &url,
uint32_t tile_size, uint32_t min_zoom, uint32_t max_zoom)
: type(type),
url(normalizeSourceURL(url)),
- glyphs(glyphs),
tile_size(tile_size),
min_zoom(min_zoom),
max_zoom(max_zoom) {}
diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp
index b3a018f427..4cf7fb22fa 100644
--- a/src/map/tile_parser.cpp
+++ b/src/map/tile_parser.cpp
@@ -183,6 +183,12 @@ std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer& laye
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketText &text) {
+ // Make sure that we always have a valid glyph store. If this is not set, the stylesheet
+ // doesn't specify a glyph URL.
+ if (!glyphStore) {
+ return nullptr;
+ }
+
const StyleBucketText &properties = text;
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
diff --git a/src/style/style.cpp b/src/style/style.cpp
index 8a23273f06..d6894f6e1c 100644
--- a/src/style/style.cpp
+++ b/src/style/style.cpp
@@ -103,6 +103,7 @@ void Style::loadJSON(const uint8_t *const data) {
layers = parser.getLayers();
sprite_url = parser.getSprite();
+ glyph_url = parser.getGlyphURL();
updateClasses();
}
diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp
index a9d5c96985..069de2dbc5 100644
--- a/src/style/style_parser.cpp
+++ b/src/style/style_parser.cpp
@@ -25,6 +25,10 @@ void StyleParser::parse(JSVal document) {
if (document.HasMember("sprite")) {
parseSprite(document["sprite"]);
}
+
+ if (document.HasMember("glyphs")) {
+ parseGlyphURL(document["glyphs"]);
+ }
}
void StyleParser::parseConstants(JSVal value) {
@@ -155,19 +159,17 @@ void StyleParser::parseSources(JSVal value) {
std::string name { itr->name.GetString(), itr->name.GetStringLength() };
SourceType type = SourceType::Vector;
std::string url;
- std::string glyphs;
uint16_t tile_size = 512;
int32_t min_zoom = 0;
int32_t max_zoom = 22;
parseRenderProperty(itr->value, type, "type", parseSourceType);
parseRenderProperty(itr->value, url, "url");
- parseRenderProperty(itr->value, glyphs, "glyphs");
parseRenderProperty(itr->value, tile_size, "tileSize");
parseRenderProperty(itr->value, min_zoom, "minZoom");
parseRenderProperty(itr->value, max_zoom, "maxZoom");
- sources.emplace(std::move(name), std::make_shared<Source>(type, url, glyphs, tile_size, min_zoom, max_zoom));
+ sources.emplace(std::move(name), std::make_shared<Source>(type, url, tile_size, min_zoom, max_zoom));
}
} else {
throw Style::exception("sources must be an object");
@@ -921,5 +923,11 @@ void StyleParser::parseSprite(JSVal value) {
}
}
+void StyleParser::parseGlyphURL(JSVal value) {
+ if (value.IsString()) {
+ glyph_url = { value.GetString(), value.GetStringLength() };
+ }
+}
+
}
diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp
index 9d88a692b5..b79010670d 100644
--- a/src/text/glyph_store.cpp
+++ b/src/text/glyph_store.cpp
@@ -5,6 +5,7 @@
#include <llmr/util/utf.hpp>
#include <llmr/util/pbf.hpp>
#include <llmr/util/constants.hpp>
+#include <llmr/util/token.hpp>
#include <llmr/platform/platform.hpp>
#include <uv.h>
#include <algorithm>
@@ -115,11 +116,16 @@ void FontStack::lineWrap(Shaping &shaping, const float &lineHeight, const float
alignVertically(shaping, line + 1, lineHeight, verticalAlignment);
}
-GlyphPBF::GlyphPBF(const std::string &fontStack, GlyphRange glyphRange)
+GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange)
: future(promise.get_future().share())
{
// Load the glyph set URL
- std::string url = util::sprintf<255>(kGlyphURL, fontStack.c_str(), glyphRange.first, glyphRange.second);
+
+ const std::map<std::string, std::string> tokens {{
+ { "fontstack", fontStack },
+ { "range", std::to_string(glyphRange.first) + "-" + std::to_string(glyphRange.second) }
+ }};
+ std::string url = util::replaceTokens(glyphURL, tokens);
// TODO: Find more reliable URL normalization function
std::replace(url.begin(), url.end(), ' ', '+');
@@ -202,6 +208,8 @@ void GlyphPBF::parse(FontStack &stack) {
data.clear();
}
+GlyphStore::GlyphStore(const std::string &glyphURL)
+ : glyphURL(glyphURL) {}
void GlyphStore::waitForGlyphRanges(const std::string &fontStack, const std::set<GlyphRange> &glyphRanges) {
// We are implementing a blocking wait with futures: Every GlyphSet has a future that we are
@@ -232,11 +240,11 @@ void GlyphStore::waitForGlyphRanges(const std::string &fontStack, const std::set
}
}
-std::shared_future<GlyphPBF &> GlyphStore::loadGlyphRange(const std::string &name, std::map<GlyphRange, std::unique_ptr<GlyphPBF>> &rangeSets, const GlyphRange range) {
+std::shared_future<GlyphPBF &> GlyphStore::loadGlyphRange(const std::string &fontStack, std::map<GlyphRange, std::unique_ptr<GlyphPBF>> &rangeSets, const GlyphRange range) {
auto range_it = rangeSets.find(range);
if (range_it == rangeSets.end()) {
// We don't have this glyph set yet for this font stack.
- range_it = rangeSets.emplace(range, std::make_unique<GlyphPBF>(name, range)).first;
+ range_it = rangeSets.emplace(range, std::make_unique<GlyphPBF>(glyphURL, fontStack, range)).first;
}
return range_it->second->getFuture();