diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-08 13:58:46 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-13 10:18:43 -0700 |
commit | 3270440f234570f1426c442898c2400e36608ebf (patch) | |
tree | dfc2330d74187a2503b244e632592cd984c0d84f /src/mbgl/layout | |
parent | f610e9bef969dc8d7ec1ea545e93919a03d98882 (diff) | |
download | qtlocation-mapboxgl-3270440f234570f1426c442898c2400e36608ebf.tar.gz |
[core] Per-tile glyph/icon atlases
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r-- | src/mbgl/layout/symbol_instance.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 81 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 9 |
4 files changed, 47 insertions, 51 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 8816f4c95c..ffb70c7ca2 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -19,7 +19,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const float iconBoxScale, const float iconPadding, const SymbolPlacementType iconPlacement, - const GlyphPositions& face, + const GlyphPositionMap& positions, const IndexedSubfeature& indexedFeature, const std::size_t featureIndex_) : point(anchor.point), @@ -38,11 +38,11 @@ SymbolInstance::SymbolInstance(Anchor& anchor, iconQuad = getIconQuad(anchor, *shapedIcon, line, layout, layoutTextSize, iconPlacement, shapedTextOrientations.first); } if (shapedTextOrientations.first) { - auto quads = getGlyphQuads(anchor, shapedTextOrientations.first, textBoxScale, line, layout, textPlacement, face); + auto quads = getGlyphQuads(anchor, shapedTextOrientations.first, textBoxScale, line, layout, textPlacement, positions); glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end()); } if (shapedTextOrientations.second) { - auto quads = getGlyphQuads(anchor, shapedTextOrientations.second, textBoxScale, line, layout, textPlacement, face); + auto quads = getGlyphQuads(anchor, shapedTextOrientations.second, textBoxScale, line, layout, textPlacement, positions); glyphQuads.insert(glyphQuads.end(), quads.begin(), quads.end()); } } diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 6a5d0c7cf3..f199d929df 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -26,7 +26,7 @@ public: const float iconBoxScale, const float iconPadding, style::SymbolPlacementType iconPlacement, - const GlyphPositions& face, + const GlyphPositionMap&, const IndexedSubfeature&, const std::size_t featureIndex); diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index b64fc4f66e..ed580bcb16 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -175,7 +175,8 @@ bool SymbolLayout::hasSymbolInstances() const { return !symbolInstances.empty(); } -void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) { +void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, + const ImageMap& imageMap, const ImagePositions& imagePositions) { float horizontalAlign = 0.5; float verticalAlign = 0.5; @@ -220,12 +221,13 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) { const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && layout.get<SymbolPlacement>() == SymbolPlacementType::Line; - auto glyphPositionsIt = glyphs.find(layout.get<TextFont>()); - if (glyphPositionsIt != glyphs.end()) { - glyphAtlas = makeGlyphAtlas(glyphPositionsIt->second); - } + auto glyphMapIt = glyphMap.find(layout.get<TextFont>()); + const Glyphs& glyphs = glyphMapIt != glyphMap.end() + ? glyphMapIt->second : Glyphs(); - imageAtlas = makeImageAtlas(images); + auto glyphPositionsIt = glyphPositions.find(layout.get<TextFont>()); + const GlyphPositionMap& glyphPositionMap = glyphPositionsIt != glyphPositions.end() + ? glyphPositionsIt->second : GlyphPositionMap(); for (auto it = features.begin(); it != features.end(); ++it) { auto& feature = *it; @@ -236,42 +238,39 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) { // if feature has text, shape the text if (feature.text) { - 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 */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get<TextLetterSpacing>() * oneEm : 0.0f, - /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), - /* 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); - } + 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 */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.get<TextLetterSpacing>() * oneEm : 0.0f, + /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), + /* verticalHeight */ oneEm, + /* writingMode */ writingMode, + /* bidirectional algorithm object */ bidi, + /* glyphs */ glyphs); + + 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); } } // if feature has icon, get sprite atlas position if (feature.icon) { - auto image = images.find(*feature.icon); - if (image != images.end()) { + auto image = imageMap.find(*feature.icon); + if (image != imageMap.end()) { shapedIcon = PositionedIcon::shapeIcon( - imageAtlas.positions.at(*feature.icon), + imagePositions.at(*feature.icon), layout.evaluate<IconOffset>(zoom, feature), layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); if (image->second->sdf) { @@ -287,7 +286,7 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) { // if either shapedText or icon position is present, add the feature if (shapedTextOrientations.first || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon); + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositionMap); } feature.geometry.clear(); @@ -299,7 +298,8 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) { void SymbolLayout::addFeature(const std::size_t index, const SymbolFeature& feature, const std::pair<Shaping, Shaping>& shapedTextOrientations, - optional<PositionedIcon> shapedIcon) { + optional<PositionedIcon> shapedIcon, + const GlyphPositionMap& glyphPositionMap) { const float minScale = 0.5f; const float glyphSize = 24.0f; @@ -356,7 +356,7 @@ void SymbolLayout::addFeature(const std::size_t index, addToBuffers, symbolInstances.size(), textBoxScale, textPadding, textPlacement, iconBoxScale, iconPadding, iconPlacement, - glyphAtlas.positions, indexedFeature, index); + glyphPositionMap, indexedFeature, index); }; const auto& type = feature.getType(); @@ -430,9 +430,6 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) { auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear); - bucket->text.atlasImage = glyphAtlas.image.clone(); - bucket->icon.atlasImage = imageAtlas.image.clone(); - // Calculate which labels can be shown and when they can be shown and // create the bufers used for rendering. diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 7d6f2319cd..b22c47c567 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -33,7 +33,8 @@ public: ImageDependencies&, GlyphDependencies&); - void prepare(const GlyphMap& glyphs, const ImageMap& icons); + void prepare(const GlyphMap&, const GlyphPositions&, + const ImageMap&, const ImagePositions&); std::unique_ptr<SymbolBucket> place(CollisionTile&); @@ -53,7 +54,8 @@ private: void addFeature(const size_t, const SymbolFeature&, const std::pair<Shaping, Shaping>& shapedTextOrientations, - optional<PositionedIcon> shapedIcon); + optional<PositionedIcon> shapedIcon, + const GlyphPositionMap&); bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&); std::map<std::u16string, std::vector<Anchor>> compareText; @@ -93,9 +95,6 @@ private: std::vector<SymbolInstance> symbolInstances; std::vector<SymbolFeature> features; - GlyphAtlas glyphAtlas; - ImageAtlas imageAtlas; - BiDi bidi; // Consider moving this up to geometry tile worker to reduce reinstantiation costs; use of BiDi/ubiditransform object must be constrained to one thread }; |