diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/painter_symbol.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.cpp | 34 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/text/quads.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/text/shaping.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/text/shaping.hpp | 14 |
8 files changed, 45 insertions, 35 deletions
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 43cd3d5405..9f2d06df22 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -187,8 +187,9 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const const float fontScale = fontSize / 1.0f; SpriteAtlas* activeSpriteAtlas = layer.spriteAtlas; - activeSpriteAtlas->bind(state.isChanging() || layout.placement == PlacementType::Line - || angleOffset != 0 || fontScale != 1 || sdf || state.getPitch() != 0); + const bool iconScaled = fontScale != 1 || data.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear; + const bool iconTransformed = layout.placement == PlacementType::Line || angleOffset != 0 || state.getPitch() != 0; + activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed); if (sdf) { renderSDF(bucket, diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index d8273fd4f8..67539637bc 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -248,11 +248,14 @@ void SymbolBucket::addFeatures(uintptr_t tileUID, if (feature.sprite.length()) { auto image = spriteAtlas.getImage(feature.sprite, false); if (image) { - shapedIcon = shapeIcon((*image).pos, layout); + shapedIcon = shapeIcon(*image, layout); assert((*image).texture); if ((*image).texture->sdf) { sdfIcons = true; } + if ((*image).relativePixelRatio != 1.0f) { + iconsNeedLinear = true; + } } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index b447db4ec9..4f52f2300b 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -112,6 +112,7 @@ private: public: SymbolLayoutProperties layout; bool sdfIcons = false; + bool iconsNeedLinear = false; private: diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index d09330e17b..a20f6f0fe3 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -27,7 +27,11 @@ SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, float pixelRatio_, dirty(true) { } -Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const size_t pixel_width, const size_t pixel_height) { +Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(float src_width, float src_height) { + + const uint16_t pixel_width = std::ceil(src_width / pixelRatio); + const uint16_t pixel_height = std::ceil(src_height / pixelRatio); + // Increase to next number divisible by 4, but at least 1. // This is so we can scale down the texture coordinates and pack them // into 2 bytes rather than 4 bytes. @@ -52,7 +56,7 @@ mapbox::util::optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::stri auto rect_it = images.find({ name, wrap }); if (rect_it != images.end()) { - return SpriteAtlasElement { rect_it->second.pos, rect_it->second.texture }; + return SpriteAtlasElement { rect_it->second.pos, rect_it->second.texture, rect_it->second.texture->pixelRatio / pixelRatio }; } auto sprite = store.getSprite(name); @@ -60,7 +64,7 @@ mapbox::util::optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::stri return {}; } - Rect<dimension> rect = allocateImage(sprite->width, sprite->height); + Rect<dimension> rect = allocateImage(sprite->width * sprite->pixelRatio, sprite->height * sprite->pixelRatio); if (rect.w == 0) { if (debug::spriteWarnings) { Log::Warning(Event::Sprite, "sprite atlas bitmap overflow"); @@ -71,7 +75,7 @@ mapbox::util::optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::stri const Holder& holder = images.emplace(Key{ name, wrap }, Holder{ sprite, rect }).first->second; copy(holder, wrap); - return SpriteAtlasElement { rect, sprite }; + return SpriteAtlasElement { rect, sprite, sprite->pixelRatio / pixelRatio }; } mapbox::util::optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name, bool repeating) { @@ -83,25 +87,17 @@ mapbox::util::optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std:: } auto rect = (*img).pos; - if (repeating) { - // When the image is repeating, get the correct position of the image, rather than the - // one rounded up to 4 pixels. - // TODO: Can't we just use originalW/originalH? - auto sprite = store.getSprite(name); - if (!sprite) { - return SpriteAtlasPosition {}; - } - - rect.w = sprite->width; - rect.h = sprite->height; - } const float padding = 1; + auto image = (*img).texture; + + const float w = image->width * (*img).relativePixelRatio; + const float h = image->height * (*img).relativePixelRatio; return SpriteAtlasPosition { - {{ float(rect.w), float(rect.h) }}, - {{ float(rect.x + padding) / width, float(rect.y + padding) / height }}, - {{ float(rect.x + padding + rect.w) / width, float(rect.y + padding + rect.h) / height }} + {{ float(image->width), float(image->height) }}, + {{ float(rect.x + padding) / width, float(rect.y + padding) / height }}, + {{ float(rect.x + padding + w) / width, float(rect.y + padding + h) / height }} }; } diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index 167d012c6b..aca82b3fea 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -34,6 +34,7 @@ struct SpriteAtlasPosition { struct SpriteAtlasElement { const Rect<uint16_t> pos; const std::shared_ptr<const SpriteImage> texture; + const float relativePixelRatio; }; class SpriteAtlas : public util::noncopyable { @@ -83,7 +84,7 @@ private: using Key = std::pair<std::string, bool>; - Rect<SpriteAtlas::dimension> allocateImage(size_t width, size_t height); + Rect<SpriteAtlas::dimension> allocateImage(float width, float height); void copy(const Holder& holder, const bool wrap); std::recursive_mutex mtx; diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 20427924a4..92866566d8 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -13,11 +13,13 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, const std::vector<Coordinate>& line, const SymbolLayoutProperties& layout, const bool alongLine) { + auto image = *(shapedIcon.image); + const float border = 1.0; auto left = shapedIcon.left - border; - auto right = left + shapedIcon.image.w; + auto right = left + image.pos.w / image.relativePixelRatio; auto top = shapedIcon.top - border; - auto bottom = top + shapedIcon.image.h; + auto bottom = top + image.pos.h / image.relativePixelRatio; vec2<float> tl{left, top}; vec2<float> tr{right, top}; vec2<float> br{right, bottom}; @@ -51,7 +53,7 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, } SymbolQuads quads; - quads.emplace_back(tl, tr, bl, br, shapedIcon.image, 0, anchor, globalMinScale, std::numeric_limits<float>::infinity()); + quads.emplace_back(tl, tr, bl, br, image.pos, 0, anchor, globalMinScale, std::numeric_limits<float>::infinity()); return quads; } diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 735841e8ca..f12658c669 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -3,13 +3,13 @@ namespace mbgl { -PositionedIcon shapeIcon(const Rect<uint16_t>& image, const SymbolLayoutProperties& layout) { +PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties& layout) { float dx = layout.icon.offset.value[0]; float dy = layout.icon.offset.value[1]; - float x1 = dx - image.originalW / 2.0f; - float x2 = x1 + image.originalW; - float y1 = dy - image.originalH / 2.0f; - float y2 = y1 + image.originalH; + float x1 = dx - image.texture->width / 2.0f; + float x2 = x1 + image.texture->width; + float y1 = dy - image.texture->height / 2.0f; + float y2 = y1 + image.texture->height; return PositionedIcon(image, y1, y2, x1, x2); } diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index acf8c470bf..decf7b946e 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -2,29 +2,35 @@ #define MBGL_TEXT_SHAPING #include <mbgl/text/glyph.hpp> +#include <mbgl/sprite/sprite_atlas.hpp> +#include <mbgl/sprite/sprite_image.hpp> +#include <mapbox/optional.hpp> #include <mbgl/util/vec.hpp> namespace mbgl { + struct SpriteAtlasElement; + class PositionedIcon { public: inline explicit PositionedIcon() {} - inline explicit PositionedIcon(Rect<uint16_t> _image, + inline explicit PositionedIcon(const SpriteAtlasElement& _image, float _top, float _bottom, float _left, float _right) : image(_image), top(_top), bottom(_bottom), left(_left), right(_right) {} - Rect<uint16_t> image; + + mapbox::util::optional<SpriteAtlasElement> image; float top = 0; float bottom = 0; float left = 0; float right = 0; - operator bool() const { return image.hasArea(); } + operator bool() const { return image && (*image).pos.hasArea(); } }; class SymbolLayoutProperties; - PositionedIcon shapeIcon(const Rect<uint16_t>& image, const SymbolLayoutProperties&); + PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties&); } // namespace mbgl |