22#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
52 assert(size < FS_END);
67 typename T::CharType *buff_begin =
new typename T::CharType[str.size() + 1];
69 line.
buffer = Layouter::LineCacheItem::Buffer(buff_begin, [](
void *p) {
delete[]
reinterpret_cast<T::CharType *
>(p); });
71 const typename T::CharType *buffer_last = buff_begin + str.size() + 1;
72 typename T::CharType *buff = buff_begin;
84 if (c ==
'\0' || c ==
'\n') {
87 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
89 }
else if (c == SCC_PUSH_COLOUR) {
91 }
else if (c == SCC_POP_COLOUR) {
93 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
97 if (!IsPrintable(c))
continue;
102 buff += T::AppendToBuffer(buff, buffer_last, c);
103 if (buff >= buffer_last)
break;
107 if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
108 font_mapping.emplace_back(buff - buff_begin, f);
116 if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
117 font_mapping.emplace_back(buff - buff_begin, f);
119 line.
layout = T::GetParagraphLayout(buff_begin, buff, font_mapping);
134 auto line_length = str.find_first_of(
'\n');
135 auto str_line = str.substr(0, line_length);
138 if (line.
layout !=
nullptr) {
145#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
146 if (line.
layout ==
nullptr) {
147 GetLayouter<ICUParagraphLayoutFactory>(line, str_line, state);
148 if (line.
layout ==
nullptr) {
149 state = std::move(old_state);
155 if (line.
layout ==
nullptr) {
156 GetLayouter<UniscribeParagraphLayoutFactory>(line, str_line, state);
157 if (line.
layout ==
nullptr) {
158 state = std::move(old_state);
164 if (line.
layout ==
nullptr) {
165 GetLayouter<CoreTextParagraphLayoutFactory>(line, str_line, state);
166 if (line.
layout ==
nullptr) {
167 state = std::move(old_state);
172 if (line.
layout ==
nullptr) {
173 GetLayouter<FallbackParagraphLayoutFactory>(line, str_line, state);
179 auto l = line.
layout->NextLine(maxw);
180 if (l ==
nullptr)
break;
181 this->push_back(std::move(l));
185 if (line_length == std::string_view::npos) {
190 str.remove_prefix(line_length + 1);
201 for (
const auto &l : *
this) {
202 d.width = std::max<uint>(d.width, l->GetWidth());
203 d.height += l->GetLeading();
213 if (ch >= SCC_BLUE && ch <= SCC_BLACK)
return true;
214 if (ch == SCC_PUSH_COLOUR)
return true;
215 if (ch == SCC_POP_COLOUR)
return true;
216 if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT)
return true;
229 const auto &line = this->front();
232 if (ch == this->
string.end()) {
245 const size_t offset = ch - this->
string.begin();
249 if (pos.GetByteOffset() != offset)
return initial_position;
251 for (
auto it = view.begin(); it < pos; ++it) {
260 size_t best_index = SIZE_MAX;
261 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
263 const auto &positions = run.GetPositions();
264 const auto &charmap = run.GetGlyphToCharMap();
266 auto itp = positions.begin();
267 for (
auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
268 const size_t cur_index =
static_cast<size_t>(*it);
270 if (cur_index == index)
return *itp;
276 if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
277 best_index = cur_index;
295 if (line_index >= this->size())
return -1;
297 const auto &line = this->at(line_index);
299 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
301 const auto &glyphs = run.GetGlyphs();
302 const auto &positions = run.GetPositions();
303 const auto &charmap = run.GetGlyphToCharMap();
305 for (
int i = 0; i < run.GetGlyphCount(); i++) {
307 if (glyphs[i] == 0xFFFF)
continue;
309 int begin_x = positions[i].left;
310 int end_x = positions[i].right + 1;
314 size_t index = charmap[i];
318 for (
auto it = view.begin(), end = view.end(); it != end; ++it) {
319 if (cur_idx == index)
return it.GetByteOffset();
336 FontColourMap::iterator it =
fonts[size].find(colour);
337 if (it !=
fonts[size].end())
return it->second.get();
339 fonts[size][colour] = std::make_unique<Font>(size, colour);
340 return fonts[size][colour].get();
348#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
364#if defined(WITH_UNISCRIBE)
365 UniscribeResetScriptCache(size);
367#if defined(WITH_COCOA)
388 return match->second;
428 assert(ch >= str.data() && (ch - str.data()) <=
static_cast<ptrdiff_t
>(str.size()));
429 auto it_ch = str.begin() + (ch - str.data());
431 Layouter layout(str, INT32_MAX, start_fontsize);
444 if (x < 0)
return -1;
446 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.
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.
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 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.
TextColour cur_colour
Current text colour.
FontMap runs
Accessed by our ParagraphLayout::nextLine.
Buffer 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.
Handling of UTF-8 encoded data.