[core] fix collisions with icon-text-fit and variable placement (#15828)

port 61a61a1982cb8c637d467f91da5b0817a61a9de6
This commit is contained in:
Ansis Brammanis
2019-10-22 20:30:55 -04:00
committed by GitHub
parent b1d048217a
commit 99feb9bb30
2 changed files with 50 additions and 11 deletions

View File

@@ -220,7 +220,6 @@ void Placement::placeBucket(
if (horizontalTextIndex) {
const PlacedSymbol& placedSymbol = bucket.text.placedSymbols.at(*horizontalTextIndex);
const float fontSize = evaluateSizeForFeature(partiallyEvaluatedTextSize, placedSymbol);
const CollisionFeature& textCollisionFeature = symbolInstance.textCollisionFeature;
const auto updatePreviousOrientationIfNotPlaced = [&](bool isPlaced) {
if (bucket.allowVerticalPlacement && !isPlaced && getPrevPlacement()) {
@@ -282,7 +281,8 @@ void Placement::placeBucket(
placeText = placed.first;
offscreen &= placed.second;
} else if (!textCollisionFeature.alongLine && !textCollisionFeature.boxes.empty()) {
} else if (!symbolInstance.textCollisionFeature.alongLine &&
!symbolInstance.textCollisionFeature.boxes.empty()) {
// If this symbol was in the last placement, shift the previously used
// anchor to the front of the anchor list, only if the previous anchor
// is still in the anchor list.
@@ -305,8 +305,13 @@ void Placement::placeBucket(
}
}
const auto placeFeatureForVariableAnchors = [&] (const CollisionFeature& collisionFeature, style::TextWritingModeType orientation) {
const CollisionBox& textBox = collisionFeature.boxes[0];
const bool doVariableIconPlacement =
hasIconTextFit && !iconAllowOverlap && symbolInstance.placedIconIndex;
const auto placeFeatureForVariableAnchors = [&](const CollisionFeature& textCollisionFeature,
style::TextWritingModeType orientation,
const CollisionFeature& iconCollisionFeature) {
const CollisionBox& textBox = textCollisionFeature.boxes[0];
const float width = textBox.x2 - textBox.x1;
const float height = textBox.y2 - textBox.y1;
const float textBoxScale = symbolInstance.textBoxScale;
@@ -323,12 +328,40 @@ void Placement::placeBucket(
}
textBoxes.clear();
placedFeature = collisionIndex.placeFeature(collisionFeature, shift,
posMatrix, mat4(), pixelRatio,
placedSymbol, scale, fontSize,
placedFeature = collisionIndex.placeFeature(textCollisionFeature,
shift,
posMatrix,
mat4(),
pixelRatio,
placedSymbol,
scale,
fontSize,
allowOverlap,
pitchWithMap,
params.showCollisionBoxes, avoidEdges, collisionGroup.second, textBoxes);
params.showCollisionBoxes,
avoidEdges,
collisionGroup.second,
textBoxes);
if (doVariableIconPlacement) {
auto placedIconFeature = collisionIndex.placeFeature(iconCollisionFeature,
shift,
posMatrix,
iconLabelPlaneMatrix,
pixelRatio,
placedSymbol,
scale,
fontSize,
iconAllowOverlap,
pitchWithMap,
params.showCollisionBoxes,
avoidEdges,
collisionGroup.second,
iconBoxes);
iconBoxes.clear();
if (!placedIconFeature.first) continue;
}
if (placedFeature.first) {
assert(symbolInstance.crossTileID != 0u);
optional<style::TextVariableAnchorType> prevAnchor;
@@ -366,12 +399,18 @@ void Placement::placeBucket(
};
const auto placeHorizontal = [&] {
return placeFeatureForVariableAnchors(symbolInstance.textCollisionFeature, style::TextWritingModeType::Horizontal);
return placeFeatureForVariableAnchors(symbolInstance.textCollisionFeature,
style::TextWritingModeType::Horizontal,
symbolInstance.iconCollisionFeature);
};
const auto placeVertical = [&] {
if (bucket.allowVerticalPlacement && !placed.first && symbolInstance.verticalTextCollisionFeature) {
return placeFeatureForVariableAnchors(*symbolInstance.verticalTextCollisionFeature, style::TextWritingModeType::Vertical);
return placeFeatureForVariableAnchors(*symbolInstance.verticalTextCollisionFeature,
style::TextWritingModeType::Vertical,
symbolInstance.verticalIconCollisionFeature
? *symbolInstance.verticalIconCollisionFeature
: symbolInstance.iconCollisionFeature);
}
return std::pair<bool, bool>{false, false};
};