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 (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
109 font_mapping.emplace_back(buff - buff_begin, f);
117 if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
118 font_mapping.emplace_back(buff - buff_begin, f);
120 line.
layout = T::GetParagraphLayout(buff_begin, buff, font_mapping);
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) {
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);
Font cache for basic fonts.
Container with information about a font.
Font(FontSize size, TextColour colour)
Construct a new 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.
static FontColourMap fonts[FS_END]
Cache of Font instances.
Layouter(std::string_view str, int maxw=INT32_MAX, FontSize fontsize=FS_NORMAL)
Create a new layouter.
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.
static void ResetFontCache(FontSize size)
Reset cached font information.
ParagraphLayouter::Position GetCharPosition(std::string_view::const_iterator ch) const
Get the position of a character in the layout.
static Font * GetFont(FontSize size, TextColour colour)
Get a static font instance.
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.
static LineCache * linecache
Cache of ParagraphLayout lines.
static void ReduceLineCache()
Reduce the size of linecache if necessary to prevent infinite growth.
Position of a glyph within a VisualRun.
Visual run contains data about the bit of text with the same font.
Control codes that are embedded in the translation strings.
Functions related to debugging.
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.
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
Get the leading corner of a character in a single-line string relative to the start of the string.
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.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
constexpr bool IsInsideMM(const 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.
void free(const void *ptr)
Version of the standard free that accepts const pointers.
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.
TextColour cur_colour
Current text colour.
FontMap runs
Accessed by our ParagraphLayout::nextLine.
void * buffer
Accessed by our ParagraphLayout::nextLine.
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).
Coordinates of a point in 2D.