diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/llmr/geometry/glyph_atlas.hpp | 3 | ||||
-rw-r--r-- | include/llmr/map/map.hpp | 3 | ||||
-rw-r--r-- | include/llmr/map/tile.hpp | 1 | ||||
-rw-r--r-- | include/llmr/map/tile_parser.hpp | 8 | ||||
-rw-r--r-- | include/llmr/map/vector_tile_data.hpp | 4 | ||||
-rw-r--r-- | include/llmr/platform/gl.hpp | 2 | ||||
-rw-r--r-- | include/llmr/platform/platform.hpp | 4 | ||||
-rw-r--r-- | include/llmr/renderer/bucket.hpp | 1 | ||||
-rw-r--r-- | include/llmr/renderer/prerendered_texture.hpp | 1 | ||||
-rw-r--r-- | include/llmr/renderer/text_bucket.hpp | 3 | ||||
-rw-r--r-- | include/llmr/style/properties.hpp | 1 | ||||
-rw-r--r-- | include/llmr/style/style_parser.hpp | 2 | ||||
-rw-r--r-- | include/llmr/text/collision.hpp | 2 | ||||
-rw-r--r-- | include/llmr/text/glyph.hpp | 5 | ||||
-rw-r--r-- | include/llmr/text/glyph_store.hpp | 80 | ||||
-rw-r--r-- | include/llmr/text/placement.hpp | 4 | ||||
-rw-r--r-- | include/llmr/util/constants.hpp | 5 | ||||
-rw-r--r-- | include/llmr/util/utf.hpp | 45 |
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 |