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/symbol_layout.cpp | |
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/symbol_layout.cpp')
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 43 |
1 files changed, 28 insertions, 15 deletions
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); |