From f2b1ccda37ca8cd044a952e98e8171a37db556cd Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Tue, 21 Aug 2018 12:12:15 -0700 Subject: [core] Mark allow-overlap symbols visible even outside of collision grid. Fixes issue #12683. --- src/mbgl/text/placement.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 0747133bd2..48c58a962e 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -117,6 +117,25 @@ void Placement::placeLayerBucket( avoidEdges = collisionIndex.projectTileBoundaries(posMatrix); } + const bool textAllowOverlap = bucket.layout.get(); + const bool iconAllowOverlap = bucket.layout.get(); + // This logic is similar to the "defaultOpacityState" logic below in updateBucketOpacities + // If we know a symbol is always supposed to show, force it to be marked visible even if + // it wasn't placed into the collision index (because some or all of it was outside the range + // of the collision grid). + // There is a subtle edge case here we're accepting: + // Symbol A has text-allow-overlap: true, icon-allow-overlap: true, icon-optional: false + // A's icon is outside the grid, so doesn't get placed + // A's text would be inside grid, but doesn't get placed because of icon-optional: false + // We still show A because of the allow-overlap settings. + // Symbol B has allow-overlap: false, and gets placed where A's text would be + // On panning in, there is a short period when Symbol B and Symbol A will overlap + // This is the reverse of our normal policy of "fade in on pan", but should look like any other + // collision and hopefully not be too noticeable. + // See https://github.com/mapbox/mapbox-gl-native/issues/12683 + const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.get()); + const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.get()); + for (auto& symbolInstance : bucket.symbolInstances) { if (seenCrossTileIDs.count(symbolInstance.crossTileID) == 0) { @@ -187,7 +206,7 @@ void Placement::placeLayerBucket( placements.erase(symbolInstance.crossTileID); } - placements.emplace(symbolInstance.crossTileID, JointPlacement(placeText, placeIcon, offscreen || bucket.justReloaded)); + placements.emplace(symbolInstance.crossTileID, JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded)); seenCrossTileIDs.insert(symbolInstance.crossTileID); } } -- cgit v1.2.1