#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include class GlyphAtlasTest; namespace mbgl { class FileSource; class AsyncRequest; class Response; namespace gl { class Context; } // namespace gl class GlyphRequestor { public: virtual void onGlyphsAvailable(GlyphPositionMap) = 0; }; class GlyphAtlas : public util::noncopyable { public: GlyphAtlas(Size, FileSource&); ~GlyphAtlas(); // Workers send a `getGlyphs` message to the main thread once they have determined // which glyphs they will need. Invoking this method will increment reference // counts for all the glyphs in `GlyphDependencies`. If all glyphs are already // locally available, the observer will be notified that the glyphs are available // immediately. Otherwise, a request on the FileSource is made, and when all glyphs // are parsed and added to the atlas, the observer will be notified. // Workers are given a copied 'GlyphPositions' map to use for placing their glyphs. // The positions specified in this object are guaranteed to be // valid for the lifetime of the tile. void getGlyphs(GlyphRequestor&, GlyphDependencies); void removeGlyphs(GlyphRequestor&); void setURL(const std::string& url) { glyphURL = url; } void setObserver(GlyphAtlasObserver*); // Binds the atlas texture to the GPU, and uploads data if it is out of date. void bind(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; private: FileSource& fileSource; std::string glyphURL; struct GlyphValue { AlphaImage bitmap; GlyphMetrics metrics; optional> rect; std::unordered_set ids; }; struct GlyphRequest { bool parsed = false; std::unique_ptr req; std::unordered_map> requestors; }; struct Entry { std::map ranges; std::map glyphs; }; std::unordered_map entries; GlyphRequest& requestRange(Entry&, const FontStack&, const GlyphRange&); void processResponse(const Response&, const FontStack&, const GlyphRange&); void addGlyphs(GlyphRequestor&, const GlyphDependencies&); Rect addGlyph(GlyphValue&); void removeGlyphValues(GlyphRequestor&, std::map&); void removePendingRanges(GlyphRequestor&, std::map&); GlyphAtlasObserver* observer = nullptr; BinPack bin; AlphaImage image; bool dirty; mbgl::optional texture; }; } // namespace mbgl