diff options
Diffstat (limited to 'src/mbgl/layout/symbol_layout.cpp')
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 101 |
1 files changed, 78 insertions, 23 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 0ee4143894..1dbb5d91dc 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -91,11 +91,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, pixelRatio(parameters.pixelRatio), tileSize(util::tileSize * overscaling), tilePixelRatio(float(util::EXTENT) / tileSize), - textSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<TextSize>()), - iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<IconSize>()), layout(createLayout(toSymbolLayerProperties(layers.at(0)).layerImpl().layout, zoom)) { const SymbolLayer::Impl& leader = toSymbolLayerProperties(layers.at(0)).layerImpl(); + textSize = leader.layout.get<TextSize>(); + iconSize = leader.layout.get<IconSize>(); + textRadialOffset = leader.layout.get<TextRadialOffset>(); + const bool hasText = has<TextField>(*layout) && has<TextFont>(*layout); const bool hasIcon = has<IconImage>(*layout); @@ -235,11 +237,9 @@ Shaping& shapingForTextJustifyType(ShapedTextOrientations& shapedTextOrientation } } -} // namespace - -// static -Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float radialOffset) { - Point<float> result{}; +std::array<float, 2> evaluateRadialOffset(style::SymbolAnchorType anchor, float radialOffset) { + std::array<float, 2> result{{0.0f, 0.0f}}; + if (radialOffset < 0.0f) radialOffset = 0.0f; // Ignore negative offset. // solve for r where r^2 + r^2 = radialOffset^2 const float sqrt2 = 1.41421356237f; const float hypotenuse = radialOffset / sqrt2; @@ -247,17 +247,17 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r switch (anchor) { case SymbolAnchorType::TopRight: case SymbolAnchorType::TopLeft: - result.y = hypotenuse - baselineOffset; + result[1] = hypotenuse - baselineOffset; break; case SymbolAnchorType::BottomRight: case SymbolAnchorType::BottomLeft: - result.y = -hypotenuse + baselineOffset; + result[1] = -hypotenuse + baselineOffset; break; case SymbolAnchorType::Bottom: - result.y = -radialOffset + baselineOffset; + result[1] = -radialOffset + baselineOffset; break; case SymbolAnchorType::Top: - result.y = radialOffset - baselineOffset; + result[1] = radialOffset - baselineOffset; break; default: break; @@ -266,17 +266,17 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r switch (anchor) { case SymbolAnchorType::TopRight: case SymbolAnchorType::BottomRight: - result.x = -hypotenuse; + result[0] = -hypotenuse; break; case SymbolAnchorType::TopLeft: case SymbolAnchorType::BottomLeft: - result.x = hypotenuse; + result[0] = hypotenuse; break; case SymbolAnchorType::Left: - result.x = radialOffset; + result[0] = radialOffset; break; case SymbolAnchorType::Right: - result.x = -radialOffset; + result[0] = -radialOffset; break; default: break; @@ -285,6 +285,54 @@ Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r return result; } +} // namespace + +// static +std::array<float, 2> SymbolLayout::evaluateVariableOffset(style::SymbolAnchorType anchor, std::array<float, 2> offset) { + if (offset[1] == INVALID_OFFSET_VALUE) { + return evaluateRadialOffset(anchor, offset[0]); + } + std::array<float, 2> result{{0.0f, 0.0f}}; + offset[0] = std::abs(offset[0]); + offset[1] = std::abs(offset[1]); + + switch (anchor) { + case SymbolAnchorType::TopRight: + case SymbolAnchorType::TopLeft: + case SymbolAnchorType::Top: + result[1] = offset[1] - baselineOffset; + break; + case SymbolAnchorType::BottomRight: + case SymbolAnchorType::BottomLeft: + case SymbolAnchorType::Bottom: + result[1] = -offset[1] + baselineOffset; + break; + case SymbolAnchorType::Center: + case SymbolAnchorType::Left: + case SymbolAnchorType::Right: + break; + } + + switch (anchor) { + case SymbolAnchorType::TopRight: + case SymbolAnchorType::BottomRight: + case SymbolAnchorType::Right: + result[0] = -offset[0]; + break; + case SymbolAnchorType::TopLeft: + case SymbolAnchorType::BottomLeft: + case SymbolAnchorType::Left: + result[0] = offset[0]; + break; + case SymbolAnchorType::Center: + case SymbolAnchorType::Top: + case SymbolAnchorType::Bottom: + break; + } + + return result; +} + void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions) { const bool isPointPlacement = layout->get<SymbolPlacement>() == SymbolPlacementType::Point; @@ -296,7 +344,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions ShapedTextOrientations shapedTextOrientations; optional<PositionedIcon> shapedIcon; - Point<float> textOffset; + std::array<float, 2> textOffset{{0.0f, 0.0f}}; // if feature has text, shape the text if (feature.formattedText) { @@ -320,18 +368,18 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions return result; }; const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout->evaluate<TextVariableAnchor>(zoom, feature); - const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature); const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature); if (variableTextAnchor.empty()) { // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector // is calculated at placement time instead of layout time + const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature); if (radialOffset > 0.0f) { // The style spec says don't use `text-offset` and `text-radial-offset` together // but doesn't actually specify what happens if you use both. We go with the radial offset. textOffset = evaluateRadialOffset(textAnchor, radialOffset * util::ONE_EM); } else { - textOffset = { layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, - layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}; + textOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, + layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}}; } } TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature); @@ -435,14 +483,13 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const ShapedTextOrientations& shapedTextOrientations, optional<PositionedIcon> shapedIcon, const GlyphPositions& glyphPositions, - Point<float> offset, + std::array<float, 2> textOffset, const SymbolContent iconType) { const float minScale = 0.5f; const float glyphSize = 24.0f; const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature); const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature); - const std::array<float, 2> textOffset = {{ offset.x, offset.y }}; const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature); @@ -462,7 +509,15 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float textMaxAngle = layout->get<TextMaxAngle>() * util::DEG2RAD; const float iconRotation = layout->evaluate<IconRotate>(zoom, feature); const float textRotation = layout->evaluate<TextRotate>(zoom, feature); - const float radialTextOffset = layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM; + std::array<float, 2> variableTextOffset; + if (!textRadialOffset.isUndefined()) { + variableTextOffset = {{layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM, + INVALID_OFFSET_VALUE}}; + } else { + variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, + layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}}; + } + const SymbolPlacementType textPlacement = layout->get<TextRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point : layout->get<SymbolPlacement>(); @@ -503,7 +558,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, iconBoxScale, iconPadding, iconOffset, indexedFeature, layoutFeatureIndex, feature.index, feature.formattedText ? feature.formattedText->rawText() : std::u16string(), - overscaling, iconRotation, textRotation, radialTextOffset, allowVerticalPlacement, iconType); + overscaling, iconRotation, textRotation, variableTextOffset, allowVerticalPlacement, iconType); } }; |