diff options
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r-- | src/mbgl/layout/merge_lines.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_feature.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 80 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 2 |
6 files changed, 53 insertions, 46 deletions
diff --git a/src/mbgl/layout/merge_lines.cpp b/src/mbgl/layout/merge_lines.cpp index 807ecb868f..2a3afa42b2 100644 --- a/src/mbgl/layout/merge_lines.cpp +++ b/src/mbgl/layout/merge_lines.cpp @@ -57,12 +57,14 @@ void mergeLines(std::vector<SymbolFeature>& features) { SymbolFeature& feature = features[k]; GeometryCollection& geometry = feature.geometry; - if (!feature.text || geometry.empty() || geometry[0].empty()) { + if (!feature.formattedText || geometry.empty() || geometry[0].empty()) { continue; } + + // TODO: Key should include formatting options (see https://github.com/mapbox/mapbox-gl-js/issues/3645) - const size_t leftKey = getKey(*feature.text, geometry[0].front()); - const size_t rightKey = getKey(*feature.text, geometry[0].back()); + const size_t leftKey = getKey(feature.formattedText->rawText(), geometry[0].front()); + const size_t rightKey = getKey(feature.formattedText->rawText(), geometry[0].back()); const auto left = rightIndex.find(leftKey); const auto right = leftIndex.find(rightKey); @@ -75,7 +77,7 @@ void mergeLines(std::vector<SymbolFeature>& features) { leftIndex.erase(leftKey); rightIndex.erase(rightKey); - rightIndex[getKey(*feature.text, features[i].geometry[0].back())] = i; + rightIndex[getKey(feature.formattedText->rawText(), features[i].geometry[0].back())] = i; } else if (left != rightIndex.end()) { // found mergeable line adjacent to the start of the current line, merge diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index f4dc1680bc..ff498f3c2a 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -2,6 +2,7 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/util/optional.hpp> +#include <mbgl/text/tagged_string.hpp> #include <array> #include <string> @@ -23,7 +24,7 @@ public: std::unique_ptr<GeometryTileFeature> feature; GeometryCollection geometry; - optional<std::u16string> text; + optional<TaggedString> formattedText; optional<std::string> icon; std::size_t index; }; diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index a9b4b929ec..2d60020dd4 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -18,7 +18,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, const float iconBoxScale, const float iconPadding, const std::array<float, 2> iconOffset_, - const GlyphPositionMap& positions, + const GlyphPositions& positions, const IndexedSubfeature& indexedFeature, const std::size_t layoutFeatureIndex_, const std::size_t dataFeatureIndex_, diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index ae79311790..6be19a0595 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, const std::array<float, 2> iconOffset, - const GlyphPositionMap&, + const GlyphPositions&, const IndexedSubfeature&, const std::size_t layoutFeatureIndex, const std::size_t dataFeatureIndex, diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 74abd74f01..f4a55a1f91 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -108,28 +108,40 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, ft.index = i; if (hasText) { - std::string u8string = layout.evaluate<TextField>(zoom, ft); - + auto formatted = layout.evaluate<TextField>(zoom, ft); auto textTransform = layout.evaluate<TextTransform>(zoom, ft); - if (textTransform == TextTransformType::Uppercase) { - u8string = platform::uppercase(u8string); - } else if (textTransform == TextTransformType::Lowercase) { - u8string = platform::lowercase(u8string); + FontStack baseFontStack = layout.evaluate<TextFont>(zoom, ft); + FontStackHash baseFontStackHash = FontStackHasher()(baseFontStack); + + ft.formattedText = TaggedString(); + for (std::size_t j = 0; j < formatted.sections.size(); j++) { + const auto& section = formatted.sections[j]; + std::string u8string = section.text; + if (textTransform == TextTransformType::Uppercase) { + u8string = platform::uppercase(u8string); + } else if (textTransform == TextTransformType::Lowercase) { + u8string = platform::lowercase(u8string); + } + + ft.formattedText->addSection(applyArabicShaping(util::utf8_to_utf16::convert(u8string)), + section.fontScale ? *section.fontScale : 1.0, + section.fontStack ? FontStackHasher()(*section.fontStack) : baseFontStackHash); + } - ft.text = applyArabicShaping(util::utf8_to_utf16::convert(u8string)); + const bool canVerticalizeText = layout.get<TextRotationAlignment>() == AlignmentType::Map && layout.get<SymbolPlacement>() != SymbolPlacementType::Point - && util::i18n::allowsVerticalWritingMode(*ft.text); - - FontStack fontStack = layout.evaluate<TextFont>(zoom, ft); - GlyphIDs& dependencies = glyphDependencies[fontStack]; - + && util::i18n::allowsVerticalWritingMode(ft.formattedText->rawText()); + // Loop through all characters of this text and collect unique codepoints. - for (char16_t chr : *ft.text) { - dependencies.insert(chr); + 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]; + char16_t codePoint = ft.formattedText->getCharCodeAt(j); + dependencies.insert(codePoint); if (canVerticalizeText) { - if (char16_t verticalChr = util::i18n::verticalizePunctuation(chr)) { + if (char16_t verticalChr = util::i18n::verticalizePunctuation(codePoint)) { dependencies.insert(verticalChr); } } @@ -141,7 +153,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, imageDependencies.emplace(*ft.icon, ImageType::Icon); } - if (ft.text || ft.icon) { + if (ft.formattedText || ft.icon) { features.push_back(std::move(ft)); } } @@ -168,44 +180,35 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions auto& feature = *it; if (feature.geometry.empty()) continue; - FontStack fontStack = layout.evaluate<TextFont>(zoom, feature); - - auto glyphMapIt = glyphMap.find(fontStack); - const Glyphs& glyphs = glyphMapIt != glyphMap.end() - ? glyphMapIt->second : Glyphs(); - - auto glyphPositionsIt = glyphPositions.find(fontStack); - const GlyphPositionMap& glyphPositionMap = glyphPositionsIt != glyphPositions.end() - ? glyphPositionsIt->second : GlyphPositionMap(); - std::pair<Shaping, Shaping> shapedTextOrientations; optional<PositionedIcon> shapedIcon; // if feature has text, shape the text - if (feature.text) { - auto applyShaping = [&] (const std::u16string& text, WritingModeType writingMode) { + if (feature.formattedText) { + auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode) { const float oneEm = 24.0f; const Shaping result = getShaping( - /* string */ text, + /* string */ formattedText, /* maxWidth: ems */ layout.get<SymbolPlacement>() == SymbolPlacementType::Point ? layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0, /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), /* justify */ layout.evaluate<TextJustify>(zoom, feature), - /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * oneEm : 0.0f, + /* spacing: ems */ util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * 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); + /* glyphs */ glyphMap); return result; }; - shapedTextOrientations.first = applyShaping(*feature.text, WritingModeType::Horizontal); + shapedTextOrientations.first = applyShaping(*feature.formattedText, WritingModeType::Horizontal); - if (util::i18n::allowsVerticalWritingMode(*feature.text) && textAlongLine) { - shapedTextOrientations.second = applyShaping(util::i18n::verticalizePunctuation(*feature.text), WritingModeType::Vertical); + if (util::i18n::allowsVerticalWritingMode(feature.formattedText->rawText()) && textAlongLine) { + feature.formattedText->verticalizePunctuation(); + shapedTextOrientations.second = applyShaping(*feature.formattedText, WritingModeType::Vertical); } } @@ -231,7 +234,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if either shapedText or icon position is present, add the feature if (shapedTextOrientations.first || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositionMap); + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositions); } feature.geometry.clear(); @@ -244,7 +247,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const SymbolFeature& feature, const std::pair<Shaping, Shaping>& shapedTextOrientations, optional<PositionedIcon> shapedIcon, - const GlyphPositionMap& glyphPositionMap) { + const GlyphPositions& glyphPositions) { const float minScale = 0.5f; const float glyphSize = 24.0f; @@ -287,7 +290,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, layout.evaluate(zoom, feature), layoutTextSize, textBoxScale, textPadding, textPlacement, textOffset, iconBoxScale, iconPadding, iconOffset, - glyphPositionMap, indexedFeature, layoutFeatureIndex, feature.index, feature.text.value_or(std::u16string()), overscaling); + glyphPositions, indexedFeature, layoutFeatureIndex, feature.index, + feature.formattedText ? feature.formattedText->rawText() : std::u16string(), overscaling); } }; @@ -308,7 +312,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, overscaling); for (auto& anchor : anchors) { - if (!feature.text || !anchorIsTooClose(*feature.text, textRepeatDistance, anchor)) { + if (!feature.formattedText || !anchorIsTooClose(feature.formattedText->rawText(), textRepeatDistance, anchor)) { addSymbolInstance(line, anchor); } } diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index b866703e6c..7045eebc22 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -55,7 +55,7 @@ private: const SymbolFeature&, const std::pair<Shaping, Shaping>& shapedTextOrientations, optional<PositionedIcon> shapedIcon, - const GlyphPositionMap&); + const GlyphPositions&); bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&); std::map<std::u16string, std::vector<Anchor>> compareText; |