summaryrefslogtreecommitdiff
path: root/src/mbgl/layout/symbol_layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/layout/symbol_layout.cpp')
-rw-r--r--src/mbgl/layout/symbol_layout.cpp90
1 files changed, 44 insertions, 46 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 3a2c082ad8..513a5e071e 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -7,10 +7,9 @@
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/get_anchors.hpp>
-#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/collision_tile.hpp>
+#include <mbgl/text/shaping.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/utf.hpp>
#include <mbgl/util/token.hpp>
@@ -33,7 +32,8 @@ using namespace style;
SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const std::vector<const Layer*>& layers,
const GeometryTileLayer& sourceLayer,
- SpriteAtlas& spriteAtlas_)
+ SpriteAtlas& spriteAtlas_,
+ GlyphDependencies& glyphDependencies)
: sourceLayerName(sourceLayer.getName()),
bucketName(layers.at(0)->getID()),
overscaling(parameters.tileID.overscaleFactor()),
@@ -93,7 +93,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
));
}
- // Determine and load glyph ranges
+ // Determine glyph dependencies
const size_t featureCount = sourceLayer.featureCount();
for (size_t i = 0; i < featureCount; ++i) {
auto feature = sourceLayer.getFeature(i);
@@ -139,9 +139,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
// Loop through all characters of this text and collect unique codepoints.
for (char16_t chr : *ft.text) {
- ranges.insert(getGlyphRange(chr));
+ glyphDependencies[layout.get<TextFont>()].insert(chr);
if (char16_t verticalChr = util::i18n::verticalizePunctuation(chr)) {
- ranges.insert(getGlyphRange(verticalChr));
+ glyphDependencies[layout.get<TextFont>()].insert(verticalChr);
}
}
}
@@ -164,13 +164,13 @@ bool SymbolLayout::hasSymbolInstances() const {
return !symbolInstances.empty();
}
-bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) {
- const bool hasTextField = layout.get<TextField>().match(
- [&] (const std::string& s) { return !s.empty(); },
- [&] (const auto&) { return true; }
- );
-
- if (hasTextField && !layout.get<TextFont>().empty() && !glyphAtlas.hasGlyphRanges(layout.get<TextFont>(), ranges)) {
+bool SymbolLayout::canPrepare(const GlyphPositionMap& glyphPositions) {
+ // TODO: This is a needlessly complex way to check if we can move to the next step, we really just want to wait until
+ // we've gotten a reply from 'getGlyphs'. I'm just keeping this in place here to reduce the number of moving parts in the refactor
+ const bool hasTextField = layout.get<TextField>().match([&] (const std::string& s) { return !s.empty(); },
+ [&] (const auto&) { return true; } );
+
+ if (hasTextField && glyphPositions.empty()) {
return false;
}
@@ -181,8 +181,7 @@ bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) {
return true;
}
-void SymbolLayout::prepare(uintptr_t tileUID,
- GlyphAtlas& glyphAtlas) {
+void SymbolLayout::prepare(const GlyphPositionMap& glyphs) {
float horizontalAlign = 0.5;
float verticalAlign = 0.5;
@@ -224,7 +223,6 @@ void SymbolLayout::prepare(uintptr_t tileUID,
layout.get<TextJustify>() == TextJustifyType::Left ? 0 :
0.5;
- auto glyphSet = glyphAtlas.getGlyphSet(layout.get<TextFont>());
const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map &&
layout.get<SymbolPlacement>() == SymbolPlacementType::Line;
@@ -239,34 +237,33 @@ void SymbolLayout::prepare(uintptr_t tileUID,
// if feature has text, shape the text
if (feature.text) {
- auto getShaping = [&] (const std::u16string& text, WritingModeType writingMode) {
- const float oneEm = 24.0f;
- const Shaping result = glyphSet->getShaping(
- /* string */ text,
- /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ?
- layout.get<TextMaxWidth>() * oneEm : 0,
- /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm,
- /* horizontalAlign */ horizontalAlign,
- /* verticalAlign */ verticalAlign,
- /* justify */ justify,
- /* spacing: ems */ layout.get<TextLetterSpacing>() * oneEm,
- /* translate */ Point<float>(layout.get<TextOffset>()[0], layout.get<TextOffset>()[1]),
- /* verticalHeight */ oneEm,
- /* writingMode */ writingMode,
- /* bidirectional algorithm object */ bidi);
-
- // Add the glyphs we need for this label to the glyph atlas.
- if (result) {
- glyphAtlas.addGlyphs(tileUID, text, layout.get<TextFont>(), glyphSet, face);
+ auto glyphPositions = glyphs.find(layout.get<TextFont>());
+ if (glyphPositions != glyphs.end()) { // If there are no glyphs available for this feature, skip shaping
+ auto applyShaping = [&] (const std::u16string& text, WritingModeType writingMode) {
+ const float oneEm = 24.0f;
+ const Shaping result = getShaping(
+ /* string */ text,
+ /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ?
+ layout.get<TextMaxWidth>() * oneEm : 0,
+ /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm,
+ /* horizontalAlign */ horizontalAlign,
+ /* verticalAlign */ verticalAlign,
+ /* justify */ justify,
+ /* spacing: ems */ layout.get<TextLetterSpacing>() * oneEm,
+ /* translate */ Point<float>(layout.get<TextOffset>()[0], layout.get<TextOffset>()[1]),
+ /* verticalHeight */ oneEm,
+ /* writingMode */ writingMode,
+ /* bidirectional algorithm object */ bidi,
+ /* glyphs */ glyphPositions->second);
+
+ return result;
+ };
+
+ shapedTextOrientations.first = applyShaping(*feature.text, WritingModeType::Horizontal);
+
+ if (util::i18n::allowsVerticalWritingMode(*feature.text) && textAlongLine) {
+ shapedTextOrientations.second = applyShaping(util::i18n::verticalizePunctuation(*feature.text), WritingModeType::Vertical);
}
-
- return result;
- };
-
- shapedTextOrientations.first = getShaping(*feature.text, WritingModeType::Horizontal);
-
- if (util::i18n::allowsVerticalWritingMode(*feature.text) && textAlongLine) {
- shapedTextOrientations.second = getShaping(util::i18n::verticalizePunctuation(*feature.text), WritingModeType::Vertical);
}
}
@@ -291,7 +288,8 @@ void SymbolLayout::prepare(uintptr_t tileUID,
// if either shapedText or icon position is present, add the feature
if (shapedTextOrientations.first || shapedIcon) {
- addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, face);
+ auto glyphPositionsIt = glyphs.find(layout.get<TextFont>());
+ addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositionsIt == glyphs.end() ? GlyphPositions() : glyphPositionsIt->second);
}
feature.geometry.clear();
@@ -304,7 +302,7 @@ void SymbolLayout::addFeature(const std::size_t index,
const SymbolFeature& feature,
const std::pair<Shaping, Shaping>& shapedTextOrientations,
const PositionedIcon& shapedIcon,
- const GlyphPositions& face) {
+ const GlyphPositions& glyphs) {
const float minScale = 0.5f;
const float glyphSize = 24.0f;
@@ -350,7 +348,7 @@ void SymbolLayout::addFeature(const std::size_t index,
symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout, addToBuffers, symbolInstances.size(),
textBoxScale, textPadding, textPlacement,
iconBoxScale, iconPadding, iconPlacement,
- face, indexedFeature, index);
+ glyphs, indexedFeature, index);
};
const auto& type = feature.getType();