21 #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
51 assert(size < FS_END);
68 typename T::CharType *buff_begin = MallocT<typename T::CharType>(str.size() + 1);
69 const typename T::CharType *buffer_last = buff_begin + str.size() + 1;
70 typename T::CharType *buff = buff_begin;
77 auto cur = str.begin();
84 for (; buff < buffer_last && cur != str.end();) {
85 char32_t c = Utf8Consume(cur);
86 if (c ==
'\0' || c ==
'\n') {
89 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
91 }
else if (c == SCC_PUSH_COLOUR) {
93 }
else if (c == SCC_POP_COLOUR) {
95 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
99 if (!IsPrintable(c))
continue;
104 buff += T::AppendToBuffer(buff, buffer_last, c);
108 if (fontMapping.count(buff - buff_begin) == 0) {
109 fontMapping[buff - buff_begin] = f;
117 if (fontMapping.count(buff - buff_begin) == 0) {
118 fontMapping[buff - buff_begin] = f;
120 line.
layout = T::GetParagraphLayout(buff_begin, buff, fontMapping);
135 auto line_length = str.find_first_of(
'\n');
136 auto str_line = str.substr(0, line_length);
139 if (line.
layout !=
nullptr) {
146 #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
147 if (line.
layout ==
nullptr) {
148 GetLayouter<ICUParagraphLayoutFactory>(line, str_line, state);
149 if (line.
layout ==
nullptr) {
155 #ifdef WITH_UNISCRIBE
156 if (line.
layout ==
nullptr) {
157 GetLayouter<UniscribeParagraphLayoutFactory>(line, str_line, state);
158 if (line.
layout ==
nullptr) {
165 if (line.
layout ==
nullptr) {
166 GetLayouter<CoreTextParagraphLayoutFactory>(line, str_line, state);
167 if (line.
layout ==
nullptr) {
173 if (line.
layout ==
nullptr) {
174 GetLayouter<FallbackParagraphLayoutFactory>(line, str_line, state);
180 auto l = line.
layout->NextLine(maxw);
181 if (l ==
nullptr)
break;
182 this->push_back(std::move(l));
186 if (line_length == std::string_view::npos) {
191 str.remove_prefix(line_length + 1);
202 for (
const auto &l : *
this) {
203 d.width = std::max<uint>(d.width, l->GetWidth());
204 d.height += l->GetLeading();
214 if (ch >= SCC_BLUE && ch <= SCC_BLACK)
return true;
215 if (ch == SCC_PUSH_COLOUR)
return true;
216 if (ch == SCC_POP_COLOUR)
return true;
217 if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT)
return true;
230 const auto &line = this->front();
233 if (ch == this->
string.end()) {
241 auto str = this->
string.begin();
243 char32_t c = Utf8Consume(str);
252 if (str != ch)
return *position;
257 size_t best_index = SIZE_MAX;
258 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
260 const auto &positions = run.GetPositions();
261 const auto &charmap = run.GetGlyphToCharMap();
263 auto itp = positions.begin();
264 for (
auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
265 const size_t cur_index =
static_cast<size_t>(*it);
267 if (cur_index == index)
return *itp;
273 if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
274 best_index = cur_index;
292 if (line_index >= this->size())
return -1;
294 const auto &line = this->at(line_index);
296 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
298 const auto &glyphs = run.GetGlyphs();
299 const auto &positions = run.GetPositions();
300 const auto &charmap = run.GetGlyphToCharMap();
302 for (
int i = 0; i < run.GetGlyphCount(); i++) {
304 if (glyphs[i] == 0xFFFF)
continue;
306 int begin_x = positions[i].left;
307 int end_x = positions[i].right + 1;
311 size_t index = charmap[i];
314 for (
auto str = this->
string.begin(); str != this->
string.end();) {
315 if (cur_idx == index)
return str - this->
string.begin();
317 char32_t c = Utf8Consume(str);
332 FontColourMap::iterator it =
fonts[size].find(colour);
333 if (it !=
fonts[size].end())
return it->second.get();
335 fonts[size][colour] = std::make_unique<Font>(size, colour);
336 return fonts[size][colour].get();
344 #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
360 #if defined(WITH_UNISCRIBE)
361 UniscribeResetScriptCache(size);
363 #if defined(WITH_COCOA)
384 return match->second;
424 assert(ch >= str.data() && (ch - str.data()) <=
static_cast<ptrdiff_t
>(str.size()));
425 auto it_ch = str.begin() + (ch - str.data());
427 Layouter layout(str, INT32_MAX, start_fontsize);
440 if (x < 0)
return -1;
442 Layouter layout(str, INT32_MAX, start_fontsize);