diff options
Diffstat (limited to 'src/mbgl/layout/symbol_layout.cpp')
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 90 |
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(); |