From fbc9fe8c963ad116c81117bf0a9b7fe5d412adad Mon Sep 17 00:00:00 2001 From: zmiao Date: Wed, 17 Jul 2019 17:40:42 +0300 Subject: make symbol instance common data shared --- platform/glfw/glfw_view.cpp | 8 + platform/glfw/main.cpp | 8 +- src/mbgl/layout/symbol_instance.cpp | 175 ++++++----- src/mbgl/layout/symbol_instance.hpp | 82 ++--- src/mbgl/layout/symbol_layout.cpp | 445 ++++++++++++++++++---------- src/mbgl/renderer/buckets/symbol_bucket.cpp | 8 +- src/mbgl/text/cross_tile_symbol_index.cpp | 4 +- src/mbgl/text/placement.cpp | 28 +- 8 files changed, 464 insertions(+), 294 deletions(-) diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 43c4de9759..51044f1ca8 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -25,6 +25,8 @@ #include #include +#include + #if MBGL_USE_GLES2 #define GLFW_INCLUDE_ES2 #endif // MBGL_USE_GLES2 @@ -281,6 +283,12 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, }; view->animateRouteCallback(view->map); } break; + case GLFW_KEY_Y:{ + view->map->jumpTo(mbgl::CameraOptions().withZoom(18).withPitch(0).withBearing(0)); + }break; + case GLFW_KEY_M:{ + view->map->jumpTo(mbgl::CameraOptions().withZoom(22).withPitch(0).withBearing(0)); + }break; case GLFW_KEY_E: view->toggle3DExtrusions(!view->show3DExtrusions); break; diff --git a/platform/glfw/main.cpp b/platform/glfw/main.cpp index 3c1e50e196..e8d72a82a2 100644 --- a/platform/glfw/main.cpp +++ b/platform/glfw/main.cpp @@ -121,11 +121,12 @@ int main(int argc, char *argv[]) { style = std::string("file://") + style; } - map.jumpTo(mbgl::CameraOptions() + /*map.jumpTo(mbgl::CameraOptions() .withCenter(mbgl::LatLng {settings.latitude, settings.longitude}) .withZoom(settings.zoom) .withBearing(settings.bearing) - .withPitch(settings.pitch)); + .withPitch(settings.pitch));*/ + map.jumpTo(mbgl::CameraOptions().withCenter(mbgl::LatLng{43.5, -100}).withZoom(12).withPitch(0).withBearing(0)); map.setDebug(mbgl::MapDebugOptions(settings.debug)); view->setOnlineStatusCallback([&settings, fileSource]() { @@ -181,7 +182,8 @@ int main(int argc, char *argv[]) { } } - map.getStyle().loadURL(style); + map.getStyle().loadURL("http://0.0.0.0:8000/style.json"); + //map.getStyle().loadURL(style); view->run(); diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 809aa2f451..6e2cc5af0c 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -9,45 +9,36 @@ using namespace style; namespace { const Shaping& getAnyShaping(const ShapedTextOrientations& shapedTextOrientations) { - if (shapedTextOrientations.right) return shapedTextOrientations.right; - if (shapedTextOrientations.center) return shapedTextOrientations.center; - if (shapedTextOrientations.left) return shapedTextOrientations.left; - if (shapedTextOrientations.vertical) return shapedTextOrientations.vertical; + if (shapedTextOrientations.right) + return shapedTextOrientations.right; + if (shapedTextOrientations.center) + return shapedTextOrientations.center; + if (shapedTextOrientations.left) + return shapedTextOrientations.left; + if (shapedTextOrientations.vertical) + return shapedTextOrientations.vertical; return shapedTextOrientations.horizontal; } } // namespace -SymbolInstance::SymbolInstance(Anchor& anchor_, - GeometryCoordinates line_, - const ShapedTextOrientations& shapedTextOrientations, - optional shapedIcon, - const SymbolLayoutProperties::Evaluated& layout, - const float layoutTextSize, - const float textBoxScale_, - const float textPadding, - const SymbolPlacementType textPlacement, - const std::array textOffset_, - const float iconBoxScale, - const float iconPadding, - const std::array iconOffset_, - const GlyphPositions& positions, - const IndexedSubfeature& indexedFeature, - const std::size_t layoutFeatureIndex_, - const std::size_t dataFeatureIndex_, - std::u16string key_, - const float overscaling, - const float rotate, - float radialTextOffset_) : - anchor(anchor_), - line(line_), +SymbolInstanceCommonData::SymbolInstanceCommonData(const GeometryCoordinates& line_, + const ShapedTextOrientations& shapedTextOrientations, + optional shapedIcon, + const style::SymbolLayoutProperties::Evaluated& layout, + const float layoutTextSize, + const float textBoxScale_, + const style::SymbolPlacementType textPlacement, + const std::array textOffset_, + const std::array iconOffset_, + const GlyphPositions& positions, + const std::size_t layoutFeatureIndex_, + const std::size_t dataFeatureIndex_, + std::u16string key_, + float radialTextOffset_) + : line(line_), hasText(false), hasIcon(shapedIcon), - - // Create the collision features that will be used to check whether this symbol instance can be placed - // As a collision approximation, we can use either the vertical or any of the horizontal versions of the feature - textCollisionFeature(line_, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, rotate), - iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature, rotate), writingModes(WritingModeType::None), layoutFeatureIndex(layoutFeatureIndex_), dataFeatureIndex(dataFeatureIndex_), @@ -56,51 +47,93 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, key(std::move(key_)), textBoxScale(textBoxScale_), radialTextOffset(radialTextOffset_), - singleLine(shapedTextOrientations.singleLine) { - - // Create the quads used for rendering the icon and glyphs. - if (shapedIcon) { - iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal); - } - - bool singleLineInitialized = false; - const auto initHorizontalGlyphQuads = [&] (SymbolQuads& quads, const Shaping& shaping) { - writingModes |= WritingModeType::Horizontal; - if (!singleLine) { - quads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); - return; + singleLine(shapedTextOrientations.singleLine){ + + // Create the quads used for rendering the icon and glyphs. + if (shapedIcon) { + iconQuad = + getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal); } - if (!singleLineInitialized) { - rightJustifiedGlyphQuads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); - singleLineInitialized = true; + + bool singleLineInitialized = false; + const auto initHorizontalGlyphQuads = [&](SymbolQuads& quads, const Shaping& shaping) { + writingModes |= WritingModeType::Horizontal; + if (!singleLine) { + quads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); + return; + } + if (!singleLineInitialized) { + rightJustifiedGlyphQuads = + getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); + singleLineInitialized = true; + } + }; + + if (shapedTextOrientations.right) { + initHorizontalGlyphQuads(rightJustifiedGlyphQuads, shapedTextOrientations.right); } - }; - - if (shapedTextOrientations.right) { - initHorizontalGlyphQuads(rightJustifiedGlyphQuads, shapedTextOrientations.right); - } - - if (shapedTextOrientations.center) { - initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center); - } - - if (shapedTextOrientations.left) { - initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left); - } - - if (shapedTextOrientations.vertical) { - writingModes |= WritingModeType::Vertical; - verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions); + + if (shapedTextOrientations.center) { + initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center); + } + + if (shapedTextOrientations.left) { + initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left); + } + + if (shapedTextOrientations.vertical) { + writingModes |= WritingModeType::Vertical; + verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, + textPlacement, positions); + } + + // 'hasText' depends on finding at least one glyph in the shaping that's also in the + // GlyphPositionMap + hasText = !rightJustifiedGlyphQuads.empty() || !centerJustifiedGlyphQuads.empty() || + !leftJustifiedGlyphQuads.empty() || !verticalGlyphQuads.empty(); } - - // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap - hasText = !rightJustifiedGlyphQuads.empty() || !centerJustifiedGlyphQuads.empty() || !leftJustifiedGlyphQuads.empty() || !verticalGlyphQuads.empty(); + +SymbolInstance::SymbolInstance(const Anchor& anchor_, + std::shared_ptr data_, + const ShapedTextOrientations& shapedTextOrientations, + optional shapedIcon, + const float textPadding, + const style::SymbolPlacementType textPlacement, + const float iconBoxScale, + const float iconPadding, + const IndexedSubfeature& indexedFeature, + const float overscaling, + const float rotate) + : anchor(std::move(anchor_)), + commonData(std::move(data_)), + // Create the collision features that will be used to check whether this symbol instance can + // be placedc As a collision approximation, we can use either the vertical or any of the + // horizontal versions of the feature + textCollisionFeature(commonData->line, + anchor, + getAnyShaping(shapedTextOrientations), + commonData->textBoxScale, + textPadding, + textPlacement, + indexedFeature, + overscaling, + rotate), + iconCollisionFeature(commonData->line, + anchor, + shapedIcon, + iconBoxScale, + iconPadding, + indexedFeature, + rotate) { } optional SymbolInstance::getDefaultHorizontalPlacedTextIndex() const { - if (placedRightTextIndex) return placedRightTextIndex; - if (placedCenterTextIndex) return placedCenterTextIndex; - if (placedLeftTextIndex) return placedLeftTextIndex; + if (placedRightTextIndex) + return placedRightTextIndex; + if (placedCenterTextIndex) + return placedCenterTextIndex; + if (placedLeftTextIndex) + return placedLeftTextIndex; return nullopt; } } // namespace mbgl diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 95159deeb1..633233fa17 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -1,10 +1,9 @@ #pragma once -#include -#include -#include #include - +#include +#include +#include namespace mbgl { @@ -15,38 +14,29 @@ struct ShapedTextOrientations { Shaping horizontal; Shaping vertical; // The following are used with variable text placement on. - Shaping& right = horizontal; + Shaping& right = horizontal; Shaping center; Shaping left; bool singleLine = false; }; -class SymbolInstance { +class SymbolInstanceCommonData { public: - SymbolInstance(Anchor& anchor, - GeometryCoordinates line, - const ShapedTextOrientations& shapedTextOrientations, - optional shapedIcon, - const style::SymbolLayoutProperties::Evaluated&, - const float layoutTextSize, - const float textBoxScale, - const float textPadding, - style::SymbolPlacementType textPlacement, - const std::array textOffset, - const float iconBoxScale, - const float iconPadding, - const std::array iconOffset, - const GlyphPositions&, - const IndexedSubfeature&, - const std::size_t layoutFeatureIndex, - const std::size_t dataFeatureIndex, - std::u16string key, - const float overscaling, - const float rotate, - float radialTextOffset); - - optional getDefaultHorizontalPlacedTextIndex() const; - Anchor anchor; + SymbolInstanceCommonData(const GeometryCoordinates& line_, + const ShapedTextOrientations& shapedTextOrientations, + optional shapedIcon, + const style::SymbolLayoutProperties::Evaluated& layout, + const float layoutTextSize, + const float textBoxScale_, + const style::SymbolPlacementType textPlacement, + const std::array textOffset_, + const std::array iconOffset_, + const GlyphPositions& positions, + const std::size_t layoutFeatureIndex_, + const std::size_t dataFeatureIndex_, + std::u16string key_, + float radialTextOffset_); + GeometryCoordinates line; bool hasText; bool hasIcon; @@ -58,24 +48,42 @@ public: SymbolQuads verticalGlyphQuads; optional iconQuad; - CollisionFeature textCollisionFeature; - CollisionFeature iconCollisionFeature; WritingModeType writingModes; std::size_t layoutFeatureIndex; // Index into the set of features included at layout time std::size_t dataFeatureIndex; // Index into the underlying tile data feature set std::array textOffset; std::array iconOffset; std::u16string key; - bool isDuplicate; + float textBoxScale; + float radialTextOffset; + bool singleLine; +}; + +class SymbolInstance { +public: + SymbolInstance(const Anchor& anchor_, + std::shared_ptr data_, + const ShapedTextOrientations& shapedTextOrientations, + optional shapedIcon, + const float textPadding, + const style::SymbolPlacementType textPlacement, + const float iconBoxScale, + const float iconPadding, + const IndexedSubfeature& indexedFeature_, + const float overscaling, + const float rotate); + + optional getDefaultHorizontalPlacedTextIndex() const; + Anchor anchor; + std::shared_ptr commonData{nullptr}; + CollisionFeature textCollisionFeature; + CollisionFeature iconCollisionFeature; optional placedRightTextIndex; optional placedCenterTextIndex; optional placedLeftTextIndex; optional placedVerticalTextIndex; optional placedIconIndex; - float textBoxScale; - float radialTextOffset; - bool singleLine; - uint32_t crossTileID = 0; + uint32_t crossTileID{0}; }; } // namespace mbgl diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index d8d143632c..59c2999163 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -1,19 +1,20 @@ -#include -#include #include +#include +#include #include -#include #include +#include #include #include -#include +#include +#include #include -#include #include #include -#include -#include +#include +#include +#include #include namespace mbgl { @@ -22,10 +23,8 @@ using namespace style; template static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) { - return layout.get().match( - [] (const typename Property::Type& t) { return !t.empty(); }, - [] (const auto&) { return true; } - ); + return layout.get().match([](const typename Property::Type& t) { return !t.empty(); }, + [](const auto&) { return true; }); } namespace { @@ -42,7 +41,8 @@ expression::Value sectionOptionsToValue(const SectionOptions& options) { return result; } -inline const SymbolLayerProperties& toSymbolLayerProperties(const Immutable& layer) { +inline const SymbolLayerProperties& +toSymbolLayerProperties(const Immutable& layer) { return static_cast(*layer); } @@ -61,8 +61,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, tileSize(util::tileSize * overscaling), tilePixelRatio(float(util::EXTENT) / tileSize), textSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get()), - iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get()) - { + iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get()) { const SymbolLayer::Impl& leader = toSymbolLayerProperties(layers.at(0)).layerImpl(); @@ -102,9 +101,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, const bool hasSymbolSortKey = !leader.layout.get().isUndefined(); const auto symbolZOrder = layout.get(); const bool sortFeaturesByKey = symbolZOrder != SymbolZOrderType::ViewportY && hasSymbolSortKey; - const bool zOrderByViewportY = symbolZOrder == SymbolZOrderType::ViewportY || (symbolZOrder == SymbolZOrderType::Auto && !sortFeaturesByKey); - sortFeaturesByY = zOrderByViewportY && (layout.get() || layout.get() || - layout.get() || layout.get()); + const bool zOrderByViewportY = symbolZOrder == SymbolZOrderType::ViewportY || + (symbolZOrder == SymbolZOrderType::Auto && !sortFeaturesByKey); + sortFeaturesByY = zOrderByViewportY && + (layout.get() || layout.get() || + layout.get() || layout.get()); for (const auto& layer : layers) { layerPaintProperties.emplace(layer->baseImpl->id, layer); @@ -114,7 +115,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, const size_t featureCount = sourceLayer->featureCount(); for (size_t i = 0; i < featureCount; ++i) { auto feature = sourceLayer->getFeature(i); - if (!leader.filter(expression::EvaluationContext { this->zoom, feature.get() })) + if (!leader.filter(expression::EvaluationContext{ this->zoom, feature.get() })) continue; SymbolFeature ft(std::move(feature)); @@ -127,7 +128,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, FontStack baseFontStack = layout.evaluate(zoom, ft); ft.formattedText = TaggedString(); - for (const auto & section : formatted.sections) { + for (const auto& section : formatted.sections) { std::string u8string = section.text; if (textTransform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -141,15 +142,17 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, section.textColor); } - - const bool canVerticalizeText = layout.get() == AlignmentType::Map - && layout.get() != SymbolPlacementType::Point - && util::i18n::allowsVerticalWritingMode(ft.formattedText->rawText()); + const bool canVerticalizeText = + layout.get() == AlignmentType::Map && + layout.get() != SymbolPlacementType::Point && + util::i18n::allowsVerticalWritingMode(ft.formattedText->rawText()); // Loop through all characters of this text and collect unique codepoints. for (std::size_t j = 0; j < ft.formattedText->length(); j++) { - const auto& sectionFontStack = formatted.sections[ft.formattedText->getSectionIndex(j)].fontStack; - GlyphIDs& dependencies = glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack]; + const auto& sectionFontStack = + formatted.sections[ft.formattedText->getSectionIndex(j)].fontStack; + GlyphIDs& dependencies = + glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack]; char16_t codePoint = ft.formattedText->getCharCodeAt(j); dependencies.insert(codePoint); if (canVerticalizeText) { @@ -201,24 +204,31 @@ const float baselineOffset = 7.0f; // We don't care which shaping we get because this is used for collision purposes // and all the justifications have the same collision box. const Shaping& getDefaultHorizontalShaping(const ShapedTextOrientations& shapedTextOrientations) { - if (shapedTextOrientations.right) return shapedTextOrientations.right; - if (shapedTextOrientations.center) return shapedTextOrientations.center; - if (shapedTextOrientations.left) return shapedTextOrientations.left; + if (shapedTextOrientations.right) + return shapedTextOrientations.right; + if (shapedTextOrientations.center) + return shapedTextOrientations.center; + if (shapedTextOrientations.left) + return shapedTextOrientations.left; return shapedTextOrientations.horizontal; } -Shaping& shapingForTextJustifyType(ShapedTextOrientations& shapedTextOrientations, style::TextJustifyType type) { - switch(type) { - case style::TextJustifyType::Right: return shapedTextOrientations.right; - case style::TextJustifyType::Left: return shapedTextOrientations.left; - case style::TextJustifyType::Center: return shapedTextOrientations.center; +Shaping& shapingForTextJustifyType(ShapedTextOrientations& shapedTextOrientations, + style::TextJustifyType type) { + switch (type) { + case style::TextJustifyType::Right: + return shapedTextOrientations.right; + case style::TextJustifyType::Left: + return shapedTextOrientations.left; + case style::TextJustifyType::Center: + return shapedTextOrientations.center; default: assert(false); return shapedTextOrientations.horizontal; } } -} // namespace +} // namespace // static Point SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float radialOffset) { @@ -268,14 +278,18 @@ Point SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float r return result; } -void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, - const ImageMap& imageMap, const ImagePositions& imagePositions) { +void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, + const GlyphPositions& glyphPositions, + const ImageMap& imageMap, + const ImagePositions& imagePositions) { const bool isPointPlacement = layout.get() == SymbolPlacementType::Point; - const bool textAlongLine = layout.get() == AlignmentType::Map && !isPointPlacement; + const bool textAlongLine = + layout.get() == AlignmentType::Map && !isPointPlacement; for (auto it = features.begin(); it != features.end(); ++it) { auto& feature = *it; - if (feature.geometry.empty()) continue; + if (feature.geometry.empty()) + continue; ShapedTextOrientations shapedTextOrientations; optional shapedIcon; @@ -284,15 +298,19 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if feature has text, shape the text if (feature.formattedText) { const float lineHeight = layout.get() * util::ONE_EM; - const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout.evaluate(zoom, feature) * util::ONE_EM : 0.0f; + const float spacing = + util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) + ? layout.evaluate(zoom, feature) * util::ONE_EM + : 0.0f; - auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode, SymbolAnchorType textAnchor, TextJustifyType textJustify) { + auto applyShaping = [&](const TaggedString& formattedText, WritingModeType writingMode, + SymbolAnchorType textAnchor, TextJustifyType textJustify) { const Shaping result = getShaping( /* string */ formattedText, - /* maxWidth: ems */ isPointPlacement ? layout.evaluate(zoom, feature) * util::ONE_EM : 0.0f, - /* ems */ lineHeight, - textAnchor, - textJustify, + /* maxWidth: ems */ + isPointPlacement ? layout.evaluate(zoom, feature) * util::ONE_EM + : 0.0f, + /* ems */ lineHeight, textAnchor, textJustify, /* ems */ spacing, /* translate */ textOffset, /* writingMode */ writingMode, @@ -301,23 +319,28 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions return result; }; - const std::vector variableTextAnchor = layout.evaluate(zoom, feature); + const std::vector variableTextAnchor = + layout.evaluate(zoom, feature); const float radialOffset = layout.evaluate(zoom, feature); - const SymbolAnchorType textAnchor = layout.evaluate(zoom, feature); + const SymbolAnchorType textAnchor = layout.evaluate(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 + // 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 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. + // 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(zoom, feature)[0] * util::ONE_EM, - layout.evaluate(zoom, feature)[1] * util::ONE_EM}; + layout.evaluate(zoom, feature)[1] * util::ONE_EM }; } } - TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout.evaluate(zoom, feature); - // If this layer uses text-variable-anchor, generate shapings for all justification possibilities. + TextJustifyType textJustify = textAlongLine + ? TextJustifyType::Center + : layout.evaluate(zoom, feature); + // If this layer uses text-variable-anchor, generate shapings for all justification + // possibilities. if (!textAlongLine && !variableTextAnchor.empty()) { std::vector justifications; if (textJustify != TextJustifyType::Auto) { @@ -327,14 +350,17 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions justifications.push_back(getAnchorJustification(anchor)); } } - for (TextJustifyType justification: justifications) { - Shaping& shapingForJustification = shapingForTextJustifyType(shapedTextOrientations, justification); + for (TextJustifyType justification : justifications) { + Shaping& shapingForJustification = + shapingForTextJustifyType(shapedTextOrientations, justification); if (shapingForJustification) { continue; } - // If using text-variable-anchor for the layer, we use a center anchor for all shapings and apply - // the offsets for the anchor in the placement step. - Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, SymbolAnchorType::Center, justification); + // If using text-variable-anchor for the layer, we use a center anchor for all + // shapings and apply the offsets for the anchor in the placement step. + Shaping shaping = + applyShaping(*feature.formattedText, WritingModeType::Horizontal, + SymbolAnchorType::Center, justification); if (shaping) { shapingForJustification = std::move(shaping); if (shaping.lineCount == 1u) { @@ -347,14 +373,17 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions if (textJustify == TextJustifyType::Auto) { textJustify = getAnchorJustification(textAnchor); } - Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, textAnchor, textJustify); + Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, + textAnchor, textJustify); if (shaping) { shapedTextOrientations.horizontal = std::move(shaping); } - if (util::i18n::allowsVerticalWritingMode(feature.formattedText->rawText()) && textAlongLine) { + if (util::i18n::allowsVerticalWritingMode(feature.formattedText->rawText()) && + textAlongLine) { feature.formattedText->verticalizePunctuation(); - shapedTextOrientations.vertical = applyShaping(*feature.formattedText, WritingModeType::Vertical, textAnchor, textJustify); + shapedTextOrientations.vertical = applyShaping( + *feature.formattedText, WritingModeType::Vertical, textAnchor, textJustify); } } } @@ -364,8 +393,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions auto image = imageMap.find(*feature.icon); if (image != imageMap.end()) { shapedIcon = PositionedIcon::shapeIcon( - imagePositions.at(*feature.icon), - layout.evaluate(zoom, feature), + imagePositions.at(*feature.icon), layout.evaluate(zoom, feature), layout.evaluate(zoom, feature), layout.evaluate(zoom, feature) * util::DEG2RAD); if (image->second->sdf) { @@ -381,7 +409,8 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if either shapedText or icon position is present, add the feature if (getDefaultHorizontalShaping(shapedTextOrientations) || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositions, textOffset); + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, + shapedIcon, glyphPositions, textOffset); } feature.geometry.clear(); @@ -401,7 +430,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float layoutTextSize = layout.evaluate(zoom + 1, feature); const float layoutIconSize = layout.evaluate(zoom + 1, feature); - const std::array textOffset = {{ offset.x, offset.y }}; + const std::array textOffset = { { offset.x, offset.y } }; const std::array iconOffset = layout.evaluate(zoom, feature); @@ -409,7 +438,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, // 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 textMaxSize = layout.evaluate(24, feature); const float fontScale = layoutTextSize / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; @@ -421,16 +450,19 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float textMaxAngle = layout.get() * util::DEG2RAD; const float rotation = layout.evaluate(zoom, feature); const float radialTextOffset = layout.evaluate(zoom, feature) * util::ONE_EM; - const SymbolPlacementType textPlacement = layout.get() != AlignmentType::Map - ? SymbolPlacementType::Point - : layout.get(); + const SymbolPlacementType textPlacement = + layout.get() != AlignmentType::Map ? SymbolPlacementType::Point + : layout.get(); const float textRepeatDistance = symbolSpacing / 2; const auto evaluatedLayoutProperties = layout.evaluate(zoom, feature); - IndexedSubfeature indexedFeature(feature.index, sourceLayer->getName(), bucketLeaderID, symbolInstances.size()); + IndexedSubfeature indexedFeature(feature.index, sourceLayer->getName(), bucketLeaderID, + symbolInstances.size()); - auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) { - const bool anchorInsideTile = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT; + auto addSymbolInstance = [&](std::shared_ptr sharedData, + Anchor& anchor) { + const bool anchorInsideTile = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && + anchor.point.y >= 0 && anchor.point.y < util::EXTENT; if (mode == MapMode::Tile || anchorInsideTile) { // For static/continuous rendering, only add symbols anchored within this tile: @@ -438,55 +470,76 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, // In tiled rendering mode, add all symbols in the buffers so that we can: // (1) render symbols that overlap into this tile // (2) approximate collision detection effects from neighboring symbols - symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, - evaluatedLayoutProperties, layoutTextSize, - textBoxScale, textPadding, textPlacement, textOffset, - iconBoxScale, iconPadding, iconOffset, - glyphPositions, indexedFeature, layoutFeatureIndex, feature.index, - feature.formattedText ? feature.formattedText->rawText() : std::u16string(), overscaling, rotation, radialTextOffset); + symbolInstances.emplace_back(anchor, sharedData, shapedTextOrientations, shapedIcon, + textPadding, textPlacement, iconBoxScale, iconPadding, + indexedFeature, overscaling, rotation); } }; const auto& type = feature.getType(); - + uint32_t count{ 0U }; if (layout.get() == SymbolPlacementType::Line) { auto clippedLines = util::clipLines(feature.geometry, 0, 0, util::EXTENT, util::EXTENT); + std::cout << "-----Zoom level " << zoom << "------" << std::endl; + // std::cout<< "---------Number of cliped lines: "<< clippedLines.size() << + // "--------------"<left() : 0), - (shapedIcon ? shapedIcon->right() : 0), - glyphSize, - textMaxBoxScale, - overscaling); - + // std::cout << "Number of geometries: "<< line.size()<< std::endl; + auto sharedData = std::make_shared( + line, shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, textBoxScale, + textPlacement, textOffset, iconOffset, glyphPositions, layoutFeatureIndex, + feature.index, + (feature.formattedText ? feature.formattedText->rawText() : std::u16string()), + radialTextOffset); + + Anchors anchors = getAnchors( + line, symbolSpacing, textMaxAngle, + (shapedTextOrientations.vertical + ?: getDefaultHorizontalShaping(shapedTextOrientations)) + .left, + (shapedTextOrientations.vertical + ?: getDefaultHorizontalShaping(shapedTextOrientations)) + .right, + (shapedIcon ? shapedIcon->left() : 0), (shapedIcon ? shapedIcon->right() : 0), + glyphSize, textMaxBoxScale, overscaling); + // std::cout<< "Number of anchors : "<< anchors.size() << std::endl; for (auto& anchor : anchors) { - if (!feature.formattedText || !anchorIsTooClose(feature.formattedText->rawText(), textRepeatDistance, anchor)) { - addSymbolInstance(line, anchor); + if (!feature.formattedText || !anchorIsTooClose(feature.formattedText->rawText(), + textRepeatDistance, anchor)) { + addSymbolInstance(sharedData, anchor); + ++count; } } } +// std::cout << "---------Create new Symbol instances for Line, number: " << count +// << "--------------" << std::endl; } else if (layout.get() == SymbolPlacementType::LineCenter) { // No clipping, multiple lines per feature are allowed // "lines" with only one point are ignored as in clipLines for (const auto& line : feature.geometry) { + auto sharedData = std::make_shared( + line, shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, textBoxScale, + textPlacement, textOffset, iconOffset, glyphPositions, layoutFeatureIndex, + feature.index, + (feature.formattedText ? feature.formattedText->rawText() : std::u16string()), + radialTextOffset); if (line.size() > 1) { - optional anchor = getCenterAnchor(line, - textMaxAngle, - (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).left, - (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).right, - (shapedIcon ? shapedIcon->left() : 0), - (shapedIcon ? shapedIcon->right() : 0), - glyphSize, - textMaxBoxScale); + optional anchor = getCenterAnchor( + line, textMaxAngle, + (shapedTextOrientations.vertical + ?: getDefaultHorizontalShaping(shapedTextOrientations)) + .left, + (shapedTextOrientations.vertical + ?: getDefaultHorizontalShaping(shapedTextOrientations)) + .right, + (shapedIcon ? shapedIcon->left() : 0), (shapedIcon ? shapedIcon->right() : 0), + glyphSize, textMaxBoxScale); if (anchor) { - addSymbolInstance(line, *anchor); + addSymbolInstance(sharedData, *anchor); } } } + } else if (type == FeatureType::Polygon) { for (const auto& polygon : classifyRings(feature.geometry)) { Polygon poly; @@ -501,24 +554,46 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, // 1 pixel worth of precision, in tile coordinates auto poi = mapbox::polylabel(poly, double(util::EXTENT / util::tileSize)); Anchor anchor(poi.x, poi.y, 0, minScale); - addSymbolInstance(polygon[0], anchor); + auto sharedData = std::make_shared( + polygon[0], shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, + textBoxScale, textPlacement, textOffset, iconOffset, glyphPositions, + layoutFeatureIndex, feature.index, + (feature.formattedText ? feature.formattedText->rawText() : std::u16string()), + radialTextOffset); + addSymbolInstance(sharedData, anchor); } } else if (type == FeatureType::LineString) { for (const auto& line : feature.geometry) { + auto sharedData = std::make_shared( + line, shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, textBoxScale, + textPlacement, textOffset, iconOffset, glyphPositions, layoutFeatureIndex, + feature.index, + (feature.formattedText ? feature.formattedText->rawText() : std::u16string()), + radialTextOffset); Anchor anchor(line[0].x, line[0].y, 0, minScale); - addSymbolInstance(line, anchor); + addSymbolInstance(sharedData, anchor); } } else if (type == FeatureType::Point) { for (const auto& points : feature.geometry) { for (const auto& point : points) { + auto sharedData = std::make_shared( + GeometryCoordinates{ point }, shapedTextOrientations, shapedIcon, evaluatedLayoutProperties, layoutTextSize, textBoxScale, + textPlacement, textOffset, iconOffset, glyphPositions, layoutFeatureIndex, + feature.index, + (feature.formattedText ? feature.formattedText->rawText() : std::u16string()), + radialTextOffset); Anchor anchor(point.x, point.y, 0, minScale); - addSymbolInstance({point}, anchor); + addSymbolInstance(sharedData, anchor); } } + // std::cout << "---------Create new Symbol instances for Point, number: "<< count + // << "--------------"< CalculateTileDistances(const GeometryCoordinates& line, const Anchor& anchor) { std::vector tileDistances(line.size()); if (anchor.segment != -1) { @@ -556,15 +631,21 @@ std::vector CalculateTileDistances(const GeometryCoordinates& line, const return tileDistances; } -void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr&, std::unordered_map& renderData, const bool firstLoad, const bool showCollisionBoxes) { - auto bucket = std::make_shared(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio); +void SymbolLayout::createBucket(const ImagePositions&, + std::unique_ptr&, + std::unordered_map& renderData, + const bool firstLoad, + const bool showCollisionBoxes) { + auto bucket = std::make_shared( + layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, + sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio); - for (SymbolInstance &symbolInstance : bucket->symbolInstances) { - const bool hasText = symbolInstance.hasText; - const bool hasIcon = symbolInstance.hasIcon; - const bool singleLine = symbolInstance.singleLine; + for (SymbolInstance& symbolInstance : bucket->symbolInstances) { + const bool hasText = symbolInstance.commonData->hasText; + const bool hasIcon = symbolInstance.commonData->hasIcon; + const bool singleLine = symbolInstance.commonData->singleLine; - const auto& feature = features.at(symbolInstance.layoutFeatureIndex); + const auto& feature = features.at(symbolInstance.commonData->layoutFeatureIndex); // Insert final placement into collision tree and add glyphs/icons to buffers @@ -572,40 +653,59 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr lastAddedSection; if (singleLine) { optional placedTextIndex; - lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, placedTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection); + lastAddedSection = addSymbolGlyphQuads( + *bucket, symbolInstance, feature, symbolInstance.commonData->writingModes, + placedTextIndex, symbolInstance.commonData->rightJustifiedGlyphQuads, + lastAddedSection); symbolInstance.placedRightTextIndex = placedTextIndex; symbolInstance.placedCenterTextIndex = placedTextIndex; symbolInstance.placedLeftTextIndex = placedTextIndex; } else { - if (!symbolInstance.rightJustifiedGlyphQuads.empty()) { - lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedRightTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection); + if (!symbolInstance.commonData->rightJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads( + *bucket, symbolInstance, feature, symbolInstance.commonData->writingModes, + symbolInstance.placedRightTextIndex, + symbolInstance.commonData->rightJustifiedGlyphQuads, lastAddedSection); } - if (!symbolInstance.centerJustifiedGlyphQuads.empty()) { - lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedCenterTextIndex, symbolInstance.centerJustifiedGlyphQuads, lastAddedSection); + if (!symbolInstance.commonData->centerJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads( + *bucket, symbolInstance, feature, symbolInstance.commonData->writingModes, + symbolInstance.placedCenterTextIndex, + symbolInstance.commonData->centerJustifiedGlyphQuads, lastAddedSection); } - if (!symbolInstance.leftJustifiedGlyphQuads.empty()) { - lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedLeftTextIndex, symbolInstance.leftJustifiedGlyphQuads, lastAddedSection); + if (!symbolInstance.commonData->leftJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads( + *bucket, symbolInstance, feature, symbolInstance.commonData->writingModes, + symbolInstance.placedLeftTextIndex, + symbolInstance.commonData->leftJustifiedGlyphQuads, lastAddedSection); } } - if (symbolInstance.writingModes & WritingModeType::Vertical) { - lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, WritingModeType::Vertical, symbolInstance.placedVerticalTextIndex, symbolInstance.verticalGlyphQuads, lastAddedSection); + if (symbolInstance.commonData->writingModes & WritingModeType::Vertical) { + lastAddedSection = addSymbolGlyphQuads( + *bucket, symbolInstance, feature, WritingModeType::Vertical, + symbolInstance.placedVerticalTextIndex, + symbolInstance.commonData->verticalGlyphQuads, lastAddedSection); } assert(lastAddedSection); // True, as hasText == true; updatePaintPropertiesForSection(*bucket, feature, *lastAddedSection); } if (hasIcon) { - if (symbolInstance.iconQuad) { + if (symbolInstance.commonData->iconQuad) { const Range sizeData = bucket->iconSizeBinder->getVertexSizeData(feature); - bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, - symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line, std::vector()); + bucket->icon.placedSymbols.emplace_back( + symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, + sizeData.max, symbolInstance.commonData->iconOffset, WritingModeType::None, + symbolInstance.commonData->line, std::vector()); symbolInstance.placedIconIndex = bucket->icon.placedSymbols.size() - 1; PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back(); - iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, *symbolInstance.iconQuad, - symbolInstance.anchor, iconSymbol, feature.sortKey); + iconSymbol.vertexStartIndex = + addSymbol(bucket->icon, sizeData, *symbolInstance.commonData->iconQuad, + symbolInstance.anchor, iconSymbol, feature.sortKey); for (auto& pair : bucket->paintProperties) { - pair.second.iconBinders.populateVertexVectors(feature, bucket->icon.vertices.elements(), {}, {}); + pair.second.iconBinders.populateVertexVectors( + feature, bucket->icon.vertices.elements(), {}, {}); } } } @@ -614,23 +714,24 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptrhasData()){ + if (bucket->hasData()) { for (const auto& pair : layerPaintProperties) { if (!firstLoad) { bucket->justReloaded = true; } - renderData.emplace(pair.first, LayerRenderData{bucket, pair.second}); + renderData.emplace(pair.first, LayerRenderData{ bucket, pair.second }); } } - } void SymbolLayout::updatePaintPropertiesForSection(SymbolBucket& bucket, const SymbolFeature& feature, std::size_t sectionIndex) { - const auto& formattedSection = sectionOptionsToValue((*feature.formattedText).sectionAt(sectionIndex)); + const auto& formattedSection = + sectionOptionsToValue((*feature.formattedText).sectionAt(sectionIndex)); for (auto& pair : bucket.paintProperties) { - pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), {}, {}, formattedSection); + pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), {}, + {}, formattedSection); } } @@ -644,8 +745,10 @@ std::size_t SymbolLayout::addSymbolGlyphQuads(SymbolBucket& bucket, const Range sizeData = bucket.textSizeBinder->getVertexSizeData(feature); const bool hasFormatSectionOverrides = bucket.hasFormatSectionOverrides(); - bucket.text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, - symbolInstance.textOffset, writingMode, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor)); + bucket.text.placedSymbols.emplace_back( + symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max, + symbolInstance.commonData->textOffset, writingMode, symbolInstance.commonData->line, + CalculateTileDistances(symbolInstance.commonData->line, symbolInstance.anchor)); placedIndex = bucket.text.placedSymbols.size() - 1; PlacedSymbol& placedSymbol = bucket.text.placedSymbols.back(); @@ -657,7 +760,8 @@ std::size_t SymbolLayout::addSymbolGlyphQuads(SymbolBucket& bucket, } lastAddedSection = symbolQuad.sectionIndex; } - size_t index = addSymbol(bucket.text, sizeData, symbolQuad, symbolInstance.anchor, placedSymbol, feature.sortKey); + size_t index = addSymbol(bucket.text, sizeData, symbolQuad, symbolInstance.anchor, + placedSymbol, feature.sortKey); if (firstSymbol) { placedSymbol.vertexStartIndex = index; firstSymbol = false; @@ -675,16 +779,17 @@ size_t SymbolLayout::addSymbol(SymbolBucket::Buffer& buffer, float sortKey) { constexpr const uint16_t vertexLength = 4; - const auto &tl = symbol.tl; - const auto &tr = symbol.tr; - const auto &bl = symbol.bl; - const auto &br = symbol.br; - const auto &tex = symbol.tex; + const auto& tl = symbol.tl; + const auto& tr = symbol.tr; + const auto& bl = symbol.bl; + const auto& br = symbol.br; + const auto& tex = symbol.tex; if (buffer.segments.empty() || buffer.segments.back().vertexLength + vertexLength > std::numeric_limits::max() || fabs(buffer.segments.back().sortKey - sortKey) > std::numeric_limits::epsilon()) { - buffer.segments.emplace_back(buffer.vertices.elements(), buffer.triangles.elements(), 0ul, 0ul, sortKey); + buffer.segments.emplace_back(buffer.vertices.elements(), buffer.triangles.elements(), 0ul, + 0ul, sortKey); } // We're generating triangle fans, so we always start with the first @@ -694,10 +799,14 @@ size_t SymbolLayout::addSymbol(SymbolBucket::Buffer& buffer, uint16_t index = segment.vertexLength; // coordinates (2 triangles) - buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, tl, symbol.glyphOffset.y, tex.x, tex.y, sizeData)); - buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, tr, symbol.glyphOffset.y, tex.x + tex.w, tex.y, sizeData)); - buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, bl, symbol.glyphOffset.y, tex.x, tex.y + tex.h, sizeData)); - buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex(labelAnchor.point, br, symbol.glyphOffset.y, tex.x + tex.w, tex.y + tex.h, sizeData)); + buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex( + labelAnchor.point, tl, symbol.glyphOffset.y, tex.x, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex( + labelAnchor.point, tr, symbol.glyphOffset.y, tex.x + tex.w, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex( + labelAnchor.point, bl, symbol.glyphOffset.y, tex.x, tex.y + tex.h, sizeData)); + buffer.vertices.emplace_back(SymbolSDFIconProgram::layoutVertex( + labelAnchor.point, br, symbol.glyphOffset.y, tex.x + tex.w, tex.y + tex.h, sizeData)); // Dynamic/Opacity vertices are initialized so that the vertex count always agrees with // the layout vertex buffer, but they will always be updated before rendering happens @@ -731,37 +840,47 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) { return; } - for (const SymbolInstance &symbolInstance : symbolInstances) { + for (const SymbolInstance& symbolInstance : symbolInstances) { auto populateCollisionBox = [&](const auto& feature) { - SymbolBucket::CollisionBuffer& collisionBuffer = feature.alongLine ? - static_cast(bucket.collisionCircle) : - static_cast(bucket.collisionBox); - for (const CollisionBox &box : feature.boxes) { + SymbolBucket::CollisionBuffer& collisionBuffer = + feature.alongLine + ? static_cast(bucket.collisionCircle) + : static_cast(bucket.collisionBox); + for (const CollisionBox& box : feature.boxes) { auto& anchor = box.anchor; - Point tl{box.x1, box.y1}; - Point tr{box.x2, box.y1}; - Point bl{box.x1, box.y2}; - Point br{box.x2, box.y2}; + Point tl{ box.x1, box.y1 }; + Point tr{ box.x2, box.y1 }; + Point bl{ box.x1, box.y2 }; + Point br{ box.x2, box.y2 }; static constexpr std::size_t vertexLength = 4; const std::size_t indexLength = feature.alongLine ? 6 : 8; - if (collisionBuffer.segments.empty() || collisionBuffer.segments.back().vertexLength + vertexLength > std::numeric_limits::max()) { - collisionBuffer.segments.emplace_back(collisionBuffer.vertices.elements(), - feature.alongLine? bucket.collisionCircle.triangles.elements() : bucket.collisionBox.lines.elements()); + if (collisionBuffer.segments.empty() || + collisionBuffer.segments.back().vertexLength + vertexLength > + std::numeric_limits::max()) { + collisionBuffer.segments.emplace_back( + collisionBuffer.vertices.elements(), + feature.alongLine ? bucket.collisionCircle.triangles.elements() + : bucket.collisionBox.lines.elements()); } auto& segment = collisionBuffer.segments.back(); uint16_t index = segment.vertexLength; - collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tl)); - collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tr)); - collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, br)); - collisionBuffer.vertices.emplace_back(CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, bl)); + collisionBuffer.vertices.emplace_back( + CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tl)); + collisionBuffer.vertices.emplace_back( + CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, tr)); + collisionBuffer.vertices.emplace_back( + CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, br)); + collisionBuffer.vertices.emplace_back( + CollisionBoxProgram::layoutVertex(anchor, symbolInstance.anchor.point, bl)); // Dynamic vertices are initialized so that the vertex count always agrees with - // the layout vertex buffer, but they will always be updated before rendering happens + // the layout vertex buffer, but they will always be updated before rendering + // happens auto dynamicVertex = CollisionBoxProgram::dynamicVertex(false, false, {}); collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 2ad5318d19..70ecc3ba04 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -196,17 +196,17 @@ void SymbolBucket::sortFeatures(const float angle) { // The index array buffer is rewritten to reference the (unchanged) vertices in the // sorted order. for (const SymbolInstance& symbolInstance : getSortedSymbols(angle)) { - featureSortOrder->push_back(symbolInstance.dataFeatureIndex); + featureSortOrder->push_back(symbolInstance.commonData->dataFeatureIndex); if (symbolInstance.placedRightTextIndex) { addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedRightTextIndex]); } - if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) { + if (symbolInstance.placedCenterTextIndex && !symbolInstance.commonData->singleLine) { addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedCenterTextIndex]); } - if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) { + if (symbolInstance.placedLeftTextIndex && !symbolInstance.commonData->singleLine) { addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedLeftTextIndex]); } @@ -231,7 +231,7 @@ std::vector> SymbolBucket::getSortedSymbo if (aRotated != bRotated) { return aRotated < bRotated; } - return a.dataFeatureIndex > b.dataFeatureIndex; // aRotated == bRotated + return a.commonData->dataFeatureIndex > b.commonData->dataFeatureIndex; // aRotated == bRotated }); return result; diff --git a/src/mbgl/text/cross_tile_symbol_index.cpp b/src/mbgl/text/cross_tile_symbol_index.cpp index 43ed85d957..6863be4bdb 100644 --- a/src/mbgl/text/cross_tile_symbol_index.cpp +++ b/src/mbgl/text/cross_tile_symbol_index.cpp @@ -10,7 +10,7 @@ namespace mbgl { TileLayerIndex::TileLayerIndex(OverscaledTileID coord_, std::vector& symbolInstances, uint32_t bucketInstanceId_) : coord(coord_), bucketInstanceId(bucketInstanceId_) { for (SymbolInstance& symbolInstance : symbolInstances) { - indexedSymbolInstances[symbolInstance.key].emplace_back(symbolInstance.crossTileID, getScaledCoordinates(symbolInstance, coord)); + indexedSymbolInstances[symbolInstance.commonData->key].emplace_back(symbolInstance.crossTileID, getScaledCoordinates(symbolInstance, coord)); } } @@ -33,7 +33,7 @@ void TileLayerIndex::findMatches(std::vector& symbolInstances, c continue; } - auto it = indexedSymbolInstances.find(symbolInstance.key); + auto it = indexedSymbolInstances.find(symbolInstance.commonData->key); if (it == indexedSymbolInstances.end()) { // No symbol with this key in this bucket continue; diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 62110fefa7..945a413230 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -191,7 +191,7 @@ void Placement::placeBucket( const CollisionBox& textBox = symbolInstance.textCollisionFeature.boxes[0]; const float width = textBox.x2 - textBox.x1; const float height = textBox.y2 - textBox.y1; - const float textBoxScale = symbolInstance.textBoxScale; + const float textBoxScale = symbolInstance.commonData->textBoxScale; // If this symbol was in the last placement, shift the previously used // anchor to the front of the anchor list. @@ -212,7 +212,7 @@ void Placement::placeBucket( } for (auto anchor : variableTextAnchors) { - Point shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.radialTextOffset, textBoxScale); + Point shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.commonData->radialTextOffset, textBoxScale); if (rotateWithMap) { float angle = pitchWithMap ? state.getBearing() : -state.getBearing(); shift = util::rotate(shift, angle); @@ -242,7 +242,7 @@ void Placement::placeBucket( } variableOffsets.insert(std::make_pair(symbolInstance.crossTileID, VariableOffset{ - symbolInstance.radialTextOffset, + symbolInstance.commonData->radialTextOffset, width, height, anchor, @@ -283,8 +283,8 @@ void Placement::placeBucket( offscreen &= placed.second; } - const bool iconWithoutText = !symbolInstance.hasText || layout.get(); - const bool textWithoutIcon = !symbolInstance.hasIcon || layout.get(); + const bool iconWithoutText = !symbolInstance.commonData->hasText || layout.get(); + const bool textWithoutIcon = !symbolInstance.commonData->hasIcon || layout.get(); // combine placements for icon and text if (!iconWithoutText && !textWithoutIcon) { @@ -540,31 +540,31 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState seenCrossTileIDs.insert(symbolInstance.crossTileID); - if (symbolInstance.hasText) { + if (symbolInstance.commonData->hasText) { auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity); if (symbolInstance.placedRightTextIndex) { - for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuads.size() * 4; i++) { + for (size_t i = 0; i < symbolInstance.commonData->rightJustifiedGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex]; placed.hidden = opacityState.isHidden(); } - if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) { - for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuads.size() * 4; i++) { + if (symbolInstance.placedCenterTextIndex && !symbolInstance.commonData->singleLine) { + for (size_t i = 0; i < symbolInstance.commonData->centerJustifiedGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedCenterTextIndex]; placed.hidden = opacityState.isHidden(); } - if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) { - for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuads.size() * 4; i++) { + if (symbolInstance.placedLeftTextIndex && !symbolInstance.commonData->singleLine) { + for (size_t i = 0; i < symbolInstance.commonData->leftJustifiedGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedLeftTextIndex]; placed.hidden = opacityState.isHidden(); } if (symbolInstance.placedVerticalTextIndex) { - for (size_t i = 0; i < symbolInstance.verticalGlyphQuads.size() * 4; i++) { + for (size_t i = 0; i < symbolInstance.commonData->verticalGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden(); @@ -575,9 +575,9 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance); } } - if (symbolInstance.hasIcon) { + if (symbolInstance.commonData->hasIcon) { auto opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity); - if (symbolInstance.iconQuad) { + if (symbolInstance.commonData->iconQuad) { bucket.icon.opacityVertices.emplace_back(opacityVertex); bucket.icon.opacityVertices.emplace_back(opacityVertex); bucket.icon.opacityVertices.emplace_back(opacityVertex); -- cgit v1.2.1