From 693c9f3641b3189b4cd439049904c95a516ae609 Mon Sep 17 00:00:00 2001 From: Anand Thakker Date: Thu, 6 Apr 2017 15:29:59 -0400 Subject: [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) --- src/mbgl/layout/symbol_layout.cpp | 43 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'src/mbgl/layout/symbol_layout.cpp') 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()->impl->layout.unevaluated.get()), + iconSize(layers.at(0)->as()->impl->layout.unevaluated.get()) + { const SymbolLayer::Impl& leader = *layers.at(0)->as()->impl; @@ -77,11 +80,6 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, layout.get() = layout.get(); } - textMaxSize = leader.layout.evaluate(PropertyEvaluationParameters(18)); - - layout.get() = leader.layout.evaluate(PropertyEvaluationParameters(zoom + 1)); - layout.get() = leader.layout.evaluate(PropertyEvaluationParameters(zoom + 1)); - const bool hasText = has(layout) && !layout.get().empty(); const bool hasIcon = has(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() / glyphSize; + + const float layoutTextSize = layout.evaluate(zoom + 1, feature); + const float layoutIconSize = layout.evaluate(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(18, feature); + + const float fontScale = layoutTextSize / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize; - const float iconBoxScale = tilePixelRatio * layout.get(); + const float iconBoxScale = tilePixelRatio * layoutIconSize; const float symbolSpacing = tilePixelRatio * layout.get(); const bool avoidEdges = layout.get() && layout.get() != SymbolPlacementType::Line; const float textPadding = layout.get() * tilePixelRatio; @@ -316,7 +323,7 @@ void SymbolLayout::addFeature(const std::size_t index, : layout.get(); 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 SymbolLayout::place(CollisionTile& collisionTile) { - auto bucket = std::make_unique(layout, layerPaintProperties, zoom, sdfIcons, iconsNeedLinear); + auto bucket = std::make_unique(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 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 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 SymbolLayout::place(CollisionTile& collisionTile) collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get()); 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 SymbolLayout::place(CollisionTile& collisionTile) template 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); -- cgit v1.2.1