summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-11-13 10:47:41 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-12-02 17:11:49 +0200
commita9c3b5a389a249a9ddb62250cdcb8f8edb2f7280 (patch)
tree822eb59b22229f0beed4d10e39089da036f29172
parenta01ecc92a079cb488d5f24d374d82e5fc34fe14b (diff)
downloadqtlocation-mapboxgl-a9c3b5a389a249a9ddb62250cdcb8f8edb2f7280.tar.gz
[core] Add evaluated images to styled text sections
-rw-r--r--src/mbgl/layout/symbol_layout.cpp31
-rw-r--r--src/mbgl/text/tagged_string.cpp40
-rw-r--r--src/mbgl/text/tagged_string.hpp23
-rw-r--r--test/text/tagged_string.test.cpp6
4 files changed, 76 insertions, 24 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index af0b1bd21b..54708d5549 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -146,27 +146,34 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
ft.formattedText = TaggedString();
for (const auto & section : formatted.sections) {
- std::string u8string = section.text;
- if (textTransform == TextTransformType::Uppercase) {
- u8string = platform::uppercase(u8string);
- } else if (textTransform == TextTransformType::Lowercase) {
- u8string = platform::lowercase(u8string);
- }
+ if (!section.image) {
+ 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::convertUTF8ToUTF16(u8string)),
- section.fontScale ? *section.fontScale : 1.0,
- section.fontStack ? *section.fontStack : baseFontStack,
- section.textColor);
+ ft.formattedText->addTextSection(applyArabicShaping(util::convertUTF8ToUTF16(u8string)),
+ section.fontScale ? *section.fontScale : 1.0,
+ section.fontStack ? *section.fontStack : baseFontStack,
+ section.textColor);
+ } else {
+ layoutParameters.imageDependencies.emplace(section.image->id(), ImageType::Icon);
+ ft.formattedText->addImageSection(section.image->id());
+ }
}
-
const bool canVerticalizeText = layout->get<TextRotationAlignment>() == AlignmentType::Map
&& layout->get<SymbolPlacement>() != SymbolPlacementType::Point
&& ft.formattedText->allowsVerticalWritingMode();
// Loop through all characters of this text and collect unique codepoints.
for (std::size_t j = 0; j < ft.formattedText->length(); j++) {
- const auto& sectionFontStack = formatted.sections[ft.formattedText->getSectionIndex(j)].fontStack;
+ const auto& section = formatted.sections[ft.formattedText->getSectionIndex(j)];
+ if (section.image) continue;
+
+ const auto& sectionFontStack = section.fontStack;
GlyphIDs& dependencies =
layoutParameters.glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack];
char16_t codePoint = ft.formattedText->getCharCodeAt(j);
diff --git a/src/mbgl/text/tagged_string.cpp b/src/mbgl/text/tagged_string.cpp
index e8a1c6f51f..83ccd610c2 100644
--- a/src/mbgl/text/tagged_string.cpp
+++ b/src/mbgl/text/tagged_string.cpp
@@ -1,16 +1,50 @@
-#include <mbgl/text/tagged_string.hpp>
#include <mbgl/math/minmax.hpp>
+#include <mbgl/text/tagged_string.hpp>
#include <mbgl/util/i18n.hpp>
+#include <mbgl/util/logging.hpp>
+
+namespace {
+char16_t PUAbegin = u'\uE000';
+char16_t PUAend = u'\uF8FF';
+} // namespace
namespace mbgl {
-
-void TaggedString::addSection(const std::u16string& sectionText, double scale, FontStack fontStack, optional<Color> textColor) {
+
+void TaggedString::addTextSection(const std::u16string& sectionText,
+ double scale,
+ FontStack fontStack,
+ optional<Color> textColor) {
styledText.first += sectionText;
sections.emplace_back(scale, fontStack, std::move(textColor));
styledText.second.resize(styledText.first.size(), sections.size() - 1);
supportsVerticalWritingMode = nullopt;
}
+void TaggedString::addImageSection(const std::string& imageID) {
+ const auto& nextImageSectionCharCode = getNextImageSectionCharCode();
+ if (!nextImageSectionCharCode) {
+ Log::Warning(Event::Style, "Exceeded maximum number of images in a label.");
+ return;
+ }
+
+ styledText.first += *nextImageSectionCharCode;
+ sections.emplace_back(imageID);
+ styledText.second.resize(styledText.first.size(), sections.size() - 1);
+}
+
+optional<char16_t> TaggedString::getNextImageSectionCharCode() {
+ if (imageSectionID == 0u) {
+ imageSectionID = PUAbegin;
+ return imageSectionID;
+ }
+
+ if (++imageSectionID > PUAend) {
+ return nullopt;
+ }
+
+ return imageSectionID;
+}
+
void TaggedString::trim() {
std::size_t beginningWhitespace = styledText.first.find_first_not_of(u" \t\n\v\f\r");
if (beginningWhitespace == std::u16string::npos) {
diff --git a/src/mbgl/text/tagged_string.hpp b/src/mbgl/text/tagged_string.hpp
index 698e539a45..fba3bbf412 100644
--- a/src/mbgl/text/tagged_string.hpp
+++ b/src/mbgl/text/tagged_string.hpp
@@ -13,11 +13,14 @@ struct SectionOptions {
fontStack(std::move(fontStack_)),
textColor(std::move(textColor_))
{}
-
+
+ explicit SectionOptions(std::string imageID_) : scale(1.0), imageID(std::move(imageID_)) {}
+
double scale;
FontStackHash fontStackHash;
FontStack fontStack;
optional<Color> textColor;
+ optional<std::string> imageID;
};
/**
@@ -76,11 +79,13 @@ struct TaggedString {
const StyledText& getStyledText() const {
return styledText;
}
-
- void addSection(const std::u16string& text,
- double scale,
- FontStack fontStack,
- optional<Color> textColor_ = nullopt);
+
+ void addTextSection(const std::u16string& text,
+ double scale,
+ FontStack fontStack,
+ optional<Color> textColor_ = nullopt);
+
+ void addImageSection(const std::string& imageID);
const SectionOptions& sectionAt(std::size_t index) const {
return sections.at(index);
@@ -101,9 +106,15 @@ struct TaggedString {
bool allowsVerticalWritingMode();
private:
+ optional<char16_t> getNextImageSectionCharCode();
+
+private:
StyledText styledText;
std::vector<SectionOptions> sections;
optional<bool> supportsVerticalWritingMode;
+ // Max number of images within a text is 6400 U+E000–U+F8FF
+ // that covers Basic Multilingual Plane Unicode Private Use Area (PUA).
+ char16_t imageSectionID = 0u;
};
} // namespace mbgl
diff --git a/test/text/tagged_string.test.cpp b/test/text/tagged_string.test.cpp
index da1141f00b..ebf10c47f4 100644
--- a/test/text/tagged_string.test.cpp
+++ b/test/text/tagged_string.test.cpp
@@ -11,9 +11,9 @@ TEST(TaggedString, Trim) {
EXPECT_EQ(basic.rawText(), u"trim that and not this");
TaggedString twoSections;
- twoSections.addSection(u" \t\ntrim that", 1.5f, {});
- twoSections.addSection(u" and not this \n\t", 0.5f, {});
-
+ twoSections.addTextSection(u" \t\ntrim that", 1.5f, {});
+ twoSections.addTextSection(u" and not this \n\t", 0.5f, {});
+
twoSections.trim();
EXPECT_EQ(twoSections.rawText(), u"trim that and not this");