diff options
author | Tim Angus <tim@ngus.net> | 2009-10-29 19:00:30 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:17:14 +0000 |
commit | e53d789f7eca53631fd286f0f2f122fd7e3163e9 (patch) | |
tree | 648a6d41ebd4bd5b1aaf832b60940f04df5be7c3 /src | |
parent | f3190da593a8f46a9c8429541ccdd6895a997983 (diff) |
* Fix text wrapping... again
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/ui_shared.c | 144 | ||||
-rw-r--r-- | src/ui/ui_shared.h | 2 |
2 files changed, 69 insertions, 77 deletions
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c index 07413490..a7813bf7 100644 --- a/src/ui/ui_shared.c +++ b/src/ui/ui_shared.c @@ -1841,20 +1841,23 @@ void UI_EscapeEmoticons( char *dest, const char *src, int destsize ) { int len; qboolean escaped; + for( ; *src && destsize > 1; src++, destsize-- ) { - if ( UI_Text_Emoticon( src, &escaped, &len, NULL, NULL ) && !escaped ) + if( UI_Text_IsEmoticon( src, &escaped, &len, NULL, NULL ) && !escaped ) { *dest++ = '['; destsize--; } + *dest++ = *src; } + *dest++ = '\0'; } -qboolean UI_Text_Emoticon( const char *s, qboolean *escaped, - int *length, qhandle_t *h, int *width ) +qboolean UI_Text_IsEmoticon( const char *s, qboolean *escaped, + int *length, qhandle_t *h, int *width ) { char name[ MAX_EMOTICON_NAME_LEN ] = {""}; const char *p = s; @@ -1945,8 +1948,8 @@ float UI_Text_Width( const char *text, float scale, int limit ) continue; } - if ( UI_Text_Emoticon( s, &emoticonEscaped, &emoticonLen, - NULL, &emoticonWidth ) ) + if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen, + NULL, &emoticonWidth ) ) { if( emoticonEscaped ) s++; @@ -2133,7 +2136,7 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus continue; } - if( UI_Text_Emoticon( s, &emoticonEscaped, &emoticonLen, + if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen, &emoticonHandle, &emoticonWidth ) ) { if( emoticonEscaped ) @@ -4283,18 +4286,53 @@ void Item_TextColor( itemDef_t *item, vec4_t *newColor ) } } +static void SkipColorCodes( const char **text, char *lastColor ) +{ + while( Q_IsColorString( *text ) ) + { + lastColor[ 0 ] = (*text)[ 0 ]; + lastColor[ 1 ] = (*text)[ 1 ]; + (*text) += 2; + } +} + +static void SkipWhiteSpace( const char **text, char *lastColor ) +{ + while( **text ) + { + SkipColorCodes( text, lastColor ); + + if( **text != '\n' && isspace( **text ) ) + (*text)++; + else + break; + } +} + +static void SkipEmoticons( const char **text ) +{ + int emoticonLen; + qboolean emoticonEscaped; + + while( UI_Text_IsEmoticon( *text, &emoticonEscaped, &emoticonLen, NULL, NULL ) ) + { + if( emoticonEscaped ) + (*text)++; + else + (*text) += emoticonLen; + } +} + const char *Item_Text_Wrap( const char *text, float scale, float width ) { static char out[ 8192 ] = ""; char *paint = out; - char c[ 3 ] = "^7"; + char c[ 3 ] = ""; const char *p = text; const char *eol; const char *q = NULL, *qMinus1 = NULL; unsigned int testLength; unsigned int i; - int emoticonLen; - qboolean emoticonEscaped; if( strlen( text ) >= sizeof( out ) ) return NULL; @@ -4303,42 +4341,15 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) while( *p ) { - // Skip leading whitespace - - while( *p ) - { - if( Q_IsColorString( p ) ) - { - c[ 0 ] = p[ 0 ]; - c[ 1 ] = p[ 1 ]; - p += 2; - } - else if( *p != '\n' && isspace( *p ) ) - p++; - else - break; - } - - if( !*p ) - break; - - Q_strcat( paint, out + sizeof( out ) - paint, c ); - testLength = 1; - eol = p; - q = p + 1; - while( Q_IsColorString( q ) ) - { - c[ 0 ] = q[ 0 ]; - c[ 1 ] = q[ 1 ]; - q += 2; - } + SkipColorCodes( &q, c ); while( UI_Text_Width( p, scale, testLength ) < width ) { + // Remaining string is too short to wrap if( testLength >= strlen( p ) ) { eol = p + strlen( p ); @@ -4346,44 +4357,18 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) } // Point q at the end of the current testLength - q = p; - - for( i = 0; i < testLength; ) + for( q = p, i = 0; i < testLength; i++ ) { - // Skip color escapes - while( Q_IsColorString( q ) ) - { - c[ 0 ] = q[ 0 ]; - c[ 1 ] = q[ 1 ]; - q += 2; - } - while( UI_Text_Emoticon( q, &emoticonEscaped, &emoticonLen, NULL, NULL ) ) - { - if( emoticonEscaped ) - q++; - else - q += emoticonLen; - } + SkipColorCodes( &q, c ); + SkipEmoticons( &q ); qMinus1 = q; q++; - i++; } // Some color escapes might still be present - while( Q_IsColorString( q ) ) - { - c[ 0 ] = q[ 0 ]; - c[ 1 ] = q[ 1 ]; - q += 2; - } - while( UI_Text_Emoticon( q, &emoticonEscaped, &emoticonLen, NULL, NULL ) ) - { - if( emoticonEscaped ) - q++; - else - q += emoticonLen; - } + SkipColorCodes( &q, c ); + SkipEmoticons( &q ); // Manual line break if( *q == '\n' ) @@ -4408,19 +4393,26 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) strncpy( paint, p, eol - p ); paint[ eol - p ] = '\0'; + p = eol; + + // Skip leading whitespace on next line and save the + // last color code + SkipWhiteSpace( &p, c ); - // Add a \n if it's not there already - if( out[ strlen( out ) - 1 ] != '\n' ) + if( out[ strlen( out ) - 1 ] == '\n' ) { - Q_strcat( out, sizeof( out ), "\n " ); - Q_strcat( out, sizeof( out ), c ); + // The line is deliberately broken, clear the color + c[ 0 ] = '\0'; } else - c[ 0 ] = '\0'; + { + // Add a \n if it's not there already + Q_strcat( out, sizeof( out ), "\n" ); + } - paint = out + strlen( out ); + Q_strcat( out, sizeof( out ), c ); - p = eol; + paint = out + strlen( out ); } return out; diff --git a/src/ui/ui_shared.h b/src/ui/ui_shared.h index e2e30508..d96eabf1 100644 --- a/src/ui/ui_shared.h +++ b/src/ui/ui_shared.h @@ -520,7 +520,7 @@ float UI_Text_Width( const char *text, float scale, int limit ); float UI_Text_Height( const char *text, float scale, int limit ); float UI_Text_EmWidth( float scale ); float UI_Text_EmHeight( float scale ); -qboolean UI_Text_Emoticon( const char *s, qboolean *escaped, int *length, qhandle_t *h, int *width ); +qboolean UI_Text_IsEmoticon( const char *s, qboolean *escaped, int *length, qhandle_t *h, int *width ); void UI_EscapeEmoticons( char *dest, const char *src, int destsize ); int trap_Parse_AddGlobalDefine( char *define ); |