mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: C++-ify the Layouter and related functions
They all now access a std::string_view, instead of a "const char *" or std::string (in some cases). Additionally, GetCharAtPosition and friends now return an index instead of a "const char *", as it makes for a more clear interface.
This commit is contained in:
parent
61d1b330d1
commit
60399e17bd
|
@ -318,11 +318,11 @@ struct IConsoleWindow : Window
|
|||
return r;
|
||||
}
|
||||
|
||||
const char *GetTextCharacterAtPosition(const Point &pt) const override
|
||||
ptrdiff_t GetTextCharacterAtPosition(const Point &pt) const override
|
||||
{
|
||||
int delta = std::min<int>(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||
|
||||
if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return nullptr;
|
||||
if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return -1;
|
||||
|
||||
return GetCharAtPosition(_iconsole_cmdline.buf, pt.x - delta);
|
||||
}
|
||||
|
|
85
src/gfx.cpp
85
src/gfx.cpp
|
@ -642,7 +642,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
* @return In case of left or center alignment the right most pixel we have drawn to.
|
||||
* In case of right alignment the left most pixel we have drawn to.
|
||||
*/
|
||||
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
/* The string may contain control chars to change the font, just use the biggest font for clipping. */
|
||||
int max_height = std::max({FONT_HEIGHT_SMALL, FONT_HEIGHT_NORMAL, FONT_HEIGHT_LARGE, FONT_HEIGHT_MONO});
|
||||
|
@ -661,28 +661,6 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour,
|
|||
return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly truncated to make it fit in its allocated space
|
||||
*
|
||||
* @param left The left most position to draw on.
|
||||
* @param right The right most position to draw on.
|
||||
* @param top The top most position to draw on.
|
||||
* @param str String to draw.
|
||||
* @param colour Colour used for drawing the string, for details see _string_colourmap in
|
||||
* table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
|
||||
* @param align The alignment of the string when drawing left-to-right. In the
|
||||
* case a right-to-left language is chosen this is inverted so it
|
||||
* will be drawn in the right direction.
|
||||
* @param underline Whether to underline what has been drawn or not.
|
||||
* @param fontsize The size of the initial characters.
|
||||
* @return In case of left or center alignment the right most pixel we have drawn to.
|
||||
* In case of right alignment the left most pixel we have drawn to.
|
||||
*/
|
||||
int DrawString(int left, int right, int top, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
return DrawString(left, right, top, str.c_str(), colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly truncated to make it fit in its allocated space
|
||||
*
|
||||
|
@ -713,7 +691,7 @@ int DrawString(int left, int right, int top, StringID str, TextColour colour, St
|
|||
* @param maxw maximum string width
|
||||
* @return height of pixels of string when it is drawn
|
||||
*/
|
||||
int GetStringHeight(const char *str, int maxw, FontSize fontsize)
|
||||
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
|
||||
{
|
||||
Layouter layout(str, maxw, TC_FROMSTRING, fontsize);
|
||||
return layout.GetBounds().height;
|
||||
|
@ -765,7 +743,7 @@ Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestio
|
|||
* @param suggestion Suggested bounding box.
|
||||
* @return Bounding box for the multi-line string, may be bigger than \a suggestion.
|
||||
*/
|
||||
Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion)
|
||||
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion)
|
||||
{
|
||||
Dimension box = {suggestion.width, (uint)GetStringHeight(str, suggestion.width)};
|
||||
return box;
|
||||
|
@ -787,7 +765,7 @@ Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &sugges
|
|||
*
|
||||
* @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written.
|
||||
*/
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
int maxw = right - left + 1;
|
||||
int maxh = bottom - top + 1;
|
||||
|
@ -833,28 +811,6 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st
|
|||
return ((align & SA_VERT_MASK) == SA_BOTTOM) ? first_line : last_line;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw string, possibly over multiple lines.
|
||||
*
|
||||
* @param left The left most position to draw on.
|
||||
* @param right The right most position to draw on.
|
||||
* @param top The top most position to draw on.
|
||||
* @param bottom The bottom most position to draw on.
|
||||
* @param str String to draw.
|
||||
* @param colour Colour used for drawing the string, for details see _string_colourmap in
|
||||
* table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h
|
||||
* @param align The horizontal and vertical alignment of the string.
|
||||
* @param underline Whether to underline all strings
|
||||
* @param fontsize The size of the initial characters.
|
||||
*
|
||||
* @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written.
|
||||
*/
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
|
||||
{
|
||||
return DrawStringMultiLine(left, right, top, bottom, str.c_str(), colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw string, possibly over multiple lines.
|
||||
*
|
||||
|
@ -888,30 +844,15 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str,
|
|||
* @param start_fontsize Fontsize to start the text with
|
||||
* @return string width and height in pixels
|
||||
*/
|
||||
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
|
||||
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
|
||||
{
|
||||
Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize);
|
||||
return layout.GetBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string dimension in pixels. The height and width are returned
|
||||
* in a single Dimension value. TINYFONT, BIGFONT modifiers are only
|
||||
* supported as the first character of the string. The returned dimensions
|
||||
* are therefore a rough estimation correct for all the current strings
|
||||
* but not every possible combination
|
||||
* @param str string to calculate pixel-width
|
||||
* @param start_fontsize Fontsize to start the text with
|
||||
* @return string width and height in pixels
|
||||
*/
|
||||
Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize)
|
||||
{
|
||||
return GetStringBoundingBox(str.c_str(), start_fontsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get bounding box of a string. Uses parameters set by #SetDParam if needed.
|
||||
* Has the same restrictions as #GetStringBoundingBox(const char *str, FontSize start_fontsize).
|
||||
* Has the same restrictions as #GetStringBoundingBox(std::string_view str, FontSize start_fontsize).
|
||||
* @param strid String to examine.
|
||||
* @return Width and height of the bounding box for the string in pixels.
|
||||
*/
|
||||
|
@ -946,10 +887,14 @@ uint GetStringListWidth(const StringID *list, FontSize fontsize)
|
|||
* @param start_fontsize Font size to start the text with.
|
||||
* @return Upper left corner of the glyph associated with the character.
|
||||
*/
|
||||
Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsize)
|
||||
Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
|
||||
{
|
||||
/* Ensure "ch" is inside "str" or at the exact end. */
|
||||
assert(ch >= str.data() && (ch - str.data()) <= static_cast<ptrdiff_t>(str.size()));
|
||||
auto it_ch = str.begin() + (ch - str.data());
|
||||
|
||||
Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize);
|
||||
return layout.GetCharPosition(ch);
|
||||
return layout.GetCharPosition(it_ch);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -957,11 +902,11 @@ Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsiz
|
|||
* @param str String to test.
|
||||
* @param x Position relative to the start of the string.
|
||||
* @param start_fontsize Font size to start the text with.
|
||||
* @return Pointer to the character at the position or nullptr if there is no character at the position.
|
||||
* @return Index of the character position or -1 if there is no character at the position.
|
||||
*/
|
||||
const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize)
|
||||
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize)
|
||||
{
|
||||
if (x < 0) return nullptr;
|
||||
if (x < 0) return -1;
|
||||
|
||||
Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize);
|
||||
return layout.GetCharAtPosition(x);
|
||||
|
|
|
@ -95,11 +95,9 @@ void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub
|
|||
void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, bool clicked, StringAlignment align); /* widget.cpp */
|
||||
std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom = ZOOM_LVL_GUI);
|
||||
|
||||
int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawString(int left, int right, int top, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawString(int left, int right, int top, std::string_view str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawString(int left, int right, int top, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL);
|
||||
|
||||
void DrawCharCentered(WChar c, const Rect &r, TextColour colour);
|
||||
|
@ -110,12 +108,7 @@ void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width
|
|||
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
|
||||
|
||||
/* Versions of DrawString/DrawStringMultiLine that accept a Rect instead of separate left, right, top and bottom parameters. */
|
||||
static inline int DrawString(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
{
|
||||
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
static inline int DrawString(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
static inline int DrawString(const Rect &r, std::string_view str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
{
|
||||
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
|
||||
}
|
||||
|
@ -125,12 +118,7 @@ static inline int DrawString(const Rect &r, StringID str, TextColour colour = TC
|
|||
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
static inline int DrawStringMultiLine(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
{
|
||||
return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize);
|
||||
}
|
||||
|
||||
static inline int DrawStringMultiLine(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
static inline int DrawStringMultiLine(const Rect &r, std::string_view str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
|
||||
{
|
||||
return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize);
|
||||
}
|
||||
|
@ -145,18 +133,17 @@ static inline void GfxFillRect(const Rect &r, int colour, FillRectMode mode = FI
|
|||
GfxFillRect(r.left, r.top, r.right, r.bottom, colour, mode);
|
||||
}
|
||||
|
||||
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL);
|
||||
Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL);
|
||||
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize = FS_NORMAL);
|
||||
Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize = FS_NORMAL);
|
||||
uint GetStringListWidth(const StringID *list, FontSize fontsize = FS_NORMAL);
|
||||
int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL);
|
||||
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize = FS_NORMAL);
|
||||
int GetStringHeight(StringID str, int maxw);
|
||||
int GetStringLineCount(StringID str, int maxw);
|
||||
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
|
||||
Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion);
|
||||
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion);
|
||||
void LoadStringWidthTable(bool monospace = false);
|
||||
Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsize = FS_NORMAL);
|
||||
const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize = FS_NORMAL);
|
||||
Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL);
|
||||
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL);
|
||||
|
||||
void DrawDirtyBlocks();
|
||||
void AddDirtyBlock(int left, int top, int right, int bottom);
|
||||
|
|
|
@ -59,7 +59,7 @@ Font::Font(FontSize size, TextColour colour) :
|
|||
* @tparam T The type of layouter we want.
|
||||
*/
|
||||
template <typename T>
|
||||
static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, FontState &state)
|
||||
static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view str, FontState &state)
|
||||
{
|
||||
if (line.buffer != nullptr) free(line.buffer);
|
||||
|
||||
|
@ -72,15 +72,18 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str,
|
|||
line.buffer = buff_begin;
|
||||
fontMapping.clear();
|
||||
|
||||
auto cur = str.begin();
|
||||
|
||||
/*
|
||||
* Go through the whole string while adding Font instances to the font map
|
||||
* whenever the font changes, and convert the wide characters into a format
|
||||
* usable by ParagraphLayout.
|
||||
*/
|
||||
for (; buff < buffer_last;) {
|
||||
WChar c = Utf8Consume(const_cast<const char **>(&str));
|
||||
for (; buff < buffer_last && cur != str.end();) {
|
||||
WChar c = Utf8Consume(cur);
|
||||
if (c == '\0' || c == '\n') {
|
||||
break;
|
||||
/* Caller should already have filtered out these characters. */
|
||||
NOT_REACHED();
|
||||
} else if (c >= SCC_BLUE && c <= SCC_BLACK) {
|
||||
state.SetColour((TextColour)(c - SCC_BLUE));
|
||||
} else if (c == SCC_PUSH_COLOUR) {
|
||||
|
@ -123,65 +126,51 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str,
|
|||
* @param colour The colour of the font.
|
||||
* @param fontsize The size of font to use.
|
||||
*/
|
||||
Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsize) : string(str)
|
||||
Layouter::Layouter(std::string_view str, int maxw, TextColour colour, FontSize fontsize) : string(str)
|
||||
{
|
||||
FontState state(colour, fontsize);
|
||||
WChar c = 0;
|
||||
|
||||
do {
|
||||
/* Scan string for end of line */
|
||||
const char *lineend = str;
|
||||
for (;;) {
|
||||
size_t len = Utf8Decode(&c, lineend);
|
||||
if (c == '\0' || c == '\n') break;
|
||||
lineend += len;
|
||||
}
|
||||
while (true) {
|
||||
auto line_length = str.find_first_of('\n');
|
||||
auto str_line = str.substr(0, line_length);
|
||||
|
||||
LineCacheItem& line = GetCachedParagraphLayout(str, lineend - str, state);
|
||||
LineCacheItem &line = GetCachedParagraphLayout(str_line, state);
|
||||
if (line.layout != nullptr) {
|
||||
/* Line is in cache */
|
||||
str = lineend + 1;
|
||||
state = line.state_after;
|
||||
line.layout->Reflow();
|
||||
} else {
|
||||
/* Line is new, layout it */
|
||||
FontState old_state = state;
|
||||
#if (defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA)
|
||||
const char *old_str = str;
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)
|
||||
if (line.layout == nullptr) {
|
||||
GetLayouter<ICUParagraphLayoutFactory>(line, str, state);
|
||||
GetLayouter<ICUParagraphLayoutFactory>(line, str_line, state);
|
||||
if (line.layout == nullptr) {
|
||||
state = old_state;
|
||||
str = old_str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_UNISCRIBE
|
||||
if (line.layout == nullptr) {
|
||||
GetLayouter<UniscribeParagraphLayoutFactory>(line, str, state);
|
||||
GetLayouter<UniscribeParagraphLayoutFactory>(line, str_line, state);
|
||||
if (line.layout == nullptr) {
|
||||
state = old_state;
|
||||
str = old_str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
if (line.layout == nullptr) {
|
||||
GetLayouter<CoreTextParagraphLayoutFactory>(line, str, state);
|
||||
GetLayouter<CoreTextParagraphLayoutFactory>(line, str_line, state);
|
||||
if (line.layout == nullptr) {
|
||||
state = old_state;
|
||||
str = old_str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (line.layout == nullptr) {
|
||||
GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
|
||||
GetLayouter<FallbackParagraphLayoutFactory>(line, str_line, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +180,15 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi
|
|||
if (l == nullptr) break;
|
||||
this->push_back(std::move(l));
|
||||
}
|
||||
} while (c != '\0');
|
||||
|
||||
/* Break out if this was the last line. */
|
||||
if (line_length == std::string_view::npos) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Go to the next line. */
|
||||
str.remove_prefix(line_length + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,21 +207,18 @@ Dimension Layouter::GetBounds()
|
|||
|
||||
/**
|
||||
* Get the position of a character in the layout.
|
||||
* @param ch Character to get the position of.
|
||||
* @param ch Character to get the position of. Must be an iterator of the string passed to the constructor.
|
||||
* @return Upper left corner of the character relative to the start of the string.
|
||||
* @note Will only work right for single-line strings.
|
||||
*/
|
||||
Point Layouter::GetCharPosition(const char *ch) const
|
||||
Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
||||
{
|
||||
/* Find the code point index which corresponds to the char
|
||||
* pointer into our UTF-8 source string. */
|
||||
size_t index = 0;
|
||||
const char *str = this->string;
|
||||
while (str < ch) {
|
||||
WChar c;
|
||||
size_t len = Utf8Decode(&c, str);
|
||||
if (c == '\0' || c == '\n') break;
|
||||
str += len;
|
||||
auto str = this->string.begin();
|
||||
while (str < ch && str != this->string.end()) {
|
||||
WChar c = Utf8Consume(str);
|
||||
index += this->front()->GetInternalCharLength(c);
|
||||
}
|
||||
|
||||
|
@ -233,7 +227,7 @@ Point Layouter::GetCharPosition(const char *ch) const
|
|||
const auto &line = this->front();
|
||||
|
||||
/* Pointer to the end-of-string/line marker? Return total line width. */
|
||||
if (*ch == '\0' || *ch == '\n') {
|
||||
if (ch == this->string.end() || *ch == '\0' || *ch == '\n') {
|
||||
Point p = { line->GetWidth(), 0 };
|
||||
return p;
|
||||
}
|
||||
|
@ -259,9 +253,9 @@ Point Layouter::GetCharPosition(const char *ch) const
|
|||
/**
|
||||
* Get the character that is at a position.
|
||||
* @param x Position in the string.
|
||||
* @return Pointer to the character at the position or nullptr if no character is at the position.
|
||||
* @return Index of the position or -1 if no character is at the position.
|
||||
*/
|
||||
const char *Layouter::GetCharAtPosition(int x) const
|
||||
ptrdiff_t Layouter::GetCharAtPosition(int x) const
|
||||
{
|
||||
const auto &line = this->front();
|
||||
|
||||
|
@ -280,17 +274,18 @@ const char *Layouter::GetCharAtPosition(int x) const
|
|||
size_t index = run.GetGlyphToCharMap()[i];
|
||||
|
||||
size_t cur_idx = 0;
|
||||
for (const char *str = this->string; *str != '\0'; ) {
|
||||
if (cur_idx == index) return str;
|
||||
int char_index = 0;
|
||||
for (auto str = this->string.begin(); str != this->string.end(); char_index++) {
|
||||
if (cur_idx == index) return char_index;
|
||||
|
||||
WChar c = Utf8Consume(&str);
|
||||
WChar c = Utf8Consume(str);
|
||||
cur_idx += line->GetInternalCharLength(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -332,18 +327,17 @@ void Layouter::ResetFontCache(FontSize size)
|
|||
* Get reference to cache item.
|
||||
* If the item does not exist yet, it is default constructed.
|
||||
* @param str Source string of the line (including colour and font size codes).
|
||||
* @param len Length of \a str in bytes (no termination).
|
||||
* @param state State of the font at the beginning of the line.
|
||||
* @return Reference to cache item.
|
||||
*/
|
||||
Layouter::LineCacheItem &Layouter::GetCachedParagraphLayout(const char *str, size_t len, const FontState &state)
|
||||
Layouter::LineCacheItem &Layouter::GetCachedParagraphLayout(std::string_view str, const FontState &state)
|
||||
{
|
||||
if (linecache == nullptr) {
|
||||
/* Create linecache on first access to avoid trouble with initialisation order of static variables. */
|
||||
linecache = new LineCache();
|
||||
}
|
||||
|
||||
if (auto match = linecache->find(LineCacheQuery{state, std::string_view{str, len}});
|
||||
if (auto match = linecache->find(LineCacheQuery{state, str});
|
||||
match != linecache->end()) {
|
||||
return match->second;
|
||||
}
|
||||
|
@ -351,7 +345,7 @@ Layouter::LineCacheItem &Layouter::GetCachedParagraphLayout(const char *str, siz
|
|||
/* Create missing entry */
|
||||
LineCacheKey key;
|
||||
key.state_before = state;
|
||||
key.str.assign(str, len);
|
||||
key.str.assign(str);
|
||||
return (*linecache)[key];
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ public:
|
|||
* It also accounts for the memory allocations and frees.
|
||||
*/
|
||||
class Layouter : public std::vector<std::unique_ptr<const ParagraphLayouter::Line>> {
|
||||
const char *string; ///< Pointer to the original string.
|
||||
std::string_view string; ///< Pointer to the original string.
|
||||
|
||||
/** Key into the linecache */
|
||||
struct LineCacheKey {
|
||||
|
@ -168,17 +168,17 @@ private:
|
|||
typedef std::map<LineCacheKey, LineCacheItem, LineCacheCompare> LineCache;
|
||||
static LineCache *linecache;
|
||||
|
||||
static LineCacheItem &GetCachedParagraphLayout(const char *str, size_t len, const FontState &state);
|
||||
static LineCacheItem &GetCachedParagraphLayout(std::string_view str, const FontState &state);
|
||||
|
||||
typedef SmallMap<TextColour, Font *> FontColourMap;
|
||||
static FontColourMap fonts[FS_END];
|
||||
public:
|
||||
static Font *GetFont(FontSize size, TextColour colour);
|
||||
|
||||
Layouter(const char *str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL);
|
||||
Layouter(std::string_view str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL);
|
||||
Dimension GetBounds();
|
||||
Point GetCharPosition(const char *ch) const;
|
||||
const char *GetCharAtPosition(int x) const;
|
||||
Point GetCharPosition(std::string_view::const_iterator ch) const;
|
||||
ptrdiff_t GetCharAtPosition(int x) const;
|
||||
|
||||
static void ResetFontCache(FontSize size);
|
||||
static void ResetLineCache();
|
||||
|
|
|
@ -896,9 +896,9 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co
|
|||
* @param w Window the edit box is in.
|
||||
* @param wid Widget index.
|
||||
* @param pt Position to test.
|
||||
* @return Pointer to the character at the position or nullptr if no character is at the position.
|
||||
* @return Index of the character position or -1 if no character is at the position.
|
||||
*/
|
||||
const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point &pt) const
|
||||
ptrdiff_t QueryString::GetCharAtPosition(const Window *w, int wid, const Point &pt) const
|
||||
{
|
||||
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
|
||||
|
||||
|
@ -910,7 +910,7 @@ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point
|
|||
|
||||
Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
if (!IsInsideMM(pt.y, r.top, r.bottom)) return nullptr;
|
||||
if (!IsInsideMM(pt.y, r.top, r.bottom)) return -1;
|
||||
|
||||
/* Clamp caret position to be inside our current width. */
|
||||
const Textbuf *tb = &this->text;
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
Point GetCaretPosition(const Window *w, int wid) const;
|
||||
Rect GetBoundingRect(const Window *w, int wid, const char *from, const char *to) const;
|
||||
const char *GetCharAtPosition(const Window *w, int wid, const Point &pt) const;
|
||||
ptrdiff_t GetCharAtPosition(const Window *w, int wid, const Point &pt) const;
|
||||
|
||||
/**
|
||||
* Get the current text.
|
||||
|
|
|
@ -1057,10 +1057,11 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
|
|||
|
||||
Point pt = { (int)view_pt.x, (int)[ self frame ].size.height - (int)view_pt.y };
|
||||
|
||||
const char *ch = _focused_window->GetTextCharacterAtPosition(pt);
|
||||
if (ch == nullptr) return NSNotFound;
|
||||
auto index = _focused_window->GetTextCharacterAtPosition(pt);
|
||||
if (index == -1) return NSNotFound;
|
||||
|
||||
return CountUtf16Units(_focused_window->GetFocusedText(), ch);
|
||||
auto text = _focused_window->GetFocusedText();
|
||||
return CountUtf16Units(text, text + index);
|
||||
}
|
||||
|
||||
/** Get the bounding rect for the given range. */
|
||||
|
|
|
@ -440,15 +440,15 @@ void Window::UpdateQueryStringSize()
|
|||
/**
|
||||
* Get the character that is rendered at a position by the focused edit box.
|
||||
* @param pt The position to test.
|
||||
* @return Pointer to the character at the position or nullptr if no character is at the position.
|
||||
* @return Index of the character position or -1 if no character is at the position.
|
||||
*/
|
||||
/* virtual */ const char *Window::GetTextCharacterAtPosition(const Point &pt) const
|
||||
/* virtual */ ptrdiff_t Window::GetTextCharacterAtPosition(const Point &pt) const
|
||||
{
|
||||
if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) {
|
||||
return this->GetQueryString(this->nested_focus->index)->GetCharAtPosition(this, this->nested_focus->index, pt);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -281,7 +281,7 @@ public:
|
|||
virtual const char *GetMarkedText(size_t *length) const;
|
||||
virtual Point GetCaretPosition() const;
|
||||
virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
|
||||
virtual const char *GetTextCharacterAtPosition(const Point &pt) const;
|
||||
virtual ptrdiff_t GetTextCharacterAtPosition(const Point &pt) const;
|
||||
|
||||
void InitNested(WindowNumber number = 0);
|
||||
void CreateNestedTree(bool fill_nested = true);
|
||||
|
|
Loading…
Reference in New Issue