summaryrefslogtreecommitdiff
path: root/src/ui/ui_shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/ui_shared.c')
-rw-r--r--src/ui/ui_shared.c212
1 files changed, 176 insertions, 36 deletions
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index 8c4ae3e8..4db016a7 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -2813,76 +2813,216 @@ void Item_TextColor(itemDef_t *item, vec4_t *newColor) {
}
}
-void Item_Text_AutoWrapped_Paint(itemDef_t *item) {
- char text[1024];
- const char *p, *textPtr, *newLinePtr;
- char buff[1024];
- int width, height, len, textWidth, newLine, newLineWidth;
- float y;
- vec4_t color;
+int Item_Text_AutoWrapped_Lines( itemDef_t *item )
+{
+ char text[ 1024 ];
+ const char *p, *textPtr, *newLinePtr;
+ char buff[ 1024 ];
+ int len, textWidth, newLine, newLineWidth;
+ vec4_t color;
+ int lines = 0;
textWidth = 0;
newLinePtr = NULL;
- if (item->text == NULL) {
- if (item->cvar == NULL) {
- return;
- }
- else {
- DC->getCVarString(item->cvar, text, sizeof(text));
+ if( item->text == NULL )
+ {
+ if( item->cvar == NULL )
+ return 0;
+ else
+ {
+ DC->getCVarString( item->cvar, text, sizeof( text ) );
textPtr = text;
}
}
- else {
+ else
textPtr = item->text;
+
+ if( *textPtr == '\0' )
+ return 0;
+
+ len = 0;
+ buff[ 0 ] = '\0';
+ newLine = 0;
+ newLineWidth = 0;
+ p = textPtr;
+
+ while( p )
+ {
+ textWidth = DC->textWidth( buff, item->textscale, 0 );
+
+ if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' )
+ {
+ newLine = len;
+ newLinePtr = p + 1;
+ newLineWidth = textWidth;
+ }
+
+ //TA: forceably split lines that are too long (where normal splitage has failed)
+ if( textWidth > item->window.rect.w && newLine == 0 )
+ {
+ newLine = len;
+ newLinePtr = p;
+ newLineWidth = textWidth;
+ }
+
+ if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' )
+ {
+ if( len )
+ buff[ newLine ] = '\0';
+
+ if( !( *p == '\n' && !*( p + 1 ) ) )
+ lines++;
+
+ if( *p == '\0' )
+ break;
+
+ //
+ p = newLinePtr;
+ len = 0;
+ newLine = 0;
+ newLineWidth = 0;
+
+ continue;
+ }
+
+ buff[ len++ ] = *p++;
+ buff[ len ] = '\0';
}
- if (*textPtr == '\0') {
- return;
+
+ return lines;
+}
+
+void Item_Text_AutoWrapped_Paint( itemDef_t *item )
+{
+ char text[ 1024 ];
+ const char *p, *textPtr, *newLinePtr;
+ char buff[ 1024 ];
+ char lastCMod[ 2 ] = { 0, 0 };
+ qboolean forwardColor;
+ int width, height, len, textWidth, newLine, newLineWidth, skipLines, totalLines;
+ float y, totalY;
+ vec4_t color;
+
+ textWidth = 0;
+ newLinePtr = NULL;
+
+ if( item->text == NULL )
+ {
+ if( item->cvar == NULL )
+ return;
+ else
+ {
+ DC->getCVarString( item->cvar, text, sizeof( text ) );
+ textPtr = text;
+ }
}
- Item_TextColor(item, &color);
- Item_SetTextExtents(item, &width, &height, textPtr);
+ else
+ textPtr = item->text;
+
+ if( *textPtr == '\0' )
+ return;
+
+ Item_TextColor( item, &color );
+ Item_SetTextExtents( item, &width, &height, textPtr );
y = item->textaligny;
len = 0;
- buff[0] = '\0';
+ buff[ 0 ] = '\0';
newLine = 0;
newLineWidth = 0;
p = textPtr;
- while (p) {
- if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0') {
+
+ skipLines = -1;
+ totalLines = Item_Text_AutoWrapped_Lines( item );
+
+ do
+ {
+ skipLines++;
+ totalY = ( totalLines - skipLines ) * ( height + 5 );
+ } while( totalY > item->window.rect.h );
+
+ while( p )
+ {
+ textWidth = DC->textWidth( buff, item->textscale, 0 );
+
+ if( *p == '^' )
+ {
+ lastCMod[ 0 ] = p[ 0 ];
+ lastCMod[ 1 ] = p[ 1 ];
+ }
+
+ if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' )
+ {
newLine = len;
newLinePtr = p+1;
newLineWidth = textWidth;
+
+ if( *p == '\n' ) //don't forward colours past deilberate \n's
+ lastCMod[ 0 ] = lastCMod[ 1 ] = 0;
+ else
+ forwardColor = qtrue;
}
- textWidth = DC->textWidth(buff, item->textscale, 0);
- if ( (newLine && textWidth > item->window.rect.w) || *p == '\n' || *p == '\0') {
- if (len) {
- if (item->textalignment == ITEM_ALIGN_LEFT) {
+
+ //TA: forceably split lines that are too long (where normal splitage has failed)
+ if( textWidth > item->window.rect.w && newLine == 0 )
+ {
+ newLine = len;
+ newLinePtr = p;
+ newLineWidth = textWidth;
+
+ forwardColor = qtrue;
+ }
+
+ if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' )
+ {
+ if( len )
+ {
+ if( item->textalignment == ITEM_ALIGN_LEFT )
item->textRect.x = item->textalignx;
- } else if (item->textalignment == ITEM_ALIGN_RIGHT) {
+ else if( item->textalignment == ITEM_ALIGN_RIGHT )
item->textRect.x = item->textalignx - newLineWidth;
- } else if (item->textalignment == ITEM_ALIGN_CENTER) {
+ else if( item->textalignment == ITEM_ALIGN_CENTER )
item->textRect.x = item->textalignx - newLineWidth / 2;
- }
+
item->textRect.y = y;
- ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
+ ToWindowCoords( &item->textRect.x, &item->textRect.y, &item->window );
//
- buff[newLine] = '\0';
- DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle);
+ buff[ newLine ] = '\0';
+
+ if( !skipLines )
+ DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle );
}
- if (*p == '\0') {
+
+ if( *p == '\0' )
break;
- }
+
//
- y += height + 5;
+ if( !skipLines )
+ y += height + 5;
+
+ if( skipLines )
+ skipLines--;
+
p = newLinePtr;
len = 0;
newLine = 0;
newLineWidth = 0;
+
+ if( forwardColor && lastCMod[ 0 ] != 0 )
+ {
+ buff[ len++ ] = lastCMod[ 0 ];
+ buff[ len++ ] = lastCMod[ 1 ];
+ buff[ len ] = '\0';
+
+ forwardColor = qfalse;
+ }
+
continue;
}
- buff[len++] = *p++;
- buff[len] = '\0';
+
+ buff[ len++ ] = *p++;
+ buff[ len ] = '\0';
}
}