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) {
148 if (line.
layout ==
nullptr) {
149 state = std::move(old_state);
155 if (line.
layout ==
nullptr) {
157 if (line.
layout ==
nullptr) {
158 state = std::move(old_state);
164 if (line.
layout ==
nullptr) {
166 if (line.
layout ==
nullptr) {
167 state = std::move(old_state);
172 if (line.
layout ==
nullptr) {
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();
225 if (ch >= SCC_BLUE && ch <= SCC_BLACK)
return true;
226 if (ch == SCC_PUSH_COLOUR)
return true;
227 if (ch == SCC_POP_COLOUR)
return true;
228 if (ch >= SCC_FIRST_FONT && ch <= SCC_LAST_FONT)
return true;
241 const auto &line = this->front();
244 if (ch == this->
string.end()) {
257 const size_t offset = ch - this->
string.begin();
261 if (pos.GetByteOffset() != offset)
return initial_position;
263 for (
auto it = view.begin(); it < pos; ++it) {
272 size_t best_index = SIZE_MAX;
273 for (
size_t run_index = 0; run_index < line->CountRuns(); run_index++) {
278 auto itp = positions.begin();
279 for (
auto it = charmap.begin(); it != charmap.end(); ++it, ++itp) {
280 const size_t cur_index =
static_cast<size_t>(*it);
282 if (cur_index == index)
return *itp;
288 if (cur_index < index && (best_index < cur_index || best_index == SIZE_MAX)) {
289 best_index = cur_index;
307 if (line_index >= this->size())
return -1;
309 const auto &line = this->at(line_index);
311 for (
size_t run_index = 0; run_index < line->CountRuns(); run_index++) {
319 if (glyphs[i] == 0xFFFF)
continue;
321 int begin_x = positions[i].left;
322 int end_x = positions[i].right + 1;
326 size_t index = charmap[i];
330 for (
auto it = view.begin(), end = view.end(); it != end; ++it) {
331 if (cur_idx == index)
return it.GetByteOffset();
351 FontColourMap::iterator it =
fonts[size].find(colour);
352 if (it !=
fonts[size].end())
return it->second.get();
354 fonts[size][colour] = std::make_unique<Font>(size, colour);
355 return fonts[size][colour].get();
363#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
379#if defined(WITH_UNISCRIBE)
380 UniscribeResetScriptCache(size);
382#if defined(WITH_COCOA)
398 linecache = std::make_unique<LineCache>(4096);
432 assert(pos <= str.size());
433 auto it_ch = str.begin() + pos;
435 Layouter layout(str, INT32_MAX, start_fontsize);
448 if (x < 0)
return -1;
450 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.
FontCache * fc
The font we are using.
TextColour colour
The colour this font has to be.
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.
std::string_view string
Pointer to the original string.
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.
virtual std::span< const GlyphID > GetGlyphs() const =0
Get the glyphs to draw.
virtual std::span< const int > GetGlyphToCharMap() const =0
The offset for each of the glyphs to the character run that was passed to the Layouter.
virtual std::span< const Position > GetPositions() const =0
Get the positions for each of the glyphs.
virtual size_t GetGlyphCount() const =0
Get the number of glyphs.
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...
#define Point
Macro that prevents name conflicts between included headers.
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).
Handling of UTF-8 encoded data.