diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-11-13 11:50:43 +0200 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-12-02 17:11:49 +0200 |
commit | f4f652063d9a9903d96bf6f32257a5e6fd6dbfe2 (patch) | |
tree | a0cfc90f23856f6c3a9ab0d193268db1df46b17f | |
parent | 34a9bc08ceefd695240047061fed41c591d30171 (diff) | |
download | qtlocation-mapboxgl-f4f652063d9a9903d96bf6f32257a5e6fd6dbfe2.tar.gz |
[core] Calculate line width and line breaks for images
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/text/shaping.cpp | 55 |
2 files changed, 34 insertions, 23 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index c64a2d21d1..55de0d2a2b 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -367,7 +367,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions const Shaping result = getShaping( /* string */ formattedText, /* maxWidth: ems */ - isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f, + isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f, /* ems */ lineHeight, textAnchor, textJustify, diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 6a9c682cc6..9714a54c28 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -163,27 +163,43 @@ void justifyLine(std::vector<PositionedGlyph>& positionedGlyphs, } } +float getGlyphAdvance(char16_t codePoint, + const SectionOptions& section, + const GlyphMap& glyphMap, + const ImagePositions& imagePositions, + float layoutTextSize, + float spacing) { + if (!section.imageID) { + auto glyphs = glyphMap.find(section.fontStackHash); + if (glyphs == glyphMap.end()) { + return 0.0; + } + auto it = glyphs->second.find(codePoint); + if (it == glyphs->second.end() || !it->second) { + return 0.0; + } + return (*it->second)->metrics.advance * section.scale + spacing; + } else { + auto image = imagePositions.find(*section.imageID); + if (image == imagePositions.end()) { + return 0.0; + } + return image->second.displaySize()[0] * section.scale * util::ONE_EM / layoutTextSize + spacing; + } +} + float determineAverageLineWidth(const TaggedString& logicalInput, - const float spacing, + float spacing, float maxWidth, const GlyphMap& glyphMap, - const ImagePositions& /*imagePositions*/, - float /*layoutTextSize*/) { + const ImagePositions& imagePositions, + float layoutTextSize) { float totalWidth = 0; for (std::size_t i = 0; i < logicalInput.length(); i++) { const SectionOptions& section = logicalInput.getSection(i); char16_t codePoint = logicalInput.getCharCodeAt(i); - auto glyphs = glyphMap.find(section.fontStackHash); - if (glyphs == glyphMap.end()) { - continue; - } - auto it = glyphs->second.find(codePoint); - if (it == glyphs->second.end() || !it->second) { - continue; - } - - totalWidth += (*it->second)->metrics.advance * section.scale + spacing; + totalWidth += getGlyphAdvance(codePoint, section, glyphMap, imagePositions, layoutTextSize, spacing); } int32_t targetLineCount = ::fmax(1, std::ceil(totalWidth / maxWidth)); @@ -303,20 +319,15 @@ std::set<std::size_t> determineLineBreaks(const TaggedString& logicalInput, for (std::size_t i = 0; i < logicalInput.length(); i++) { const SectionOptions& section = logicalInput.getSection(i); char16_t codePoint = logicalInput.getCharCodeAt(i); - auto glyphs = glyphMap.find(section.fontStackHash); - if (glyphs == glyphMap.end()) { - continue; - } - auto it = glyphs->second.find(codePoint); - if (it != glyphs->second.end() && it->second && !util::i18n::isWhitespace(codePoint)) { - currentX += (*it->second)->metrics.advance * section.scale + spacing; + if (!util::i18n::isWhitespace(codePoint)) { + currentX += getGlyphAdvance(codePoint, section, glyphMap, imagePositions, layoutTextSize, spacing); } - + // Ideographic characters, spaces, and word-breaking punctuation that often appear without // surrounding spaces. if (i < logicalInput.length() - 1) { const bool allowsIdeographicBreak = util::i18n::allowsIdeographicBreaking(codePoint); - if (allowsIdeographicBreak || util::i18n::allowsWordBreaking(codePoint)) { + if (section.imageID || allowsIdeographicBreak || util::i18n::allowsWordBreaking(codePoint)) { const bool penalizableIdeographicBreak = allowsIdeographicBreak && hasServerSuggestedBreaks; const std::size_t nextIndex = i + 1; potentialBreaks.push_back(evaluateBreak(nextIndex, currentX, targetWidth, potentialBreaks, |