Move ColorBitmapText to SNetSelectBase since this is very specific to the SMO code. This should probably be done in a general way in BitmapText and the string parsing to color code should be kept where it is used instead of part of the bitmap text class.

This commit is contained in:
Steve Checkoway
2007-06-09 07:56:34 +00:00
parent acb030f229
commit 32a9724841
4 changed files with 264 additions and 267 deletions
+2 -245
View File
@@ -207,10 +207,10 @@ void BitmapText::BuildChars()
float fX = SCALE( m_fHorizAlign, 0.0f, 1.0f, -m_size.x/2.0f, +m_size.x/2.0f - iLineWidth );
int iX = lrintf( fX );
for( unsigned i = 0; i < sLine.size(); ++i )
for( unsigned j = 0; j < sLine.size(); ++j )
{
RageSpriteVertex v[4];
const glyph &g = m_pFont->GetGlyph( sLine[i] );
const glyph &g = m_pFont->GetGlyph( sLine[j] );
if( m_pFont->IsRightToLeft() )
iX -= g.m_iHadvance;
@@ -620,249 +620,6 @@ void BitmapText::SetWrapWidthPixels( int iWrapWidthPixels )
SetText( m_sText, "", iWrapWidthPixels );
}
ColorBitmapText::ColorBitmapText( ) : BitmapText()
{
m_vColors.clear();
}
void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels )
{
ASSERT( m_pFont );
RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText;
if( iWrapWidthPixels == -1 ) // wrap not specified
iWrapWidthPixels = m_iWrapWidthPixels;
if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels )
return;
m_sText = sNewText;
m_iWrapWidthPixels = iWrapWidthPixels;
// Set up the first color.
m_vColors.clear();
ColorChange change;
change.c = RageColor ( 1, 1, 1, 1 );
change.l = 0;
m_vColors.push_back( change );
m_wTextLines.clear();
RString sCurrentLine = "";
int iLineWidth = 0;
RString sCurrentWord = "";
int iWordWidth = 0;
int iGlyphsSoFar = 0;
for( unsigned i = 0; i < m_sText.length(); i++ )
{
int iCharsLeft = m_sText.length() - i - 1;
// First: Check for the special (color) case.
RString FirstThree = m_sText.substr( i, 3 );
if( FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8 )
{
ColorChange change;
int r, g, b;
sscanf( m_sText, "|%*c0%2x%2x%2x", &r, &g, &b );
change.c = RageColor( r/255.f, g/255.f, b/255.f, 1.f );
change.l = iGlyphsSoFar;
if( iGlyphsSoFar == 0 )
m_vColors[0] = change;
else
m_vColors.push_back( change );
i+=8;
continue;
}
char curChar = m_sText[0];
int iCharLen = m_pFont->GetLineWidthInSourcePixels( wstring(1, curChar) );
switch( curChar )
{
case ' ':
if( /* iLineWidth == 0 &&*/ iWordWidth == 0 )
break;
sCurrentLine += sCurrentWord + " ";
iLineWidth += iWordWidth + iCharLen;
sCurrentWord = "";
iWordWidth = 0;
iGlyphsSoFar++;
break;
case '\n':
if( iLineWidth + iWordWidth > iWrapWidthPixels )
{
SimpleAddLine( sCurrentLine, iLineWidth );
if( iWordWidth > 0 )
iLineWidth = iWordWidth + //Add the width of a space
m_pFont->GetLineWidthInSourcePixels( RStringToWstring( " " ) );
sCurrentLine = sCurrentWord + " ";
iWordWidth = 0;
sCurrentWord = "";
iGlyphsSoFar++;
}
else
{
SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth );
sCurrentLine = ""; iLineWidth = 0;
sCurrentWord = ""; iWordWidth = 0;
}
break;
default:
if( iWordWidth + iCharLen > iWrapWidthPixels && iLineWidth == 0 )
{
SimpleAddLine( sCurrentWord, iWordWidth );
sCurrentWord = curChar; iWordWidth = iCharLen;
}
else if( iWordWidth + iLineWidth + iCharLen > iWrapWidthPixels )
{
SimpleAddLine( sCurrentLine, iLineWidth );
sCurrentLine = "";
iLineWidth = 0;
sCurrentWord += curChar;
iWordWidth += iCharLen;
}
else
{
sCurrentWord += curChar;
iWordWidth += iCharLen;
}
iGlyphsSoFar++;
break;
}
}
if( iWordWidth > 0 )
{
sCurrentLine += sCurrentWord;
iLineWidth += iWordWidth;
}
if( iLineWidth > 0 )
SimpleAddLine( sCurrentLine, iLineWidth );
BuildChars();
UpdateBaseZoom();
}
void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels)
{
m_wTextLines.push_back( RStringToWstring( sAddition ) );
m_iLineWidths.push_back( iWidthPixels );
}
void ColorBitmapText::DrawPrimitives( )
{
Actor::SetGlobalRenderStates(); // set Actor-specified render states
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );
/* Draw if we're not fully transparent or the zbuffer is enabled */
if( m_pTempState->diffuse[0].a != 0 )
{
//
// render the shadow
//
if( m_fShadowLength != 0 )
{
DISPLAY->PushMatrix();
DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a); // semi-transparent black
for( unsigned i=0; i<m_aVertices.size(); i++ )
m_aVertices[i].c = dim;
DrawChars();
DISPLAY->PopMatrix();
}
//
// render the diffuse pass
//
int loc = 0, cur = 0;
RageColor c = m_pTempState->diffuse[0];
for( unsigned i=0; i<m_aVertices.size(); i+=4 )
{
loc++;
if( cur < (int)m_vColors.size() )
{
if ( loc > m_vColors[cur].l )
{
c = m_vColors[cur].c;
cur++;
}
}
for( unsigned j=0; j<4; j++ )
m_aVertices[i+j].c = c;
}
DrawChars();
}
/* render the glow pass */
if( m_pTempState->glow.a > 0.0001f )
{
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
for( unsigned i=0; i<m_aVertices.size(); i++ )
m_aVertices[i].c = m_pTempState->glow;
DrawChars();
}
}
void ColorBitmapText::SetMaxLines( int iNumLines, int iDirection )
{
iNumLines = max( 0, iNumLines );
iNumLines = min( (int)m_wTextLines.size(), iNumLines );
if( iDirection == 0 )
{
// Crop all bottom lines
m_wTextLines.resize( iNumLines );
m_iLineWidths.resize( iNumLines );
}
else
{
// Because colors are relative to the beginning, we have to crop them back
unsigned shift = 0;
for( unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++ )
shift += m_wTextLines[i].length();
// When we're cutting out text, we need to maintain the last
// color, so our text at the top doesn't become colorless.
RageColor LastColor;
for( unsigned i = 0; i < m_vColors.size(); i++ )
{
m_vColors[i].l -= shift;
if( m_vColors[i].l < 0 )
{
LastColor = m_vColors[i].c;
m_vColors.erase( m_vColors.begin() + i );
i--;
}
}
// If we already have a color set for the first char
// do not override it.
if( m_vColors.size() > 0 && m_vColors[0].l > 0 )
{
ColorChange tmp;
tmp.c = LastColor;
tmp.l = 0;
m_vColors.insert( m_vColors.begin(), tmp );
}
m_wTextLines.erase( m_wTextLines.begin(), m_wTextLines.end() - iNumLines );
m_iLineWidths.erase( m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines );
}
BuildChars();
}
// lua start
#include "FontCharAliases.h"
class LunaBitmapText: public Luna<BitmapText>
+1 -20
View File
@@ -21,7 +21,7 @@ public:
bool LoadFromFont( const RString& sFontName );
bool LoadFromTextureAndChars( const RString& sTexturePath, const RString& sChars );
void SetText( const RString& sText, const RString& sAlternateText = "", int iWrapWidthPixels = -1 );
virtual void SetText( const RString& sText, const RString& sAlternateText = "", int iWrapWidthPixels = -1 );
void SetVertSpacing( int iSpacing );
void SetMaxWidth( float fMaxWidth );
void SetMaxHeight( float fMaxHeight );
@@ -70,25 +70,6 @@ protected:
void UpdateBaseZoom();
};
class ColorBitmapText : public BitmapText
{
public:
ColorBitmapText();
void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 );
void DrawPrimitives();
void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top
void SimpleAddLine( const RString &sAddition, int iWidthPixels );
void SetMaxLines( int iNumLines, int iDirection );
protected:
struct ColorChange
{
RageColor c; //Color to change to
int l; //Change Location
};
vector<ColorChange> m_vColors;
};
#endif
/*
+241
View File
@@ -14,6 +14,8 @@
#include "GameState.h"
#include "InputEventPlus.h"
#include "RageInput.h"
#include "Font.h"
#include "RageDisplay.h"
#define CHATINPUT_WIDTH THEME->GetMetricF(m_sName,"ChatInputBoxWidth")
#define CHATINPUT_HEIGHT THEME->GetMetricF(m_sName,"ChatInputBoxHeight")
@@ -218,6 +220,245 @@ void ScreenNetSelectBase::UpdateUsers()
}
}
void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels )
{
ASSERT( m_pFont );
RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText;
if( iWrapWidthPixels == -1 ) // wrap not specified
iWrapWidthPixels = m_iWrapWidthPixels;
if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels )
return;
m_sText = sNewText;
m_iWrapWidthPixels = iWrapWidthPixels;
// Set up the first color.
m_vColors.clear();
ColorChange change;
change.c = RageColor ( 1, 1, 1, 1 );
change.l = 0;
m_vColors.push_back( change );
m_wTextLines.clear();
RString sCurrentLine = "";
int iLineWidth = 0;
RString sCurrentWord = "";
int iWordWidth = 0;
int iGlyphsSoFar = 0;
for( unsigned i = 0; i < m_sText.length(); i++ )
{
int iCharsLeft = m_sText.length() - i - 1;
// First: Check for the special (color) case.
RString FirstThree = m_sText.substr( i, 3 );
if( FirstThree.CompareNoCase("|c0") == 0 && iCharsLeft > 8 )
{
ColorChange change;
int r, g, b;
sscanf( m_sText, "|%*c0%2x%2x%2x", &r, &g, &b );
change.c = RageColor( r/255.f, g/255.f, b/255.f, 1.f );
change.l = iGlyphsSoFar;
if( iGlyphsSoFar == 0 )
m_vColors[0] = change;
else
m_vColors.push_back( change );
i+=8;
continue;
}
char curChar = m_sText[0];
int iCharLen = m_pFont->GetLineWidthInSourcePixels( wstring(1, curChar) );
switch( curChar )
{
case ' ':
if( /* iLineWidth == 0 &&*/ iWordWidth == 0 )
break;
sCurrentLine += sCurrentWord + " ";
iLineWidth += iWordWidth + iCharLen;
sCurrentWord = "";
iWordWidth = 0;
iGlyphsSoFar++;
break;
case '\n':
if( iLineWidth + iWordWidth > iWrapWidthPixels )
{
SimpleAddLine( sCurrentLine, iLineWidth );
if( iWordWidth > 0 )
iLineWidth = iWordWidth + //Add the width of a space
m_pFont->GetLineWidthInSourcePixels( RStringToWstring( " " ) );
sCurrentLine = sCurrentWord + " ";
iWordWidth = 0;
sCurrentWord = "";
iGlyphsSoFar++;
}
else
{
SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth );
sCurrentLine = ""; iLineWidth = 0;
sCurrentWord = ""; iWordWidth = 0;
}
break;
default:
if( iWordWidth + iCharLen > iWrapWidthPixels && iLineWidth == 0 )
{
SimpleAddLine( sCurrentWord, iWordWidth );
sCurrentWord = curChar; iWordWidth = iCharLen;
}
else if( iWordWidth + iLineWidth + iCharLen > iWrapWidthPixels )
{
SimpleAddLine( sCurrentLine, iLineWidth );
sCurrentLine = "";
iLineWidth = 0;
sCurrentWord += curChar;
iWordWidth += iCharLen;
}
else
{
sCurrentWord += curChar;
iWordWidth += iCharLen;
}
iGlyphsSoFar++;
break;
}
}
if( iWordWidth > 0 )
{
sCurrentLine += sCurrentWord;
iLineWidth += iWordWidth;
}
if( iLineWidth > 0 )
SimpleAddLine( sCurrentLine, iLineWidth );
BuildChars();
UpdateBaseZoom();
}
void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels)
{
m_wTextLines.push_back( RStringToWstring( sAddition ) );
m_iLineWidths.push_back( iWidthPixels );
}
void ColorBitmapText::DrawPrimitives( )
{
Actor::SetGlobalRenderStates(); // set Actor-specified render states
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );
/* Draw if we're not fully transparent or the zbuffer is enabled */
if( m_pTempState->diffuse[0].a != 0 )
{
//
// render the shadow
//
if( m_fShadowLength != 0 )
{
DISPLAY->PushMatrix();
DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 ); // shift by 5 units
RageColor dim(0,0,0,0.5f*m_pTempState->diffuse[0].a); // semi-transparent black
for( unsigned i=0; i<m_aVertices.size(); i++ )
m_aVertices[i].c = dim;
DrawChars();
DISPLAY->PopMatrix();
}
//
// render the diffuse pass
//
int loc = 0, cur = 0;
RageColor c = m_pTempState->diffuse[0];
for( unsigned i=0; i<m_aVertices.size(); i+=4 )
{
loc++;
if( cur < (int)m_vColors.size() )
{
if ( loc > m_vColors[cur].l )
{
c = m_vColors[cur].c;
cur++;
}
}
for( unsigned j=0; j<4; j++ )
m_aVertices[i+j].c = c;
}
DrawChars();
}
/* render the glow pass */
if( m_pTempState->glow.a > 0.0001f )
{
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
for( unsigned i=0; i<m_aVertices.size(); i++ )
m_aVertices[i].c = m_pTempState->glow;
DrawChars();
}
}
void ColorBitmapText::SetMaxLines( int iNumLines, int iDirection )
{
iNumLines = max( 0, iNumLines );
iNumLines = min( (int)m_wTextLines.size(), iNumLines );
if( iDirection == 0 )
{
// Crop all bottom lines
m_wTextLines.resize( iNumLines );
m_iLineWidths.resize( iNumLines );
}
else
{
// Because colors are relative to the beginning, we have to crop them back
unsigned shift = 0;
for( unsigned i = 0; i < m_wTextLines.size() - iNumLines; i++ )
shift += m_wTextLines[i].length();
// When we're cutting out text, we need to maintain the last
// color, so our text at the top doesn't become colorless.
RageColor LastColor;
for( unsigned i = 0; i < m_vColors.size(); i++ )
{
m_vColors[i].l -= shift;
if( m_vColors[i].l < 0 )
{
LastColor = m_vColors[i].c;
m_vColors.erase( m_vColors.begin() + i );
i--;
}
}
// If we already have a color set for the first char
// do not override it.
if( m_vColors.size() > 0 && m_vColors[0].l > 0 )
{
ColorChange tmp;
tmp.c = LastColor;
tmp.l = 0;
m_vColors.insert( m_vColors.begin(), tmp );
}
m_wTextLines.erase( m_wTextLines.begin(), m_wTextLines.end() - iNumLines );
m_iLineWidths.erase( m_iLineWidths.begin(), m_iLineWidths.end() - iNumLines );
}
BuildChars();
}
void UtilSetQuadInit( Actor& actor, const RString &sClassName )
{
ActorUtil::LoadAllCommandsAndSetXYAndOnCommand( actor, sClassName );
+20 -2
View File
@@ -8,6 +8,24 @@
#include "Quad.h"
#include "BitmapText.h"
class ColorBitmapText : public BitmapText
{
public:
void SetText( const RString &sText, const RString &sAlternateText = "", int iWrapWidthPixels = -1 );
void DrawPrimitives();
void SetMaxLines( int iLines, bool bCutBottom = true ); //if bCutBottom = false then, it will crop the top
void SimpleAddLine( const RString &sAddition, int iWidthPixels );
void SetMaxLines( int iNumLines, int iDirection );
protected:
struct ColorChange
{
RageColor c; //Color to change to
int l; //Change Location
};
vector<ColorChange> m_vColors;
};
class ScreenNetSelectBase : public ScreenWithMenuElements
{
public:
@@ -21,8 +39,8 @@ public:
void UpdateTextInput();
private:
//Chatting
ColorBitmapText m_textChatInput;
ColorBitmapText m_textChatOutput;
ColorBitmapText m_textChatInput;
ColorBitmapText m_textChatOutput;
Sprite m_sprChatInputBox;
Sprite m_sprChatOutputBox;
RString m_sTextInput;