summaryrefslogtreecommitdiff
path: root/src/mbgl/layout/symbol_instance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/layout/symbol_instance.cpp')
-rw-r--r--src/mbgl/layout/symbol_instance.cpp136
1 files changed, 94 insertions, 42 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 809aa2f451..133cdec698 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -18,20 +18,63 @@ const Shaping& getAnyShaping(const ShapedTextOrientations& shapedTextOrientation
} // namespace
+SymbolInstanceSharedData::SymbolInstanceSharedData(GeometryCoordinates line_,
+ const ShapedTextOrientations& shapedTextOrientations,
+ const optional<PositionedIcon>& shapedIcon,
+ const style::SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
+ const style::SymbolPlacementType textPlacement,
+ const std::array<float, 2>& textOffset,
+ const GlyphPositions& positions) : line(std::move(line_)) {
+ // 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) {
+ if (!shapedTextOrientations.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.center) {
+ initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center);
+ }
+
+ if (shapedTextOrientations.left) {
+ initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left);
+ }
+
+ if (shapedTextOrientations.vertical) {
+ verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions);
+ }
+}
+
+bool SymbolInstanceSharedData::empty() const {
+ return rightJustifiedGlyphQuads.empty() && centerJustifiedGlyphQuads.empty() && leftJustifiedGlyphQuads.empty() && verticalGlyphQuads.empty();
+}
+
SymbolInstance::SymbolInstance(Anchor& anchor_,
- GeometryCoordinates line_,
+ std::shared_ptr<SymbolInstanceSharedData> sharedData_,
const ShapedTextOrientations& shapedTextOrientations,
- optional<PositionedIcon> shapedIcon,
- const SymbolLayoutProperties::Evaluated& layout,
- const float layoutTextSize,
+ const optional<PositionedIcon>& shapedIcon,
const float textBoxScale_,
const float textPadding,
const SymbolPlacementType textPlacement,
- const std::array<float, 2> textOffset_,
+ const std::array<float, 2>& textOffset_,
const float iconBoxScale,
const float iconPadding,
- const std::array<float, 2> iconOffset_,
- const GlyphPositions& positions,
+ const std::array<float, 2>& iconOffset_,
const IndexedSubfeature& indexedFeature,
const std::size_t layoutFeatureIndex_,
const std::size_t dataFeatureIndex_,
@@ -39,15 +82,15 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
const float overscaling,
const float rotate,
float radialTextOffset_) :
+ sharedData(std::move(sharedData_)),
anchor(anchor_),
- line(line_),
- hasText(false),
+ // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap
+ hasText(!sharedData->empty()),
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),
+ textCollisionFeature(sharedData->line, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, rotate),
+ iconCollisionFeature(sharedData->line, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature, rotate),
writingModes(WritingModeType::None),
layoutFeatureIndex(layoutFeatureIndex_),
dataFeatureIndex(dataFeatureIndex_),
@@ -58,43 +101,52 @@ SymbolInstance::SymbolInstance(Anchor& anchor_,
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) {
+ rightJustifiedGlyphQuadsSize = sharedData->rightJustifiedGlyphQuads.size();
+ centerJustifiedGlyphQuadsSize = sharedData->centerJustifiedGlyphQuads.size();
+ leftJustifiedGlyphQuadsSize = sharedData->leftJustifiedGlyphQuads.size();
+ verticalGlyphQuadsSize = sharedData->verticalGlyphQuads.size();
+
+ if (rightJustifiedGlyphQuadsSize || centerJustifiedGlyphQuadsSize || leftJustifiedGlyphQuadsSize) {
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.center) {
- initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center);
+ if (verticalGlyphQuadsSize) {
+ writingModes |= WritingModeType::Vertical;
}
+}
- if (shapedTextOrientations.left) {
- initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left);
- }
+const GeometryCoordinates& SymbolInstance::line() const {
+ assert(sharedData);
+ return sharedData->line;
+}
- if (shapedTextOrientations.vertical) {
- writingModes |= WritingModeType::Vertical;
- verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions);
- }
+const SymbolQuads& SymbolInstance::rightJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->rightJustifiedGlyphQuads;
+}
- // '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();
+const SymbolQuads& SymbolInstance::leftJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->leftJustifiedGlyphQuads;
+}
+
+const SymbolQuads& SymbolInstance::centerJustifiedGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->centerJustifiedGlyphQuads;
+}
+
+const SymbolQuads& SymbolInstance::verticalGlyphQuads() const {
+ assert(sharedData);
+ return sharedData->verticalGlyphQuads;
+}
+
+const optional<SymbolQuad>& SymbolInstance::iconQuad() const {
+ assert(sharedData);
+ return sharedData->iconQuad;
+}
+
+void SymbolInstance::releaseSharedData() {
+ sharedData.reset();
}
optional<size_t> SymbolInstance::getDefaultHorizontalPlacedTextIndex() const {