summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeterN <peter@fuzzle.org>2018-04-19 19:33:21 +0100
committerGitHub <noreply@github.com>2018-04-19 19:33:21 +0100
commit3b32075e8a3440c9bca8764289c0b1e3c2f4c28d (patch)
treecc5dde691f49ec264e0f932bb2ad56a689dc3c80
parentf4f9e18790b23862239164721dba831756ae24d7 (diff)
downloadopenttd-3b32075e8a3440c9bca8764289c0b1e3c2f4c28d.tar.xz
Add: {PUSH_COLOUR} and {POP_COLOUR} control codes to handle switching colours. (#6737)
This replaces the internal SCC_PREVIOUS_COLOUR swap.
-rw-r--r--src/gfx_layout.cpp6
-rw-r--r--src/gfx_layout.h29
-rw-r--r--src/strings.cpp6
-rw-r--r--src/table/control_codes.h3
-rw-r--r--src/table/strgen_tables.h2
5 files changed, 33 insertions, 13 deletions
diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp
index de59fc5c8..3290aea65 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 0a21d9b0c..45d79ae47 100644
--- a/src/gfx_layout.h
+++ b/src/gfx_layout.h
@@ -18,6 +18,7 @@
#include <map>
#include <string>
+#include <stack>
#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<TextColour> 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()
+ {
+ if (colour_stack.empty()) return;
+ SetColour(colour_stack.top());
+ colour_stack.pop();
+ }
+
+ /**
+ * Push the current colour on to the stack.
+ */
+ inline void PushColour()
{
- Swap(this->cur_colour, this->prev_colour);
+ colour_stack.push(this->cur_colour);
}
/**
@@ -149,7 +162,7 @@ class Layouter : public AutoDeleteSmallVector<const ParagraphLayouter::Line *, 4
{
if (this->state_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 82669ddb2..e1e352f5d 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 ad620197a..d8e9673e9 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 d4294fa84..6297eea3b 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