Skip to content

Commit 26a0635

Browse files
committed
color: Add the ability to selectively preserve colors
This adds back the "DECOLOR" functionality that was removed as part of Unvanquished/Unvanquished@d61c9d2. No motivation was given for the removal, and the DECOLOR functionality is important for external tools that parse game logs to display player colors leading to a richer experience.
1 parent f960177 commit 26a0635

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/common/Color.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,30 @@ int StrlenNocolor( const char *string )
8686

8787
void StripColors( const char *in, char *out, size_t len )
8888
{
89+
bool preserveColor = false;
90+
8991
for ( const auto& token : Parser( in ) )
9092
{
91-
Str::StringView text = token.PlainText();
93+
if ( token.Type() == Token::TokenType::CONTROL )
94+
{
95+
if ( token.RawToken().size() != 1 )
96+
{
97+
Log::Warn( "Invalid control token of length %d", token.RawToken().size() );
98+
continue;
99+
}
100+
switch ( token.RawToken()[0] )
101+
{
102+
case Constants::DECOLOR_ON:
103+
preserveColor = false;
104+
break;
105+
case Constants::DECOLOR_OFF:
106+
preserveColor = true;
107+
break;
108+
}
109+
continue;
110+
}
111+
Str::StringView text = ( preserveColor && token.Type() == Token::TokenType::COLOR ) ?
112+
token.RawToken() : token.PlainText();
92113
if ( text.size() >= len )
93114
{
94115
break;
@@ -106,9 +127,30 @@ std::string StripColors( Str::StringRef input )
106127
std::string output;
107128
output.reserve( input.size() );
108129

130+
bool preserveColor = false;
131+
109132
for ( const auto& token : Parser( input.c_str() ) )
110133
{
111-
Str::StringView text = token.PlainText();
134+
if ( token.Type() == Token::TokenType::CONTROL )
135+
{
136+
if ( token.RawToken().size() != 1 )
137+
{
138+
Log::Warn( "Invalid control token of length %d", token.RawToken().size() );
139+
continue;
140+
}
141+
switch ( token.RawToken()[0] )
142+
{
143+
case Constants::DECOLOR_ON:
144+
preserveColor = false;
145+
break;
146+
case Constants::DECOLOR_OFF:
147+
preserveColor = true;
148+
break;
149+
}
150+
continue;
151+
}
152+
Str::StringView text = ( preserveColor && token.Type() == Token::TokenType::COLOR ) ?
153+
token.RawToken() : token.PlainText();
112154
output.append( text.begin(), text.end() );
113155
}
114156

@@ -210,6 +252,10 @@ TokenIterator::value_type TokenIterator::NextToken(const char* input)
210252
}
211253
}
212254
}
255+
else if ( input[0] == Constants::DECOLOR_ON || input[0] == Constants::DECOLOR_OFF )
256+
{
257+
return value_type( input, input + 1, value_type::TokenType::CONTROL );
258+
}
213259

214260
return value_type( input, input + Q_UTF8_Width( input ), value_type::TokenType::CHARACTER );
215261
}

src/common/Color.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ namespace Constants {
344344
enum {
345345
ESCAPE = '^',
346346
NULL_COLOR = '*',
347+
// Magic chars to preserve colors between DECOLOR_OFF and DECOLOR_ON when calling StripColors.
348+
DECOLOR_OFF = '\16',
349+
DECOLOR_ON = '\17',
347350
}; // enum
348351
} // namespace Constants
349352

@@ -371,6 +374,7 @@ class Token
371374
CHARACTER, // A character
372375
ESCAPE, // Color escape
373376
COLOR, // Color code
377+
CONTROL, // Control character (basically controlling decolor behavior.)
374378
};
375379

376380
/*

src/common/ColorTest.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ TEST(StripColorTest, ReturningString)
4242

4343
std::string onlyColors = "^xF1A^1^0^O^9^a^;^*^xeE2^#123Aa5^#3903ff";
4444
EXPECT_EQ("", StripColors(onlyColors));
45+
46+
// Decolor
47+
std::string decolor = Str::Format("%c^1wtf^#aabbccbad%c^1a^2c^^^3c", Constants::DECOLOR_ON, Constants::DECOLOR_OFF);
48+
EXPECT_EQ("wtfbad^1a^2c^^3c", StripColors(decolor));
49+
4550
}
4651

4752
TEST(StripColorTest, ToBuffer)
@@ -57,8 +62,13 @@ TEST(StripColorTest, ToBuffer)
5762
char justright[7];
5863
StripColors("dretc^#123456h", justright, sizeof(justright));
5964
EXPECT_EQ("dretch", std::string(justright));
65+
66+
// Decolor
67+
char decolorjustright[9];
68+
StripColors(Str::Format("%c^1dretc%c^#123456h", Constants::DECOLOR_OFF, Constants::DECOLOR_ON).c_str(), decolorjustright, sizeof(decolorjustright));
69+
EXPECT_EQ("^1dretch", std::string(decolorjustright));
70+
6071
}
6172

6273
} // namespace
6374
} // namespace Color
64-

0 commit comments

Comments
 (0)