20 #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
50 assert(size < FS_END);
67 typename T::CharType *buff_begin = MallocT<typename T::CharType>(str.size() + 1);
68 const typename T::CharType *buffer_last = buff_begin + str.size() + 1;
69 typename T::CharType *buff = buff_begin;
76 auto cur = str.begin();
83 for (; buff < buffer_last && cur != str.end();) {
84 char32_t c = Utf8Consume(cur);
85 if (c ==
'\0' || c ==
'\n') {
88 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
90 }
else if (c == SCC_PUSH_COLOUR) {
92 }
else if (c == SCC_POP_COLOUR) {
94 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
98 if (!IsPrintable(c))
continue;
103 buff += T::AppendToBuffer(buff, buffer_last, c);
107 if (fontMapping.count(buff - buff_begin) == 0) {
108 fontMapping[buff - buff_begin] = f;
116 if (fontMapping.count(buff - buff_begin) == 0) {
117 fontMapping[buff - buff_begin] = f;
119 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()) {
234 Point p = { line->GetWidth(), 0 };
241 auto str = this->
string.begin();
243 char32_t c = Utf8Consume(str);
248 static const std::vector<Point> zero = { {0, 0} };
249 auto position = zero.begin();
252 if (str != ch)
return *position;
257 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
259 const auto &positions = run.GetPositions();
260 const auto &charmap = run.GetGlyphToCharMap();
263 if ((
size_t)charmap.front() > index)
return *position;
265 position = positions.begin();
266 for (
auto it = charmap.begin(); it != charmap.end(); ) {
268 if ((
size_t)*it == index)
return *position;
270 if (it == charmap.end())
break;
273 if ((
size_t)*it > index)
return *position;
290 if (line_index >= this->size())
return -1;
292 const auto &line = this->at(line_index);
294 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
296 const auto &glyphs = run.GetGlyphs();
297 const auto &positions = run.GetPositions();
298 const auto &charmap = run.GetGlyphToCharMap();
300 for (
int i = 0; i < run.GetGlyphCount(); i++) {
302 if (glyphs[i] == 0xFFFF)
continue;
304 int begin_x = positions[i].x;
305 int end_x = positions[i + 1].x;
309 size_t index = charmap[i];
312 for (
auto str = this->
string.begin(); str != this->
string.end();) {
313 if (cur_idx == index)
return str - this->
string.begin();
315 char32_t c = Utf8Consume(str);
330 FontColourMap::iterator it =
fonts[size].find(colour);
331 if (it !=
fonts[size].end())
return it->second.get();
333 fonts[size][colour] = std::make_unique<Font>(size, colour);
334 return fonts[size][colour].get();
342 #if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
358 #if defined(WITH_UNISCRIBE)
359 UniscribeResetScriptCache(size);
361 #if defined(WITH_COCOA)
382 return match->second;