diff --git a/src/gfx.cpp b/src/gfx.cpp index 3d652ab18d..5cc3ee9b90 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -491,11 +491,12 @@ static void SetColourRemap(TextColour colour) * will be drawn in the right direction. * @param underline Whether to underline what has been drawn or not. * @param truncation Whether to perform string truncation or not. + * @param default_colour Colour of text if not specified within string. * * @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. */ -static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation) +static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation, TextColour default_colour) { if (line.CountRuns() == 0) return 0; @@ -589,6 +590,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, FontCache *fc = f->fc; TextColour colour = f->colour; + if (colour == TC_INVALID) colour = default_colour; colour_has_shadow = (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK; SetColourRemap(do_shadow ? TC_BLACK : colour); // the last run also sets the colour for the truncation dots if (do_shadow && (!fc->GetDrawGlyphShadow() || !colour_has_shadow)) continue; @@ -665,10 +667,10 @@ int DrawString(int left, int right, int top, std::string_view str, TextColour co return 0; } - Layouter layout(str, INT32_MAX, colour, fontsize); + Layouter layout(str, INT32_MAX, fontsize); if (layout.empty()) return 0; - return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true); + return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true, colour); } /** @@ -702,7 +704,7 @@ int DrawString(int left, int right, int top, StringID str, TextColour colour, St int GetStringHeight(std::string_view str, int maxw, FontSize fontsize) { assert(maxw > 0); - Layouter layout(str, maxw, TC_FROMSTRING, fontsize); + Layouter layout(str, maxw, fontsize); return layout.GetBounds().height; } @@ -778,7 +780,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_vi * do we really want to support fonts of 0 or less pixels high? */ if (maxh <= 0) return top; - Layouter layout(str, maxw, colour, fontsize); + Layouter layout(str, maxw, fontsize); int total_height = layout.GetBounds().height; int y; switch (align & SA_VERT_MASK) { @@ -807,7 +809,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_vi last_line = y + line_height; if (first_line > y) first_line = y; - DrawLayoutLine(*line, y, left, right, align, underline, false); + DrawLayoutLine(*line, y, left, right, align, underline, false, colour); } y += line_height; } @@ -848,7 +850,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, */ Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize) { - Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize); + Layouter layout(str, INT32_MAX, start_fontsize); return layout.GetBounds(); } @@ -907,7 +909,7 @@ Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fo assert(ch >= str.data() && (ch - str.data()) <= static_cast(str.size())); auto it_ch = str.begin() + (ch - str.data()); - Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize); + Layouter layout(str, INT32_MAX, start_fontsize); return layout.GetCharPosition(it_ch); } @@ -922,7 +924,7 @@ ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize { if (x < 0) return -1; - Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize); + Layouter layout(str, INT32_MAX, start_fontsize); return layout.GetCharAtPosition(x, 0); } diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 28a3c7a57d..392ba1fa4a 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -125,12 +125,11 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s * Create a new layouter. * @param str The string to create the layout for. * @param maxw The maximum width. - * @param colour The colour of the font. * @param fontsize The size of font to use. */ -Layouter::Layouter(std::string_view str, int maxw, TextColour colour, FontSize fontsize) : string(str) +Layouter::Layouter(std::string_view str, int maxw, FontSize fontsize) : string(str) { - FontState state(colour, fontsize); + FontState state(TC_INVALID, fontsize); while (true) { auto line_length = str.find_first_of('\n'); diff --git a/src/gfx_layout.h b/src/gfx_layout.h index 636b5cdadc..42b809f561 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -36,7 +36,7 @@ struct FontState { */ inline void SetColour(TextColour c) { - assert((c & TC_COLOUR_MASK) >= TC_BLUE && (c & TC_COLOUR_MASK) <= TC_BLACK); + assert(((c & TC_COLOUR_MASK) >= TC_BLUE && (c & TC_COLOUR_MASK) <= TC_BLACK) || (c & TC_COLOUR_MASK) == TC_INVALID); assert((c & (TC_COLOUR_MASK | TC_FLAGS_MASK)) == c); if ((this->cur_colour & TC_FORCED) == 0) this->cur_colour = c; } @@ -174,7 +174,7 @@ private: public: static Font *GetFont(FontSize size, TextColour colour); - Layouter(std::string_view str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL); + Layouter(std::string_view str, int maxw = INT32_MAX, FontSize fontsize = FS_NORMAL); Dimension GetBounds(); Point GetCharPosition(std::string_view::const_iterator ch) const; ptrdiff_t GetCharAtPosition(int x, size_t line_index) const; diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index a95c15ac48..1ae7673715 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -331,7 +331,7 @@ void TextfileWindow::CheckHyperlinkClick(Point pt) /* Build line layout to figure out character position that was clicked. */ uint window_width = IsWidgetLowered(WID_TF_WRAPTEXT) ? this->GetWidget(WID_TF_BACKGROUND)->current_x - WidgetDimensions::scaled.frametext.Horizontal() : INT_MAX; - Layouter layout(this->lines[line_index].text, window_width, this->lines[line_index].colour, FS_MONO); + Layouter layout(this->lines[line_index].text, window_width, FS_MONO); assert(subline < layout.size()); ptrdiff_t char_index = layout.GetCharAtPosition(pt.x - WidgetDimensions::scaled.frametext.left, subline); if (char_index < 0) return;