27#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
46 std::array<std::set<char32_t>, FS_END> glyphs{};
50 FontLoadReason GetLoadReason()
override {
return FontLoadReason::MissingFallback; }
52 inline void Insert(
FontSize fs,
char32_t c)
54 this->glyphs[fs].insert(c);
55 this->search_timeout.
Reset();
62 r.merge(this->glyphs[fs]);
71 auto &missing = this->glyphs[fs];
72 if (missing.empty())
continue;
78 if (!changed_fontsizes.Any())
return;
101 typename T::CharType *buff_begin =
new typename T::CharType[str.size() + 1];
103 line.
buffer = Layouter::LineCacheItem::Buffer(buff_begin, [](
void *p) {
delete[]
reinterpret_cast<T::CharType *
>(p); });
105 const typename T::CharType *buffer_last = buff_begin + str.size() + 1;
106 typename T::CharType *buff = buff_begin;
110 font_mapping.clear();
118 for (
auto it = view.begin(); it != view.end(); ) {
121 if (c ==
'\0' || c ==
'\n') {
124 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
126 }
else if (c == SCC_PUSH_COLOUR) {
128 }
else if (c == SCC_POP_COLOUR) {
130 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
134 if (!IsPrintable(c))
continue;
140 if constexpr (!T::SUPPORTS_RTL)
continue;
142 buff += T::AppendToBuffer(buff, buffer_last, c);
143 if (buff >= buffer_last)
break;
147 FontIndex font_index = FontCache::GetFontIndexForCharacter(state.
fontsize, c);
149 if (font_index == INVALID_FONT_INDEX) {
150 _missing_glyphs.Insert(state.
fontsize, c);
151 font_index = FontCache::GetDefaultFontIndex(state.
fontsize);
155 buff += T::AppendToBuffer(buff, buffer_last, c);
156 if (buff >= buffer_last)
break;
166 if (buff - buff_begin > 0 && (font_mapping.empty() || font_mapping.back().first != buff - buff_begin)) {
167 font_mapping.emplace_back(buff - buff_begin, f);
175 if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
176 font_mapping.emplace_back(buff - buff_begin, f);
179 if constexpr (!std::is_same_v<T, FallbackParagraphLayoutFactory>) {
181 if (std::ranges::all_of(font_mapping, [](
const auto &i) {
return i.second.GetFontCache().IsBuiltInFont(); })) {
186 line.
layout = T::GetParagraphLayout(buff_begin, buff, font_mapping);
198 FontState state(TC_INVALID, fontsize, FontCache::GetDefaultFontIndex(fontsize));
201 auto line_length = str.find_first_of(
'\n');
202 auto str_line = str.substr(0, line_length);
205 if (line.
layout !=
nullptr) {
212#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
213 if (line.
layout ==
nullptr) {
214 GetLayouter<ICUParagraphLayoutFactory>(line, str_line, state);
215 if (line.
layout ==
nullptr) {
216 state = std::move(old_state);
222 if (line.
layout ==
nullptr) {
223 GetLayouter<UniscribeParagraphLayoutFactory>(line, str_line, state);
224 if (line.
layout ==
nullptr) {
225 state = std::move(old_state);
231 if (line.
layout ==
nullptr) {
232 GetLayouter<CoreTextParagraphLayoutFactory>(line, str_line, state);
233 if (line.
layout ==
nullptr) {
234 state = std::move(old_state);
239 if (line.
layout ==
nullptr) {
240 GetLayouter<FallbackParagraphLayoutFactory>(line, str_line, state);
250 auto l = line.
layout->NextLine(maxw);
251 if (l ==
nullptr)
break;
258 this->push_back(l.get());
262 if (line_length == std::string_view::npos) {
267 str.remove_prefix(line_length + 1);
278 for (
const auto &l : *
this) {
279 d.width = std::max<uint>(d.width, l->GetWidth());
280 d.height += l->GetLeading();
290 if (ch >= SCC_BLUE && ch <= SCC_BLACK)
return true;
291 if (ch == SCC_PUSH_COLOUR)
return true;
292 if (ch == SCC_POP_COLOUR)
return true;
293 if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT)
return true;
306 const auto &line = this->front();
309 if (ch == this->
string.end()) {
322 const size_t offset = ch - this->
string.begin();
326 if (pos.GetByteOffset() != offset)
return initial_position;
328 for (
auto it = view.begin(); it < pos; ++it) {
337 size_t best_index = SIZE_MAX;
338 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
340 const auto &positions = run.GetPositions();
341 const auto &charmap = run.GetGlyphToCharMap();
343 auto itp = positions.begin();
344 for (
auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
345 const size_t cur_index =
static_cast<size_t>(*it);
347 if (cur_index == index)
return *itp;
353 if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
354 best_index = cur_index;
372 if (line_index >= this->size())
return -1;
374 const auto &line = this->at(line_index);
376 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
378 const auto &glyphs = run.GetGlyphs();
379 const auto &positions = run.GetPositions();
380 const auto &charmap = run.GetGlyphToCharMap();
382 for (
int i = 0; i < run.GetGlyphCount(); i++) {
384 if (glyphs[i] == 0xFFFF)
continue;
386 int begin_x = positions[i].left;
387 int end_x = positions[i].right + 1;
391 size_t index = charmap[i];
395 for (
auto it = view.begin(), end = view.end(); it != end; ++it) {
396 if (cur_idx == index)
return it.GetByteOffset();
413#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
426#if defined(WITH_UNISCRIBE)
427 UniscribeResetScriptCache(size);
429#if defined(WITH_COCOA)
445 linecache = std::make_unique<LineCache>(4096);
479 assert(pos <= str.size());
480 auto it_ch = str.begin() + pos;
482 Layouter layout(str, INT32_MAX, start_fontsize);
495 if (x < 0)
return -1;
497 Layouter layout(str, INT32_MAX, start_fontsize);
void UpdateAllVirtCoords()
Update the viewport coordinates of all signs.
static void LoadFontCaches(FontSizes fontsizes)
(Re)initialize the font cache related things, i.e.
static bool FindFallbackFont(const std::string &language_isocode, FontSizes fontsizes, class MissingGlyphSearcher *callback)
We would like to have a fallback font as the current one doesn't contain all characters we need.
Container with information about a font.
static void InitializeLayouter()
Initialize data needed for the ICU layouter.
The layouter performs all the layout work.
static void Initialize()
Perform initialization of layout engine.
Layouter(std::string_view str, int maxw=INT32_MAX, FontSize fontsize=FS_NORMAL)
Create a new layouter.
static void ResetFontCache(FontSize fs)
Reset cached font information.
ptrdiff_t GetCharAtPosition(int x, size_t line_index) const
Get the character that is at a pixel position in the first line of the layouted text.
ParagraphLayouter::Position GetCharPosition(std::string_view::const_iterator ch) const
Get the position of a character in the layout.
static std::unique_ptr< LineCache > linecache
Cache of ParagraphLayout lines.
static void ResetLineCache()
Clear line cache.
Dimension GetBounds()
Get the boundaries of this paragraph.
static LineCacheItem & GetCachedParagraphLayout(std::string_view str, const FontState &state)
Get reference to cache item.
A searcher for missing glyphs.
FontSizes fontsizes
Font sizes to search for.
Position of a glyph within a VisualRun.
Visual run contains data about the bit of text with the same font.
std::set< char32_t > GetRequiredGlyphs(FontSizes fontsizes) override
Get set of glyphs required for the current language.
A timeout timer will fire once after the interval.
void Reset()
Reset the timer, so it will fire again after the timeout.
Constant span of UTF-8 encoded data.
iterator GetIterAtByte(size_t offset) const
Create iterator pointing at codepoint, which occupies the byte position "offset".
Control codes that are embedded in the translation strings.
Functions related to debugging.
void LoadStringWidthTable(FontSizes fontsizes)
Initialize _stringwidth_table cache for the specified font sizes.
Functions related to the gfx engine.
ParagraphLayouter::Position GetCharPosInString(std::string_view str, size_t pos, FontSize start_fontsize)
Get the leading corner of a character in a single-line string relative to the start of the string.
static bool IsConsumedFormattingCode(char32_t ch)
Test whether a character is a non-printable formatting code.
static void GetLayouter(Layouter::LineCacheItem &line, std::string_view str, FontState &state)
Helper for getting a ParagraphLayouter of the given type.
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize)
Get the character from a string that is drawn at a specific position.
Functions related to laying out the texts.
std::vector< std::pair< int, Font > > FontMap
Mapping from index to font.
Functions related to laying out the texts as fallback.
Functions related to laying out the texts with ICU.
FontSize
Available font sizes.
constexpr FontSizes FONTSIZES_ALL
Mask of all possible font sizes.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
Functions related to low-level strings.
bool IsTextDirectionChar(char32_t c)
Is the given character a text direction character.
void MacOSResetScriptCache(FontSize size)
Delete CoreText font reference for a specific font size.
Functions related to localized text support on OSX.
Functions related to laying out text on Win32.
TextDirection _current_text_dir
Text direction of the currently selected language.
Functions related to OTTD's strings.
@ TD_LTR
Text is written left-to-right by default.
Dimensions (a width and height) of a rectangle in 2D.
Text drawing parameters, which can change while drawing a line, but are kept between multiple parts o...
void PushColour()
Push the current colour on to the stack.
void SetColour(TextColour c)
Switch to new colour c.
void PopColour()
Switch to and pop the last saved colour on the stack.
void SetFontSize(FontSize f)
Switch to using a new font f.
FontSize fontsize
Current font size.
FontIndex font_index
Current font index.
TextColour cur_colour
Current text colour.
FontMap runs
Accessed by our ParagraphLayout::nextLine.
Buffer buffer
Accessed by our ParagraphLayout::nextLine.
int cached_width
Width used for the cached layout.
std::vector< std::unique_ptr< const ParagraphLayouter::Line > > cached_layout
Cached results of line layouting.
FontState state_after
Font state after the line.
std::unique_ptr< ParagraphLayouter > layout
Layout of the line.
FontState state_before
Font state at the beginning of the line.
std::string str
Source string of the line (including colour and font size codes).
Definition of Interval and OneShot timers.
Definition of the Window system.
Handling of UTF-8 encoded data.
Functions related to (drawing on) viewports.
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Window functions not directly related to making/drawing windows.