1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#pragma once
#include <mbgl/text/bidi.hpp>
#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/font_stack.hpp>
namespace mbgl {
struct SectionOptions {
SectionOptions(double scale_, FontStack fontStack_, optional<Color> textColor_ = nullopt)
: scale(scale_),
fontStackHash(FontStackHasher()(fontStack_)),
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;
};
/**
* A TaggedString is the shaping-code counterpart of the Formatted type
* Whereas Formatted matches the logical structure of a 'format' expression,
* a TaggedString represents the same data at a per-character level so that
* character-rearranging operations (e.g. BiDi) preserve formatting.
* Text is represented as:
* - A string of characters
* - A matching array of indices, pointing to:
* - An array of SectionsOptions, representing the evaluated formatting
* options of the original sections.
*
* Once the guts of a TaggedString have been re-arranged by BiDi, you can
* iterate over the contents in order, using getCharCodeAt and getSection
* to get the formatting options for each character in turn.
*/
struct TaggedString {
TaggedString() = default;
TaggedString(std::u16string text_, SectionOptions options)
: styledText(std::move(text_),
std::vector<uint8_t>(text_.size(), 0)) {
sections.push_back(std::move(options));
}
TaggedString(StyledText styledText_, std::vector<SectionOptions> sections_)
: styledText(std::move(styledText_))
, sections(std::move(sections_)) {
}
std::size_t length() const {
return styledText.first.length();
}
std::size_t sectionCount() const {
return sections.size();
}
bool empty() const {
return styledText.first.empty();
}
const SectionOptions& getSection(std::size_t index) const {
return sections.at(styledText.second.at(index));
}
char16_t getCharCodeAt(std::size_t index) const {
return styledText.first[index];
}
const std::u16string& rawText() const {
return styledText.first;
}
const StyledText& getStyledText() const {
return styledText;
}
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);
}
const std::vector<SectionOptions>& getSections() const {
return sections;
}
uint8_t getSectionIndex(std::size_t characterIndex) const {
return styledText.second.at(characterIndex);
}
double getMaxScale() const;
void trim();
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
|