[core] Add evaluated images to styled text sections

This commit is contained in:
Alexander Shalamov
2019-11-13 10:47:41 +02:00
parent a01ecc92a0
commit a9c3b5a389
4 changed files with 76 additions and 24 deletions

View File

@@ -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->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());
}
ft.formattedText->addSection(applyArabicShaping(util::convertUTF8ToUTF16(u8string)),
section.fontScale ? *section.fontScale : 1.0,
section.fontStack ? *section.fontStack : baseFontStack,
section.textColor);
}
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);

View File

@@ -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) {

View File

@@ -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);
@@ -100,10 +105,16 @@ struct TaggedString {
void verticalizePunctuation();
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

View File

@@ -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");