summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/llmr/geometry/glyph_atlas.hpp3
-rw-r--r--include/llmr/map/map.hpp3
-rw-r--r--include/llmr/map/tile.hpp1
-rw-r--r--include/llmr/map/tile_parser.hpp8
-rw-r--r--include/llmr/map/vector_tile_data.hpp4
-rw-r--r--include/llmr/platform/gl.hpp2
-rw-r--r--include/llmr/platform/platform.hpp4
-rw-r--r--include/llmr/renderer/bucket.hpp1
-rw-r--r--include/llmr/renderer/prerendered_texture.hpp1
-rw-r--r--include/llmr/renderer/text_bucket.hpp3
-rw-r--r--include/llmr/style/properties.hpp1
-rw-r--r--include/llmr/style/style_parser.hpp2
-rw-r--r--include/llmr/text/collision.hpp2
-rw-r--r--include/llmr/text/glyph.hpp5
-rw-r--r--include/llmr/text/glyph_store.hpp80
-rw-r--r--include/llmr/text/placement.hpp4
-rw-r--r--include/llmr/util/constants.hpp5
-rw-r--r--include/llmr/util/utf.hpp45
18 files changed, 162 insertions, 12 deletions
diff --git a/include/llmr/geometry/glyph_atlas.hpp b/include/llmr/geometry/glyph_atlas.hpp
index 312572f5ef..5bcd573f56 100644
--- a/include/llmr/geometry/glyph_atlas.hpp
+++ b/include/llmr/geometry/glyph_atlas.hpp
@@ -2,6 +2,7 @@
#define LLMR_GEOMETRY_GLYPH_ATLAS
#include <llmr/geometry/binpack.hpp>
+#include <llmr/text/glyph_store.hpp>
#include <string>
#include <set>
@@ -30,7 +31,7 @@ public:
Rect<uint16_t> addGlyph(uint64_t tile_id, const std::string& face_name,
- const VectorTileGlyph& glyph);
+ const SDFGlyph& glyph);
void removeGlyphs(uint64_t tile_id);
void bind();
diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp
index ab1738f961..49050540c9 100644
--- a/include/llmr/map/map.hpp
+++ b/include/llmr/map/map.hpp
@@ -8,6 +8,7 @@
#include <llmr/map/transform.hpp>
#include <llmr/style/style.hpp>
#include <llmr/geometry/glyph_atlas.hpp>
+#include <llmr/text/glyph_store.hpp>
#include <llmr/renderer/painter.hpp>
#include <llmr/util/noncopyable.hpp>
#include <llmr/util/texturepool.hpp>
@@ -98,6 +99,7 @@ public:
inline const TransformState &getState() const { return state; }
inline const Style &getStyle() const { return style; }
inline GlyphAtlas &getGlyphAtlas() { return glyphAtlas; }
+ inline GlyphStore &getGlyphStore() { return glyphStore; }
inline SpriteAtlas &getSpriteAtlas() { return spriteAtlas; }
inline uv_loop_t *getLoop() { return loop; }
inline time getAnimationTime() const { return animationTime; }
@@ -152,6 +154,7 @@ private:
Texturepool texturepool;
Style style;
GlyphAtlas glyphAtlas;
+ GlyphStore glyphStore;
SpriteAtlas spriteAtlas;
Painter painter;
diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp
index 0f43f9df2b..9681c36374 100644
--- a/include/llmr/map/tile.hpp
+++ b/include/llmr/map/tile.hpp
@@ -9,6 +9,7 @@
#include <forward_list>
#include <string>
#include <bitset>
+#include <memory>
namespace llmr {
diff --git a/include/llmr/map/tile_parser.hpp b/include/llmr/map/tile_parser.hpp
index 86545e4f76..5785c29b3a 100644
--- a/include/llmr/map/tile_parser.hpp
+++ b/include/llmr/map/tile_parser.hpp
@@ -4,11 +4,15 @@
#include <llmr/map/vector_tile_data.hpp>
#include <llmr/map/vector_tile.hpp>
#include <llmr/text/placement.hpp>
+#include <llmr/text/glyph_store.hpp>
+#include <llmr/text/glyph.hpp>
+#include <llmr/util/utf.hpp>
namespace llmr {
class Style;
class GlyphAtlas;
+class GlyphStore;
class SpriteAtlas;
class LayerDescription;
@@ -16,12 +20,13 @@ class Bucket;
class TileParser {
public:
- TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, SpriteAtlas &spriteAtlas);
+ TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, GlyphStore &glyphStore, SpriteAtlas &spriteAtlas);
private:
bool obsolete() const;
void parseGlyphs();
void parseStyleLayers(const std::vector<LayerDescription>& layers);
+ void addGlyph(uint64_t tileid, const std::string stackname, const std::u32string &string, const FontStack &fontStack, GlyphAtlas &glyphAtlas, GlyphPositions &face);
std::unique_ptr<Bucket> createBucket(const BucketDescription& bucket_desc);
std::unique_ptr<Bucket> createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc);
@@ -35,6 +40,7 @@ private:
VectorTileData& tile;
const Style& style;
GlyphAtlas& glyphAtlas;
+ GlyphStore &glyphStore;
SpriteAtlas &spriteAtlas;
Faces faces;
Placement placement;
diff --git a/include/llmr/map/vector_tile_data.hpp b/include/llmr/map/vector_tile_data.hpp
index 24d2c7cc2b..f82e2ebff9 100644
--- a/include/llmr/map/vector_tile_data.hpp
+++ b/include/llmr/map/vector_tile_data.hpp
@@ -13,7 +13,7 @@
#include <llmr/geometry/icon_buffer.hpp>
#include <llmr/geometry/text_buffer.hpp>
-#include <map>
+#include <unordered_map>
namespace llmr {
@@ -42,7 +42,7 @@ protected:
// Holds the buckets of this tile.
// They contain the location offsets in the buffers stored above
- std::map<std::string, std::unique_ptr<Bucket>> buckets;
+ std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
};
diff --git a/include/llmr/platform/gl.hpp b/include/llmr/platform/gl.hpp
index f0f913a5ea..da30d746e5 100644
--- a/include/llmr/platform/gl.hpp
+++ b/include/llmr/platform/gl.hpp
@@ -39,7 +39,7 @@
namespace llmr {
namespace gl {
// Debug group markers, useful for debuggin on iOS
-#if GL_EXT_debug_marker
+#if defined(__APPLE__) && defined(DEBUG) && defined(GL_EXT_debug_marker)
// static int indent = 0;
inline void start_group(const std::string &str) {
glPushGroupMarkerEXT(0, str.c_str());
diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp
index 972e7db6ba..d516378c2a 100644
--- a/include/llmr/platform/platform.hpp
+++ b/include/llmr/platform/platform.hpp
@@ -25,9 +25,11 @@ struct Response {
// Makes an HTTP request of a URL, preferrably on a background thread, and calls a function with the
// results in the original thread (which runs the libuv loop).
+// If the loop pointer is NULL, the callback function will be called on an arbitrary thread.
// Returns a cancellable request.
std::shared_ptr<Request> request_http(const std::string &url,
- std::function<void(Response *)> callback, uv_loop_t *loop);
+ std::function<void(Response *)> callback,
+ uv_loop_t *loop = nullptr);
// Cancels an HTTP request.
void cancel_request_http(const std::shared_ptr<Request> &req);
diff --git a/include/llmr/renderer/bucket.hpp b/include/llmr/renderer/bucket.hpp
index f8447be89a..43bd96e3f5 100644
--- a/include/llmr/renderer/bucket.hpp
+++ b/include/llmr/renderer/bucket.hpp
@@ -2,6 +2,7 @@
#define LLMR_RENDERER_BUCKET
#include <string>
+#include <memory>
#include <llmr/map/tile.hpp>
#include <llmr/util/noncopyable.hpp>
#include <llmr/renderer/prerendered_texture.hpp>
diff --git a/include/llmr/renderer/prerendered_texture.hpp b/include/llmr/renderer/prerendered_texture.hpp
index e35cc0321e..4b163ac70c 100644
--- a/include/llmr/renderer/prerendered_texture.hpp
+++ b/include/llmr/renderer/prerendered_texture.hpp
@@ -26,7 +26,6 @@ private:
GLint previous_fbo = 0;
GLuint fbo = 0;
GLuint texture = 0;
- bool mipmapped = false;
};
}
diff --git a/include/llmr/renderer/text_bucket.hpp b/include/llmr/renderer/text_bucket.hpp
index 2b73aa74da..ad282bdd0b 100644
--- a/include/llmr/renderer/text_bucket.hpp
+++ b/include/llmr/renderer/text_bucket.hpp
@@ -7,6 +7,7 @@
#include <llmr/geometry/elements_buffer.hpp>
#include <llmr/map/vector_tile.hpp>
#include <llmr/text/types.hpp>
+#include <llmr/text/glyph.hpp>
#include <memory>
#include <map>
#include <vector>
@@ -36,7 +37,7 @@ public:
PlacementRange placementRange, float zoom);
void addFeature(const VectorTileFeature &feature,
- const IndexedFaces &faces,
+ const GlyphPositions &face,
const std::map<Value, Shaping> &shapings);
void drawGlyphs(TextShader &shader);
diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp
index 4dfc7e40b5..b8ffcfad6e 100644
--- a/include/llmr/style/properties.hpp
+++ b/include/llmr/style/properties.hpp
@@ -16,6 +16,7 @@ namespace llmr {
typedef std::array<float, 4> Color;
struct PropertyTransition {
+ inline PropertyTransition(uint16_t duration, uint16_t delay = 0) : duration(duration), delay(delay) {}
uint16_t duration = 0;
uint16_t delay = 0;
};
diff --git a/include/llmr/style/style_parser.hpp b/include/llmr/style/style_parser.hpp
index 109b94f1ff..7c7d0a70ab 100644
--- a/include/llmr/style/style_parser.hpp
+++ b/include/llmr/style/style_parser.hpp
@@ -47,7 +47,7 @@ private:
Value parseValue(JSVal value);
FunctionProperty::fn parseFunctionType(JSVal type);
FunctionProperty parseFunction(JSVal value);
- PropertyTransition parseTransition(JSVal value, std::string property_name);
+ boost::optional<PropertyTransition> parseTransition(JSVal value, std::string property_name);
private:
std::map<std::string, const rapidjson::Value *> constants;
diff --git a/include/llmr/text/collision.hpp b/include/llmr/text/collision.hpp
index ef4899c264..c9dafdd386 100644
--- a/include/llmr/text/collision.hpp
+++ b/include/llmr/text/collision.hpp
@@ -11,7 +11,7 @@ public:
Collision();
~Collision();
- PlacementProperty place(const PlacedGlyphs &boxes,
+ PlacementProperty place(const GlyphBoxes &boxes,
const CollisionAnchor &anchor,
float minPlacementScale, float maxPlacementScale,
float padding, bool horizontal, bool alwaysVisible);
diff --git a/include/llmr/text/glyph.hpp b/include/llmr/text/glyph.hpp
index 91531e24f3..e6138e712e 100644
--- a/include/llmr/text/glyph.hpp
+++ b/include/llmr/text/glyph.hpp
@@ -9,6 +9,11 @@
namespace llmr {
+typedef std::pair<uint16_t, uint16_t> GlyphRange;
+
+// Note: this only works for the BMP
+GlyphRange getGlyphRange(uint32_t glyph);
+
struct GlyphMetrics {
operator bool() const {
return width == 0 && height == 0 && advance == 0;
diff --git a/include/llmr/text/glyph_store.hpp b/include/llmr/text/glyph_store.hpp
new file mode 100644
index 0000000000..eb5d6038f1
--- /dev/null
+++ b/include/llmr/text/glyph_store.hpp
@@ -0,0 +1,80 @@
+#ifndef LLMR_TEXT_GLYPH_STORE
+#define LLMR_TEXT_GLYPH_STORE
+
+#include <llmr/text/glyph.hpp>
+#include <llmr/util/pbf.hpp>
+
+#include <cstdint>
+#include <vector>
+#include <future>
+#include <map>
+#include <set>
+#include <unordered_map>
+
+namespace llmr {
+
+
+class SDFGlyph {
+public:
+ uint32_t id = 0;
+
+ // A signed distance field of the glyph with a border of 3 pixels.
+ std::string bitmap;
+
+ // Glyph metrics
+ GlyphMetrics metrics;
+};
+
+class FontStack {
+public:
+ void insert(uint32_t id, const SDFGlyph &glyph);
+ const std::map<uint32_t, GlyphMetrics> &getMetrics() const;
+ const std::map<uint32_t, SDFGlyph> &getSDFs() const;
+ const Shaping getShaping(const std::u32string &string) const;
+
+private:
+ std::map<uint32_t, std::string> bitmaps;
+ std::map<uint32_t, GlyphMetrics> metrics;
+ std::map<uint32_t, SDFGlyph> sdfs;
+ mutable std::mutex mtx;
+};
+
+class GlyphPBF {
+public:
+ GlyphPBF(const std::string &fontStack, GlyphRange glyphRange);
+
+ void parse(FontStack &stack);
+
+ std::shared_future<GlyphPBF &> getFuture();
+
+private:
+ std::string data;
+ std::promise<GlyphPBF &> promise;
+ std::shared_future<GlyphPBF &> future;
+ std::mutex mtx;
+};
+
+// Manages Glyphrange PBF loading.
+class GlyphStore {
+public:
+ // Block until all specified GlyphRanges of the specified font stack are loaded.
+ void waitForGlyphRanges(const std::string &fontStack, const std::set<GlyphRange> &glyphRanges);
+
+ FontStack &getFontStack(const std::string &fontStack);
+
+private:
+ // Loads an individual glyph range from the font stack and adds it to rangeSets
+ std::shared_future<GlyphPBF &> loadGlyphRange(const std::string &fontStack, std::map<GlyphRange, std::unique_ptr<GlyphPBF>> &rangeSets, GlyphRange range);
+
+ FontStack &createFontStack(const std::string &fontStack);
+
+private:
+ std::unordered_map<std::string, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>> ranges;
+ std::unordered_map<std::string, std::unique_ptr<FontStack>> stacks;
+ std::mutex mtx;
+};
+
+
+}
+
+#endif
diff --git a/include/llmr/text/placement.hpp b/include/llmr/text/placement.hpp
index 8ec7df5e4f..87c47345ec 100644
--- a/include/llmr/text/placement.hpp
+++ b/include/llmr/text/placement.hpp
@@ -18,9 +18,9 @@ public:
void addFeature(TextBucket &bucket, const std::vector<Coordinate> &line,
const BucketGeometryDescription &info,
- const IndexedFaces &faces,
+ const GlyphPositions &face,
const Shaping &shaping);
- float measureText(const IndexedFaces &faces,
+ float measureText(const GlyphPositions &face,
const Shaping &shaping);
private:
diff --git a/include/llmr/util/constants.hpp b/include/llmr/util/constants.hpp
index 70befcb379..f315e5171b 100644
--- a/include/llmr/util/constants.hpp
+++ b/include/llmr/util/constants.hpp
@@ -19,6 +19,11 @@ extern const bool styleParseWarnings;
extern const bool spriteWarnings;
extern const bool renderWarnings;
extern const bool renderTree;
+extern const bool labelTextMissingWarning;
+extern const bool missingFontStackWarning;
+extern const bool missingFontFaceWarning;
+extern const bool glyphWarning;
+extern const bool shapingWarning;
}
diff --git a/include/llmr/util/utf.hpp b/include/llmr/util/utf.hpp
new file mode 100644
index 0000000000..92da93f018
--- /dev/null
+++ b/include/llmr/util/utf.hpp
@@ -0,0 +1,45 @@
+#ifndef LLMR_UTIL_UTF
+#define LLMR_UTIL_UTF
+
+#include <memory>
+
+// g++/libstdc++ is missing c++11 codecvt support
+#ifdef __linux__
+#include <boost/locale.hpp>
+#else
+#include <codecvt>
+#include <locale>
+#endif
+
+namespace llmr {
+
+namespace util {
+
+#ifdef __linux__
+
+class utf8_to_utf32 {
+ public:
+ explicit utf8_to_utf32() {}
+ std::u32string convert(std::string const& utf8) {
+ return boost::locale::conv::utf_to_utf<char32_t>(utf8);
+ }
+};
+
+#else
+
+class utf8_to_utf32 {
+ public:
+ explicit utf8_to_utf32()
+ : utf32conv_() {}
+ std::u32string convert(std::string const& utf8) {
+ return utf32conv_.from_bytes(utf8);
+ }
+ private:
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv_;
+};
+
+#endif
+
+}}
+
+#endif