diff options
author | Anand Thakker <anandthakker@users.noreply.github.com> | 2017-04-06 15:29:59 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-06 15:29:59 -0400 |
commit | 693c9f3641b3189b4cd439049904c95a516ae609 (patch) | |
tree | 8341a16f57ff184a2fe9e085c490e8762eb206ce /src/mbgl/layout | |
parent | f9cc044357d60dd5cf15ba951384529f88802089 (diff) | |
download | qtlocation-mapboxgl-693c9f3641b3189b4cd439049904c95a516ae609.tar.gz |
[core] Add DDS support for {text,icon}-size (#8593)
* Update gl-js and generate style code
* Factor out packUint8Pair() helper function
* Draft implementation of DDS for {text,icon}-size
Ports https://github.com/mapbox/mapbox-gl-js/pull/4455
* Fix text-size/composite-function-line-placement test
* Refactor to PaintPropertyBinders-like strategy
* Dedupe gl::Program construction
* Use exponential function base for interpolation
* Dedupe coveringZoomStops method
* Fixup tests
* Fix CI errors (hidden within #if block)
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r-- | src/mbgl/layout/symbol_instance.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 43 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 17 |
4 files changed, 49 insertions, 20 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 8bdc528bbb..2a3bf068c1 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -10,6 +10,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const std::pair<Shaping, Shaping>& shapedTextOrientations, const PositionedIcon& shapedIcon, const SymbolLayoutProperties::Evaluated& layout, + const float layoutTextSize, const bool addToBuffers, const uint32_t index_, const float textBoxScale, @@ -26,15 +27,18 @@ SymbolInstance::SymbolInstance(Anchor& anchor, hasText(shapedTextOrientations.first || shapedTextOrientations.second), hasIcon(shapedIcon), + // Create the collision features that will be used to check whether this symbol instance can be placed textCollisionFeature(line, anchor, shapedTextOrientations.second ?: shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature), iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconPlacement, indexedFeature), featureIndex(featureIndex_) { + + // Create the quads used for rendering the icon and glyphs. if (addToBuffers) { if (shapedIcon) { - iconQuad = getIconQuad(anchor, shapedIcon, line, layout, iconPlacement, shapedTextOrientations.first); + iconQuad = getIconQuad(anchor, shapedIcon, line, layout, layoutTextSize, iconPlacement, shapedTextOrientations.first); } if (shapedTextOrientations.first) { auto quads = getGlyphQuads(anchor, shapedTextOrientations.first, textBoxScale, line, layout, textPlacement, face); @@ -55,6 +59,8 @@ SymbolInstance::SymbolInstance(Anchor& anchor, } else { writingModes = WritingModeType::None; } + + } } // namespace mbgl diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 70ebfeefa2..efe6cb05aa 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -17,6 +17,7 @@ public: const std::pair<Shaping, Shaping>& shapedTextOrientations, const PositionedIcon& shapedIcon, const style::SymbolLayoutProperties::Evaluated&, + const float layoutTextSize, const bool inside, const uint32_t index, const float textBoxScale, diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 978caabd70..907e60a598 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -50,7 +50,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, mode(parameters.mode), spriteAtlasMapIndex(_spriteAtlasMapIndex), tileSize(util::tileSize * overscaling), - tilePixelRatio(float(util::EXTENT) / tileSize) { + tilePixelRatio(float(util::EXTENT) / tileSize), + textSize(layers.at(0)->as<SymbolLayer>()->impl->layout.unevaluated.get<TextSize>()), + iconSize(layers.at(0)->as<SymbolLayer>()->impl->layout.unevaluated.get<IconSize>()) + { const SymbolLayer::Impl& leader = *layers.at(0)->as<SymbolLayer>()->impl; @@ -77,11 +80,6 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, layout.get<TextPitchAlignment>() = layout.get<TextRotationAlignment>(); } - textMaxSize = leader.layout.evaluate<TextSize>(PropertyEvaluationParameters(18)); - - layout.get<IconSize>() = leader.layout.evaluate<IconSize>(PropertyEvaluationParameters(zoom + 1)); - layout.get<TextSize>() = leader.layout.evaluate<TextSize>(PropertyEvaluationParameters(zoom + 1)); - const bool hasText = has<TextField>(layout) && !layout.get<TextFont>().empty(); const bool hasIcon = has<IconImage>(layout); @@ -298,11 +296,20 @@ void SymbolLayout::addFeature(const std::size_t index, const GlyphPositions& glyphs) { const float minScale = 0.5f; const float glyphSize = 24.0f; - - const float fontScale = layout.get<TextSize>() / glyphSize; + + const float layoutTextSize = layout.evaluate<TextSize>(zoom + 1, feature); + const float layoutIconSize = layout.evaluate<IconSize>(zoom + 1, feature); + + // To reduce the number of labels that jump around when zooming we need + // to use a text-size value that is the same for all zoom levels. + // This calculates text-size at a high zoom level so that all tiles can + // use the same value when calculating anchor positions. + const float textMaxSize = layout.evaluate<TextSize>(18, feature); + + const float fontScale = layoutTextSize / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize; - const float iconBoxScale = tilePixelRatio * layout.get<IconSize>(); + const float iconBoxScale = tilePixelRatio * layoutIconSize; const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>(); const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line; const float textPadding = layout.get<TextPadding>() * tilePixelRatio; @@ -316,7 +323,7 @@ void SymbolLayout::addFeature(const std::size_t index, : layout.get<SymbolPlacement>(); const float textRepeatDistance = symbolSpacing / 2; IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, bucketName, symbolInstances.size()}; - + auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) { // https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers // +-------------------+ Symbols with anchors located on tile edges @@ -338,7 +345,9 @@ void SymbolLayout::addFeature(const std::size_t index, const bool addToBuffers = mode == MapMode::Still || withinPlus0; - symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout.evaluate(zoom, feature), addToBuffers, symbolInstances.size(), + symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, + layout.evaluate(zoom, feature), layoutTextSize, + addToBuffers, symbolInstances.size(), textBoxScale, textPadding, textPlacement, iconBoxScale, iconPadding, iconPlacement, glyphs, indexedFeature, index); @@ -413,7 +422,7 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe } std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) { - auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, zoom, sdfIcons, iconsNeedLinear); + auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear); // Calculate which labels can be shown and when they can be shown and // create the bufers used for rendering. @@ -477,6 +486,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) iconScale = util::max(iconScale, glyphScale); } + const auto& feature = features.at(symbolInstance.featureIndex); // Insert final placement into collision tree and add glyphs/icons to buffers @@ -486,7 +496,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) if (glyphScale < collisionTile.maxScale) { for (const auto& symbol : symbolInstance.glyphQuads) { addSymbol( - bucket->text, symbol, placementZoom, + bucket->text, *bucket->textSizeBinder, symbol, feature, placementZoom, keepUpright, textPlacement, collisionTile.config.angle, symbolInstance.writingModes); } } @@ -497,12 +507,11 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get<IconIgnorePlacement>()); if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad) { addSymbol( - bucket->icon, *symbolInstance.iconQuad, placementZoom, + bucket->icon, *bucket->iconSizeBinder, *symbolInstance.iconQuad, feature, placementZoom, keepUpright, iconPlacement, collisionTile.config.angle, symbolInstance.writingModes); } } - const auto& feature = features.at(symbolInstance.featureIndex); for (auto& pair : bucket->paintPropertyBinders) { pair.second.first.populateVertexVectors(feature, bucket->icon.vertices.vertexSize()); pair.second.second.populateVertexVectors(feature, bucket->text.vertices.vertexSize()); @@ -518,7 +527,9 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) template <typename Buffer> void SymbolLayout::addSymbol(Buffer& buffer, + SymbolSizeBinder& sizeBinder, const SymbolQuad& symbol, + const SymbolFeature& feature, const float placementZoom, const bool keepUpright, const style::SymbolPlacementType placement, @@ -580,6 +591,8 @@ void SymbolLayout::addSymbol(Buffer& buffer, minZoom, maxZoom, placementZoom, glyphAngle)); buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, tex.x + tex.w, tex.y + tex.h, minZoom, maxZoom, placementZoom, glyphAngle)); + + sizeBinder.populateVertexVector(feature); // add the two triangles, referencing the four coordinates we just inserted. buffer.triangles.emplace_back(index + 0, index + 1, index + 2); diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index d79ccb3273..4ec84f0f58 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -6,6 +6,7 @@ #include <mbgl/layout/symbol_instance.hpp> #include <mbgl/text/bidi.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> +#include <mbgl/programs/symbol_program.hpp> #include <memory> #include <map> @@ -64,9 +65,15 @@ private: // Adds placed items to the buffer. template <typename Buffer> - void addSymbol(Buffer&, const SymbolQuad&, float scale, - const bool keepUpright, const style::SymbolPlacementType, const float placementAngle, - WritingModeType writingModes); + void addSymbol(Buffer&, + SymbolSizeBinder& sizeBinder, + const SymbolQuad&, + const SymbolFeature& feature, + float scale, + const bool keepUpright, + const style::SymbolPlacementType, + const float placementAngle, + WritingModeType writingModes); const std::string sourceLayerName; const std::string bucketName; @@ -75,7 +82,6 @@ private: const MapMode mode; style::SymbolLayoutProperties::PossiblyEvaluated layout; - float textMaxSize; uintptr_t spriteAtlasMapIndex; // Actually a pointer to the SpriteAtlas for this symbol's layer, but don't use it from worker threads! @@ -84,6 +90,9 @@ private: bool sdfIcons = false; bool iconsNeedLinear = false; + + style::TextSize::UnevaluatedType textSize; + style::IconSize::UnevaluatedType iconSize; std::vector<SymbolInstance> symbolInstances; std::vector<SymbolFeature> features; |