From 34a9bc08ceefd695240047061fed41c591d30171 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Wed, 13 Nov 2019 11:22:26 +0200 Subject: [core] Pass images and evaluated layout text size to shaping --- src/mbgl/layout/symbol_layout.cpp | 28 ++++++++++++++++++------ src/mbgl/layout/symbol_layout.hpp | 2 ++ src/mbgl/text/shaping.cpp | 45 ++++++++++++++++++++++++++++----------- src/mbgl/text/shaping.hpp | 2 ++ test/text/shaping.test.cpp | 10 ++++++--- 5 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 54708d5549..c64a2d21d1 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -352,16 +352,22 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions ShapedTextOrientations shapedTextOrientations; optional shapedIcon; std::array textOffset{{0.0f, 0.0f}}; + const float layoutTextSize = layout->evaluate(zoom + 1, feature); + const float layoutIconSize = layout->evaluate(zoom + 1, feature); // if feature has text, shape the text if (feature.formattedText) { const float lineHeight = layout->get() * util::ONE_EM; const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout->evaluate(zoom, feature) * util::ONE_EM : 0.0f; - auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode, SymbolAnchorType textAnchor, TextJustifyType textJustify) { + auto applyShaping = [&](const TaggedString& formattedText, + WritingModeType writingMode, + SymbolAnchorType textAnchor, + TextJustifyType textJustify) { const Shaping result = getShaping( /* string */ formattedText, - /* maxWidth: ems */ isPointPlacement ? layout->evaluate(zoom, feature) * util::ONE_EM : 0.0f, + /* maxWidth: ems */ + isPointPlacement ? layout->evaluate(zoom, feature) * util::ONE_EM : 0.0f, /* ems */ lineHeight, textAnchor, textJustify, @@ -370,10 +376,13 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions /* writingMode */ writingMode, /* bidirectional algorithm object */ bidi, /* glyphs */ glyphMap, + /* images */ imagePositions, + layoutTextSize, allowVerticalPlacement); return result; }; + const std::vector variableTextAnchor = layout->evaluate(zoom, feature); const SymbolAnchorType textAnchor = layout->evaluate(zoom, feature); if (variableTextAnchor.empty()) { @@ -475,7 +484,15 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if either shapedText or icon position is present, add the feature if (getDefaultHorizontalShaping(shapedTextOrientations) || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, std::move(shapedIcon), glyphPositions, textOffset, iconType); + addFeature(std::distance(features.begin(), it), + feature, + shapedTextOrientations, + std::move(shapedIcon), + glyphPositions, + textOffset, + layoutTextSize, + layoutIconSize, + iconType); } feature.geometry.clear(); @@ -490,13 +507,12 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, optional shapedIcon, const GlyphPositions& glyphPositions, std::array textOffset, + float layoutTextSize, + float layoutIconSize, const SymbolContent iconType) { const float minScale = 0.5f; const float glyphSize = 24.0f; - const float layoutTextSize = layout->evaluate(zoom + 1, feature); - const float layoutIconSize = layout->evaluate(zoom + 1, feature); - const std::array iconOffset = layout->evaluate(zoom, feature); // To reduce the number of labels that jump around when zooming we need diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 2b99c2fa24..804bc39741 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -62,6 +62,8 @@ private: optional shapedIcon, const GlyphPositions&, std::array textOffset, + float layoutTextSize, + float layoutIconSize, const SymbolContent iconType); bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&); diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 8eb885af5d..6a9c682cc6 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -166,7 +166,9 @@ void justifyLine(std::vector& positionedGlyphs, float determineAverageLineWidth(const TaggedString& logicalInput, const float spacing, float maxWidth, - const GlyphMap& glyphMap) { + const GlyphMap& glyphMap, + const ImagePositions& /*imagePositions*/, + float /*layoutTextSize*/) { float totalWidth = 0; for (std::size_t i = 0; i < logicalInput.length(); i++) { @@ -279,7 +281,9 @@ std::set leastBadBreaks(const PotentialBreak& lastLineBreak) { std::set determineLineBreaks(const TaggedString& logicalInput, const float spacing, float maxWidth, - const GlyphMap& glyphMap) { + const GlyphMap& glyphMap, + const ImagePositions& imagePositions, + float layoutTextSize) { if (!maxWidth) { return {}; } @@ -287,9 +291,10 @@ std::set determineLineBreaks(const TaggedString& logicalInput, if (logicalInput.empty()) { return {}; } - - const float targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap); - + + const float targetWidth = + determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphMap, imagePositions, layoutTextSize); + std::list potentialBreaks; float currentX = 0; // Find first occurance of zero width space (ZWSP) character. @@ -332,6 +337,8 @@ void shapeLines(Shaping& shaping, const style::TextJustifyType textJustify, const WritingModeType writingMode, const GlyphMap& glyphMap, + const ImagePositions& /*imagePositions*/, + float /*layoutTextSize*/, bool allowVerticalPlacement) { float x = 0; float y = Shaping::yOffset; @@ -425,27 +432,39 @@ const Shaping getShaping(const TaggedString& formattedString, const WritingModeType writingMode, BiDi& bidi, const GlyphMap& glyphs, + const ImagePositions& imagePositions, + float layoutTextSize, bool allowVerticalPlacement) { std::vector reorderedLines; if (formattedString.sectionCount() == 1) { - auto untaggedLines = bidi.processText(formattedString.rawText(), - determineLineBreaks(formattedString, spacing, maxWidth, glyphs)); + auto untaggedLines = bidi.processText( + formattedString.rawText(), + determineLineBreaks(formattedString, spacing, maxWidth, glyphs, imagePositions, layoutTextSize)); for (const auto& line : untaggedLines) { reorderedLines.emplace_back(line, formattedString.sectionAt(0)); } } else { - auto processedLines = bidi.processStyledText(formattedString.getStyledText(), - determineLineBreaks(formattedString, spacing, maxWidth, glyphs)); + auto processedLines = bidi.processStyledText( + formattedString.getStyledText(), + determineLineBreaks(formattedString, spacing, maxWidth, glyphs, imagePositions, layoutTextSize)); for (const auto& line : processedLines) { reorderedLines.emplace_back(line, formattedString.getSections()); } } Shaping shaping(translate[0], translate[1], writingMode, reorderedLines.size()); - shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor, - textJustify, writingMode, glyphs, allowVerticalPlacement); - + shapeLines(shaping, + reorderedLines, + spacing, + lineHeight, + textAnchor, + textJustify, + writingMode, + glyphs, + imagePositions, + layoutTextSize, + allowVerticalPlacement); + return shaping; } - } // namespace mbgl diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index 6ed1b5cb0e..ac608563ff 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -69,6 +69,8 @@ const Shaping getShaping(const TaggedString& string, const WritingModeType, BiDi& bidi, const GlyphMap& glyphs, + const ImagePositions& imagePositions, + float layoutTextSize, bool allowVerticalPlacement); } // namespace mbgl diff --git a/test/text/shaping.test.cpp b/test/text/shaping.test.cpp index b22cd7da36..c4d2ef7fc4 100644 --- a/test/text/shaping.test.cpp +++ b/test/text/shaping.test.cpp @@ -26,17 +26,21 @@ TEST(Shaping, ZWSP) { { FontStackHasher()(fontStack), {{u'δΈ­', std::move(immutableGlyph)}} } }; - const auto testGetShaping = [&] (const TaggedString& string, unsigned maxWidthInChars) { + ImagePositions imagePositions; + + const auto testGetShaping = [&](const TaggedString& string, unsigned maxWidthInChars) { return getShaping(string, maxWidthInChars * ONE_EM, - ONE_EM, // lineHeight + ONE_EM, // lineHeight style::SymbolAnchorType::Center, style::TextJustifyType::Center, - 0, // spacing + 0, // spacing {{0.0f, 0.0f}}, // translate WritingModeType::Horizontal, bidi, glyphs, + imagePositions, + 16.0, /*allowVerticalPlacement*/ false); }; -- cgit v1.2.1