//=============== //SCR_DrawRawString - Doesn't care about aligning. Returns drawn len. // It can stop when reaching maximum width when a value has been parsed. //=============== static int SCR_DrawRawString( int x, int y, const char *str, int maxwidth, struct mufont_s *font, vec4_t color ) { int xoffset = 0, yoffset = 0; vec4_t scolor; const char *s, *olds; int gc, colorindex; qwchar num; if( !str ) return 0; if( !font ) font = cls.fontSystemSmall; if( maxwidth < 0 ) maxwidth = 0; Vector4Copy( color, scolor ); s = str; while( s ) { olds = s; gc = Q_GrabWCharFromColorString( &s, &num, &colorindex ); if( gc == GRABCHAR_CHAR ) { if( num == '\n' ) break; if( num < ' ' ) continue; if( num >= font->numchars || !( font->chars[num].height ) ) num = REPLACEMENT_CHAR; if( maxwidth && ( ( xoffset + font->chars[num].width ) > maxwidth ) ) { s = olds; break; } if( num != ' ' ) R_DrawStretchPic( x+xoffset, y+yoffset, font->chars[num].width, font->chars[num].height, font->chars[num].s1, font->chars[num].t1, font->chars[num].s2, font->chars[num].t2, scolor, font->shader ); xoffset += font->chars[num].width; } else if( gc == GRABCHAR_COLOR ) { assert( ( unsigned )colorindex < MAX_S_COLORS ); VectorCopy( color_table[colorindex], scolor ); } else if( gc == GRABCHAR_END ) break; else assert( 0 ); } return ( s - str ); }
void SCR_DrawClampString( int x, int y, const char *str, int xmin, int ymin, int xmax, int ymax, struct mufont_s *font, vec4_t color ) { int xoffset = 0, yoffset = 0; vec4_t scolor; int colorindex; qwchar num; const char *s = str; int gc; if( !str ) return; if( !font ) font = cls.fontSystemSmall; // clamp mins and maxs to the screen space if( xmin < 0 ) xmin = 0; if( xmax > (int)viddef.width ) xmax = (int)viddef.width; if( ymin < 0 ) ymin = 0; if( ymax > (int)viddef.height ) ymax = (int)viddef.height; if( xmax <= xmin || ymax <= ymin || x > xmax || y > ymax ) return; Vector4Copy( color, scolor ); while( 1 ) { gc = Q_GrabWCharFromColorString( &s, &num, &colorindex ); if( gc == GRABCHAR_CHAR ) { if( num == '\n' ) break; if( num < ' ' ) continue; if( num >= font->numchars || !( font->chars[num].height ) ) num = REPLACEMENT_CHAR; if( num != ' ' ) SCR_DrawClampChar( x + xoffset, y + yoffset, num, xmin, ymin, xmax, ymax, font, scolor ); xoffset += font->chars[num].width; if( x + xoffset > xmax ) break; } else if( gc == GRABCHAR_COLOR ) { assert( ( unsigned )colorindex < MAX_S_COLORS ); VectorCopy( color_table[colorindex], scolor ); } else if( gc == GRABCHAR_END ) break; else assert( 0 ); } }
/* * FTLIB_GrabChar */ static int FTLIB_GrabChar( const char **pstr, wchar_t *wc, int *colorindex, int flags ) { if( flags & TEXTDRAWFLAG_NO_COLORS ) { wchar_t num = Q_GrabWCharFromUtf8String( pstr ); *wc = num; return num ? GRABCHAR_CHAR : GRABCHAR_END; } return Q_GrabWCharFromColorString( pstr, wc, colorindex ); }
//================== // SCR_StrlenForWidth // returns the len allowed for the string to fit inside a given width when using a given font. //================== size_t SCR_StrlenForWidth( const char *str, struct mufont_s *font, size_t maxwidth ) { const char *s, *olds; size_t width = 0; int gc; qwchar num; if( !str ) return 0; if( !font ) font = cls.fontSystemSmall; s = str; while( s ) { olds = s; gc = Q_GrabWCharFromColorString( &s, &num, NULL ); if( gc == GRABCHAR_CHAR ) { if( num == '\n' ) break; if( num < ' ' ) continue; if( num >= font->numchars || !( font->chars[num].height ) ) num = REPLACEMENT_CHAR; if( maxwidth && ( ( width + font->chars[num].width ) > maxwidth ) ) { s = olds; break; } width += font->chars[num].width; } else if( gc == GRABCHAR_COLOR ) continue; else if( gc == GRABCHAR_END ) break; else assert( 0 ); } return (unsigned int)( s - str ); }
//================== // SCR_strWidth // doesn't count invisible characters. Counts up to given length, if any. //================== size_t SCR_strWidth( const char *str, struct mufont_s *font, int maxlen ) { const char *s = str; size_t width = 0; qwchar num; if( !str ) return 0; if( !font ) font = cls.fontSystemSmall; while( *s && *s != '\n' ) { if( maxlen && ( s - str ) >= maxlen ) // stop counting at desired len return width; switch( Q_GrabWCharFromColorString( &s, &num, NULL ) ) { case GRABCHAR_CHAR: if( num < ' ' ) break; if( num >= font->numchars || !( font->chars[num].height ) ) num = REPLACEMENT_CHAR; width += font->chars[num].width; break; case GRABCHAR_COLOR: break; case GRABCHAR_END: return width; default: assert( 0 ); } } return width; }