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);
183 auto l = line.
layout->NextLine(maxw);
184 if (l ==
nullptr)
break;
191 this->push_back(l.get());
195 if (line_length == std::string_view::npos) {
200 str.remove_prefix(line_length + 1);
211 for (
const auto &l : *
this) {
212 d.width = std::max<uint>(d.width, l->GetWidth());
213 d.height += l->GetLeading();
223 if (ch >= SCC_BLUE && ch <= SCC_BLACK)
return true;
224 if (ch == SCC_PUSH_COLOUR)
return true;
225 if (ch == SCC_POP_COLOUR)
return true;
226 if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT)
return true;
239 const auto &line = this->front();
242 if (ch == this->
string.end()) {
255 const size_t offset = ch - this->
string.begin();
259 if (pos.GetByteOffset() != offset)
return initial_position;
261 for (
auto it = view.begin(); it < pos; ++it) {
270 size_t best_index = SIZE_MAX;
271 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
273 const auto &positions = run.GetPositions();
274 const auto &charmap = run.GetGlyphToCharMap();
276 auto itp = positions.begin();
277 for (
auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
278 const size_t cur_index =
static_cast<size_t>(*it);
280 if (cur_index == index)
return *itp;
286 if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
287 best_index = cur_index;
305 if (line_index >= this->size())
return -1;
307 const auto &line = this->at(line_index);
309 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
311 const auto &glyphs = run.GetGlyphs();
312 const auto &positions = run.GetPositions();
313 const auto &charmap = run.GetGlyphToCharMap();
315 for (
int i = 0; i < run.GetGlyphCount(); i++) {
317 if (glyphs[i] == 0xFFFF)
continue;
319 int begin_x = positions[i].left;
320 int end_x = positions[i].right + 1;
324 size_t index = charmap[i];
328 for (
auto it = view.begin(), end = view.end(); it != end; ++it) {
329 if (cur_idx == index)
return it.GetByteOffset();
346 FontColourMap::iterator it =
fonts[size].find(colour);
347 if (it !=
fonts[size].end())
return it->second.get();
349 fonts[size][colour] = std::make_unique<Font>(size, colour);
350 return fonts[size][colour].get();
358#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
374#if defined(WITH_UNISCRIBE)
375 UniscribeResetScriptCache(size);
377#if defined(WITH_COCOA)
393 linecache = std::make_unique<LineCache>(4096);
427 assert(pos <= str.size());
428 auto it_ch = str.begin() + pos;
430 Layouter layout(str, INT32_MAX, start_fontsize);
443 if (x < 0)
return -1;
445 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 std::unique_ptr< LineCache > linecache
Cache of ParagraphLayout lines.
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.
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.
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.
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.
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).
Coordinates of a point in 2D.
Handling of UTF-8 encoded data.