From 3b32075e8a3440c9bca8764289c0b1e3c2f4c28d Mon Sep 17 00:00:00 2001 From: PeterN Date: Thu, 19 Apr 2018 19:33:21 +0100 Subject: [PATCH] Add: {PUSH_COLOUR} and {POP_COLOUR} control codes to handle switching colours. (#6737) This replaces the internal SCC_PREVIOUS_COLOUR swap. --- src/gfx_layout.cpp | 6 ++++-- src/gfx_layout.h | 29 +++++++++++++++++++++-------- src/strings.cpp | 6 ++++-- src/table/control_codes.h | 3 ++- src/table/strgen_tables.h | 2 ++ 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index de59fc5c82..3290aea653 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -594,8 +594,10 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, break; } else if (c >= SCC_BLUE && c <= SCC_BLACK) { state.SetColour((TextColour)(c - SCC_BLUE)); - } else if (c == SCC_PREVIOUS_COLOUR) { // Revert to the previous colour. - state.SetPreviousColour(); + } else if (c == SCC_PUSH_COLOUR) { + state.PushColour(); + } else if (c == SCC_POP_COLOUR) { + state.PopColour(); } else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) { state.SetFontSize((FontSize)(c - SCC_FIRST_FONT)); } else { diff --git a/src/gfx_layout.h b/src/gfx_layout.h index 0a21d9b0ca..45d79ae474 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -18,6 +18,7 @@ #include #include +#include #ifdef WITH_ICU_LAYOUT #include "layout/ParagraphLayout.h" @@ -33,10 +34,11 @@ struct FontState { FontSize fontsize; ///< Current font size. TextColour cur_colour; ///< Current text colour. - TextColour prev_colour; ///< Text colour from before the last colour switch. - FontState() : fontsize(FS_END), cur_colour(TC_INVALID), prev_colour(TC_INVALID) {} - FontState(TextColour colour, FontSize fontsize) : fontsize(fontsize), cur_colour(colour), prev_colour(colour) {} + std::stack colour_stack; ///< Stack of colours to assist with colour switching. + + FontState() : fontsize(FS_END), cur_colour(TC_INVALID) {} + FontState(TextColour colour, FontSize fontsize) : fontsize(fontsize), cur_colour(colour) {} /** * Switch to new colour \a c. @@ -45,14 +47,25 @@ struct FontState { inline void SetColour(TextColour c) { assert(c >= TC_BLUE && c <= TC_BLACK); - this->prev_colour = this->cur_colour; this->cur_colour = c; } - /** Switch to previous colour. */ - inline void SetPreviousColour() + /** + * Switch to and pop the last saved colour on the stack. + */ + inline void PopColour() { - Swap(this->cur_colour, this->prev_colour); + if (colour_stack.empty()) return; + SetColour(colour_stack.top()); + colour_stack.pop(); + } + + /** + * Push the current colour on to the stack. + */ + inline void PushColour() + { + colour_stack.push(this->cur_colour); } /** @@ -149,7 +162,7 @@ class Layouter : public AutoDeleteSmallVectorstate_before.fontsize != other.state_before.fontsize) return this->state_before.fontsize < other.state_before.fontsize; if (this->state_before.cur_colour != other.state_before.cur_colour) return this->state_before.cur_colour < other.state_before.cur_colour; - if (this->state_before.prev_colour != other.state_before.prev_colour) return this->state_before.prev_colour < other.state_before.prev_colour; + if (this->state_before.colour_stack != other.state_before.colour_stack) return this->state_before.colour_stack < other.state_before.colour_stack; return this->str < other.str; } }; diff --git a/src/strings.cpp b/src/strings.cpp index 82669ddb23..e1e352f5df 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -449,6 +449,8 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n /* convert from negative */ if (number < 0) { + if (buff + Utf8CharLen(SCC_PUSH_COLOUR) > last) return buff; + buff += Utf8Encode(buff, SCC_PUSH_COLOUR); if (buff + Utf8CharLen(SCC_RED) > last) return buff; buff += Utf8Encode(buff, SCC_RED); buff = strecpy(buff, "-", last); @@ -485,8 +487,8 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last); if (negative) { - if (buff + Utf8CharLen(SCC_PREVIOUS_COLOUR) > last) return buff; - buff += Utf8Encode(buff, SCC_PREVIOUS_COLOUR); + if (buff + Utf8CharLen(SCC_POP_COLOUR) > last) return buff; + buff += Utf8Encode(buff, SCC_POP_COLOUR); *buff = '\0'; } diff --git a/src/table/control_codes.h b/src/table/control_codes.h index ad620197a6..d8e9673e9f 100644 --- a/src/table/control_codes.h +++ b/src/table/control_codes.h @@ -115,7 +115,8 @@ enum StringControlCode { SCC_GRAY, SCC_DKBLUE, SCC_BLACK, - SCC_PREVIOUS_COLOUR, + SCC_PUSH_COLOUR, + SCC_POP_COLOUR, /** * The next variables are part of a NewGRF subsystem for creating text strings. diff --git a/src/table/strgen_tables.h b/src/table/strgen_tables.h index d4294fa84a..6297eea3bc 100644 --- a/src/table/strgen_tables.h +++ b/src/table/strgen_tables.h @@ -60,6 +60,8 @@ static const CmdStruct _cmd_structs[] = { {"GRAY", EmitSingleChar, SCC_GRAY, 0, -1, C_DONTCOUNT}, {"DKBLUE", EmitSingleChar, SCC_DKBLUE, 0, -1, C_DONTCOUNT}, {"BLACK", EmitSingleChar, SCC_BLACK, 0, -1, C_DONTCOUNT}, + {"PUSH_COLOUR", EmitSingleChar, SCC_PUSH_COLOUR, 0, -1, C_DONTCOUNT}, + {"POP_COLOUR", EmitSingleChar, SCC_POP_COLOUR, 0, -1, C_DONTCOUNT}, {"REV", EmitSingleChar, SCC_REVISION, 0, -1, C_NONE}, // openttd revision string