[core] Add evaluated images to styled text sections
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user