summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <zmiao.jamie@gmail.com>2019-07-17 17:40:42 +0300
committerzmiao <zmiao.jamie@gmail.com>2019-07-17 17:40:42 +0300
commitfbc9fe8c963ad116c81117bf0a9b7fe5d412adad (patch)
tree0961ef35ddd2494a5412ba4a730c4ac60c961f9b
parent5f6f20e667d36fd2f2475756c55d17bade8ee3e2 (diff)
downloadqtlocation-mapboxgl-upstream/origin/15022_memory_consumption.tar.gz
make symbol instance common data sharedupstream/origin/15022_memory_consumption
-rw-r--r--platform/glfw/glfw_view.cpp8
-rw-r--r--platform/glfw/main.cpp8
-rw-r--r--src/mbgl/layout/symbol_instance.cpp175
-rw-r--r--src/mbgl/layout/symbol_instance.hpp82
-rw-r--r--src/mbgl/layout/symbol_layout.cpp445
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp8
-rw-r--r--src/mbgl/text/cross_tile_symbol_index.cpp4
-rw-r--r--src/mbgl/text/placement.cpp28
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 <mapbox/geometry.hpp>
#include <mapbox/geojson.hpp>
+#include <iostream>
+
#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<PositionedIcon> shapedIcon,
- const SymbolLayoutProperties::Evaluated& layout,
- const float layoutTextSize,
- const float textBoxScale_,
- const float textPadding,
- const SymbolPlacementType textPlacement,
- const std::array<float, 2> textOffset_,
- const float iconBoxScale,
- const float iconPadding,
- const std::array<float, 2> 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<PositionedIcon> shapedIcon,
+ const style::SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
+ const float textBoxScale_,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2> textOffset_,
+ const std::array<float, 2> 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<SymbolInstanceCommonData> data_,
+ const ShapedTextOrientations& shapedTextOrientations,
+ optional<PositionedIcon> 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<size_t> 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 <mbgl/text/quads.hpp>
-#include <mbgl/text/glyph_atlas.hpp>
-#include <mbgl/text/collision_feature.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
-
+#include <mbgl/text/collision_feature.hpp>
+#include <mbgl/text/glyph_atlas.hpp>
+#include <mbgl/text/quads.hpp>
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<PositionedIcon> shapedIcon,
- const style::SymbolLayoutProperties::Evaluated&,
- const float layoutTextSize,
- const float textBoxScale,
- const float textPadding,
- style::SymbolPlacementType textPlacement,
- const std::array<float, 2> textOffset,
- const float iconBoxScale,
- const float iconPadding,
- const std::array<float, 2> 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<size_t> getDefaultHorizontalPlacedTextIndex() const;
- Anchor anchor;
+ SymbolInstanceCommonData(const GeometryCoordinates& line_,
+ const ShapedTextOrientations& shapedTextOrientations,
+ optional<PositionedIcon> shapedIcon,
+ const style::SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
+ const float textBoxScale_,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2> textOffset_,
+ const std::array<float, 2> 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<SymbolQuad> 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<float, 2> textOffset;
std::array<float, 2> iconOffset;
std::u16string key;
- bool isDuplicate;
+ float textBoxScale;
+ float radialTextOffset;
+ bool singleLine;
+};
+
+class SymbolInstance {
+public:
+ SymbolInstance(const Anchor& anchor_,
+ std::shared_ptr<SymbolInstanceCommonData> data_,
+ const ShapedTextOrientations& shapedTextOrientations,
+ optional<PositionedIcon> shapedIcon,
+ const float textPadding,
+ const style::SymbolPlacementType textPlacement,
+ const float iconBoxScale,
+ const float iconPadding,
+ const IndexedSubfeature& indexedFeature_,
+ const float overscaling,
+ const float rotate);
+
+ optional<size_t> getDefaultHorizontalPlacedTextIndex() const;
+ Anchor anchor;
+ std::shared_ptr<SymbolInstanceCommonData> commonData{nullptr};
+ CollisionFeature textCollisionFeature;
+ CollisionFeature iconCollisionFeature;
optional<size_t> placedRightTextIndex;
optional<size_t> placedCenterTextIndex;
optional<size_t> placedLeftTextIndex;
optional<size_t> placedVerticalTextIndex;
optional<size_t> 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 <mbgl/layout/symbol_layout.hpp>
-#include <mbgl/layout/merge_lines.hpp>
#include <mbgl/layout/clip_lines.hpp>
+#include <mbgl/layout/merge_lines.hpp>
+#include <mbgl/layout/symbol_layout.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
-#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/image_atlas.hpp>
+#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/text/get_anchors.hpp>
#include <mbgl/text/shaping.hpp>
-#include <mbgl/util/utf.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/tile/tile.hpp>
#include <mbgl/util/constants.hpp>
-#include <mbgl/util/string.hpp>
#include <mbgl/util/i18n.hpp>
#include <mbgl/util/platform.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/tile/tile.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/util/utf.hpp>
+#include <iostream>
#include <mapbox/polylabel.hpp>
namespace mbgl {
@@ -22,10 +23,8 @@ using namespace style;
template <class Property>
static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout) {
- return layout.get<Property>().match(
- [] (const typename Property::Type& t) { return !t.empty(); },
- [] (const auto&) { return true; }
- );
+ return layout.get<Property>().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<LayerProperties>& layer) {
+inline const SymbolLayerProperties&
+toSymbolLayerProperties(const Immutable<LayerProperties>& layer) {
return static_cast<const SymbolLayerProperties&>(*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<TextSize>()),
- iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<IconSize>())
- {
+ iconSize(toSymbolLayerProperties(layers.at(0)).layerImpl().layout.get<IconSize>()) {
const SymbolLayer::Impl& leader = toSymbolLayerProperties(layers.at(0)).layerImpl();
@@ -102,9 +101,11 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const bool hasSymbolSortKey = !leader.layout.get<SymbolSortKey>().isUndefined();
const auto symbolZOrder = layout.get<SymbolZOrder>();
const bool sortFeaturesByKey = symbolZOrder != SymbolZOrderType::ViewportY && hasSymbolSortKey;
- const bool zOrderByViewportY = symbolZOrder == SymbolZOrderType::ViewportY || (symbolZOrder == SymbolZOrderType::Auto && !sortFeaturesByKey);
- sortFeaturesByY = zOrderByViewportY && (layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
- layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>());
+ const bool zOrderByViewportY = symbolZOrder == SymbolZOrderType::ViewportY ||
+ (symbolZOrder == SymbolZOrderType::Auto && !sortFeaturesByKey);
+ sortFeaturesByY = zOrderByViewportY &&
+ (layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
+ layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>());
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<TextFont>(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<TextRotationAlignment>() == AlignmentType::Map
- && layout.get<SymbolPlacement>() != SymbolPlacementType::Point
- && util::i18n::allowsVerticalWritingMode(ft.formattedText->rawText());
+ const bool canVerticalizeText =
+ layout.get<TextRotationAlignment>() == AlignmentType::Map &&
+ layout.get<SymbolPlacement>() != 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<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float radialOffset) {
@@ -268,14 +278,18 @@ Point<float> 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<SymbolPlacement>() == SymbolPlacementType::Point;
- const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && !isPointPlacement;
+ const bool textAlongLine =
+ layout.get<TextRotationAlignment>() == 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<PositionedIcon> 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<TextLineHeight>() * util::ONE_EM;
- const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * util::ONE_EM : 0.0f;
+ const float spacing =
+ util::i18n::allowsLetterSpacing(feature.formattedText->rawText())
+ ? layout.evaluate<TextLetterSpacing>(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<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f,
- /* ems */ lineHeight,
- textAnchor,
- textJustify,
+ /* maxWidth: ems */
+ isPointPlacement ? layout.evaluate<TextMaxWidth>(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<style::TextVariableAnchorType> variableTextAnchor = layout.evaluate<TextVariableAnchor>(zoom, feature);
+ 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);
+ 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
+ // 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<TextOffset>(zoom, feature)[0] * util::ONE_EM,
- layout.evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM};
+ layout.evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM };
}
}
- TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout.evaluate<TextJustify>(zoom, feature);
- // If this layer uses text-variable-anchor, generate shapings for all justification possibilities.
+ TextJustifyType textJustify = textAlongLine
+ ? TextJustifyType::Center
+ : layout.evaluate<TextJustify>(zoom, feature);
+ // If this layer uses text-variable-anchor, generate shapings for all justification
+ // possibilities.
if (!textAlongLine && !variableTextAnchor.empty()) {
std::vector<TextJustifyType> 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<IconOffset>(zoom, feature),
+ imagePositions.at(*feature.icon), layout.evaluate<IconOffset>(zoom, feature),
layout.evaluate<IconAnchor>(zoom, feature),
layout.evaluate<IconRotate>(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<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> textOffset = { { offset.x, offset.y } };
const std::array<float, 2> iconOffset = layout.evaluate<IconOffset>(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<TextSize>(18, feature);
+ const float textMaxSize = layout.evaluate<TextSize>(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<TextMaxAngle>() * util::DEG2RAD;
const float rotation = layout.evaluate<IconRotate>(zoom, feature);
const float radialTextOffset = layout.evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM;
- const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map
- ? SymbolPlacementType::Point
- : layout.get<SymbolPlacement>();
+ const SymbolPlacementType textPlacement =
+ layout.get<TextRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point
+ : layout.get<SymbolPlacement>();
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<SymbolInstanceCommonData> 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<SymbolPlacement>() == 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() <<
+ // "--------------"<<std::endl;
for (const auto& line : clippedLines) {
- 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 geometries: "<< line.size()<< std::endl;
+ auto sharedData = std::make_shared<SymbolInstanceCommonData>(
+ 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<SymbolPlacement>() == 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<SymbolInstanceCommonData>(
+ 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> 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> 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<double> 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<SymbolInstanceCommonData>(
+ 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<SymbolInstanceCommonData>(
+ 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<SymbolInstanceCommonData>(
+ 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
+ // << "--------------"<<std::endl;
}
}
-bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor& anchor) {
+bool SymbolLayout::anchorIsTooClose(const std::u16string& text,
+ const float repeatDistance,
+ const Anchor& anchor) {
if (compareText.find(text) == compareText.end()) {
compareText.emplace(text, Anchors());
} else {
@@ -533,8 +608,8 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe
return false;
}
-// Analog of `addToLineVertexArray` in JS. This version doesn't need to build up a line array like the
-// JS version does, but it uses the same logic to calculate tile distances.
+// Analog of `addToLineVertexArray` in JS. This version doesn't need to build up a line array like
+// the JS version does, but it uses the same logic to calculate tile distances.
std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const Anchor& anchor) {
std::vector<float> tileDistances(line.size());
if (anchor.segment != -1) {
@@ -556,15 +631,21 @@ std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const
return tileDistances;
}
-void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIndex>&, std::unordered_map<std::string, LayerRenderData>& renderData, const bool firstLoad, const bool showCollisionBoxes) {
- auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio);
+void SymbolLayout::createBucket(const ImagePositions&,
+ std::unique_ptr<FeatureIndex>&,
+ std::unordered_map<std::string, LayerRenderData>& renderData,
+ const bool firstLoad,
+ const bool showCollisionBoxes) {
+ auto bucket = std::make_shared<SymbolBucket>(
+ 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<FeatureIn
optional<std::size_t> lastAddedSection;
if (singleLine) {
optional<std::size_t> 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<float> 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<float>());
+ 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<float>());
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_ptr<FeatureIn
if (showCollisionBoxes) {
addToDebugBuffers(*bucket);
}
- if (bucket->hasData()){
+ 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<float> 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<uint16_t>::max() ||
fabs(buffer.segments.back().sortKey - sortKey) > std::numeric_limits<float>::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<SymbolBucket::CollisionBuffer&>(bucket.collisionCircle) :
- static_cast<SymbolBucket::CollisionBuffer&>(bucket.collisionBox);
- for (const CollisionBox &box : feature.boxes) {
+ SymbolBucket::CollisionBuffer& collisionBuffer =
+ feature.alongLine
+ ? static_cast<SymbolBucket::CollisionBuffer&>(bucket.collisionCircle)
+ : static_cast<SymbolBucket::CollisionBuffer&>(bucket.collisionBox);
+ for (const CollisionBox& box : feature.boxes) {
auto& anchor = box.anchor;
- Point<float> tl{box.x1, box.y1};
- Point<float> tr{box.x2, box.y1};
- Point<float> bl{box.x1, box.y2};
- Point<float> br{box.x2, box.y2};
+ Point<float> tl{ box.x1, box.y1 };
+ Point<float> tr{ box.x2, box.y1 };
+ Point<float> bl{ box.x1, box.y2 };
+ Point<float> 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<uint16_t>::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<uint16_t>::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<std::reference_wrapper<SymbolInstance>> 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<SymbolInstance>& 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<SymbolInstance>& 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<float> shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.radialTextOffset, textBoxScale);
+ Point<float> 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<style::TextOptional>();
- const bool textWithoutIcon = !symbolInstance.hasIcon || layout.get<style::IconOptional>();
+ const bool iconWithoutText = !symbolInstance.commonData->hasText || layout.get<style::TextOptional>();
+ const bool textWithoutIcon = !symbolInstance.commonData->hasIcon || layout.get<style::IconOptional>();
// 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);