summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-11-13 11:50:43 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-12-02 17:11:49 +0200
commitf4f652063d9a9903d96bf6f32257a5e6fd6dbfe2 (patch)
treea0cfc90f23856f6c3a9ab0d193268db1df46b17f
parent34a9bc08ceefd695240047061fed41c591d30171 (diff)
downloadqtlocation-mapboxgl-f4f652063d9a9903d96bf6f32257a5e6fd6dbfe2.tar.gz
[core] Calculate line width and line breaks for images
-rw-r--r--src/mbgl/layout/symbol_layout.cpp2
-rw-r--r--src/mbgl/text/shaping.cpp55
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,