summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2009-11-03 23:38:49 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:17:17 +0000
commite9551ec91ffc7fb144eac71c5b65501c2c40f39d (patch)
tree0a975d9804f5f7a0940b6740061c1a098cb6c39a /src/ui
parentc49ee670d39f11f5eea3bd621c7e918e41c20876 (diff)
* Indent wrapped chat lines to avoid potential imitation exploits
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/ui_shared.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index fcf359f1..2e54df2b 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -1905,6 +1905,32 @@ qboolean UI_Text_IsEmoticon( const char *s, qboolean *escaped,
return qfalse;
}
+static float UI_Parse_Indent( const char **text )
+{
+ char indentWidth[ MAX_STRING_CHARS ];
+ char *p = indentWidth;
+ int numChars;
+ float pixels;
+
+ Q_strncpyz( indentWidth, *text, MAX_STRING_CHARS );
+
+ while( isdigit( *p ) || *p == '.' )
+ p++;
+
+ if( *p != INDENT_MARKER )
+ return 0.0f;
+
+ *p++ = '\0';
+ numChars = ( p - indentWidth );
+ p = indentWidth;
+
+ if( !Float_Parse( &p, &pixels ) )
+ return 0.0f;
+
+ (*text) += numChars;
+
+ return pixels;
+}
float UI_Text_Width( const char *text, float scale, int limit )
{
@@ -1919,6 +1945,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
float emoticonW;
int emoticonWidth;
int emoticons = 0;
+ float indentWidth = 0.0f;
if( scale <= DC->getCVarValue( "ui_smallFont" ) )
font = &DC->Assets.smallFont;
@@ -1937,6 +1964,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
len = limit;
count = 0;
+ indentWidth = UI_Parse_Indent( &s );
while( s && *s && count < len )
{
@@ -1948,6 +1976,12 @@ float UI_Text_Width( const char *text, float scale, int limit )
continue;
}
+ if( *s == INDENT_MARKER )
+ {
+ s++;
+ continue;
+ }
+
if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen,
NULL, &emoticonWidth ) )
{
@@ -1967,7 +2001,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
}
}
- return ( out * useScale ) + ( emoticons * emoticonW );
+ return ( out * useScale ) + ( emoticons * emoticonW ) + indentWidth;
}
float UI_Text_Height( const char *text, float scale, int limit )
@@ -2114,6 +2148,8 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus
DC->setColor( color );
memcpy( &newColor[0], &color[0], sizeof( vec4_t ) );
+ x += UI_Parse_Indent( &s );
+
while( s && *s && count < len )
{
glyph = &font->glyphs[ (int)*s ];
@@ -2136,6 +2172,12 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus
continue;
}
+ if( *s == INDENT_MARKER )
+ {
+ s++;
+ continue;
+ }
+
if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen,
&emoticonHandle, &emoticonWidth ) )
{
@@ -4383,9 +4425,11 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
char c[ 3 ] = "";
const char *p = text;
const char *eol;
- const char *q = NULL, *qMinus1 = NULL;
+ const char *q = NULL;
unsigned int testLength;
unsigned int i;
+ float indentWidth = 0.0f;
+ float testWidth;
if( strlen( text ) >= sizeof( out ) )
return NULL;
@@ -4394,14 +4438,17 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
while( *p )
{
- testLength = 1;
eol = p;
q = p + 1;
+ testLength = 0;
+ testWidth = width - indentWidth;
SkipColorCodes( &q, c );
- while( UI_Text_Width( p, scale, testLength ) < width )
+ while( testLength == 0 || UI_Text_Width( p, scale, testLength ) < testWidth )
{
+ qboolean previousCharIsSpace = qfalse;
+
// Remaining string is too short to wrap
if( testLength >= strlen( p ) )
{
@@ -4415,10 +4462,13 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
SkipColorCodes( &q, c );
SkipEmoticons( &q );
- qMinus1 = q;
+ previousCharIsSpace = isspace( *q );
q++;
}
+ if( testLength > 0 && *q == INDENT_MARKER )
+ indentWidth = UI_Text_Width( p, scale, testLength );
+
// Some color escapes might still be present
SkipColorCodes( &q, c );
SkipEmoticons( &q );
@@ -4430,7 +4480,7 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
break;
}
- if( !isspace( *qMinus1 ) && isspace( *q ) )
+ if( !previousCharIsSpace && isspace( *q ) )
eol = q;
testLength++;
@@ -4450,14 +4500,20 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
if( out[ strlen( out ) - 1 ] == '\n' )
{
- // The line is deliberately broken, clear the color
+ // The line is deliberately broken, clear the color and
+ // any current indent
c[ 0 ] = '\0';
+ indentWidth = 0.0f;
}
else
{
// Add a \n if it's not there already
Q_strcat( out, sizeof( out ), "\n" );
+ // Insert a pixel indent on the next line
+ if( indentWidth > 0.0f )
+ Q_strcat( out, sizeof( out ), va( "%f%c", indentWidth, INDENT_MARKER ) );
+
// Skip leading whitespace on next line and save the
// last color code
SkipWhiteSpace( &p, c );