Support adding attributes to BitmapText. The only ones supported currently are diffuse color and glow color. Overlapping attributes are undefined. However, a length of -1 means the attribute applies until the end of the text or another attribute, whichever comes first.
This commit is contained in:
+171
-13
@@ -52,6 +52,7 @@ BitmapText::BitmapText()
|
|||||||
m_fMaxWidth = 0;
|
m_fMaxWidth = 0;
|
||||||
m_fMaxHeight = 0;
|
m_fMaxHeight = 0;
|
||||||
m_iVertSpacing = 0;
|
m_iVertSpacing = 0;
|
||||||
|
m_bHasGlowAttribute = false;
|
||||||
|
|
||||||
SetShadowLength( 4 );
|
SetShadowLength( 4 );
|
||||||
}
|
}
|
||||||
@@ -83,6 +84,8 @@ BitmapText &BitmapText::operator =( const BitmapText &cpy )
|
|||||||
CPY( m_iVertSpacing );
|
CPY( m_iVertSpacing );
|
||||||
CPY( m_aVertices );
|
CPY( m_aVertices );
|
||||||
CPY( m_pTextures );
|
CPY( m_pTextures );
|
||||||
|
CPY( m_bHasGlowAttribute );
|
||||||
|
CPY( m_mAttributes );
|
||||||
#undef CPY
|
#undef CPY
|
||||||
|
|
||||||
if( m_pFont )
|
if( m_pFont )
|
||||||
@@ -118,7 +121,6 @@ void BitmapText::LoadFromNode( const XNode* pNode )
|
|||||||
LoadFromFont( sFont );
|
LoadFromFont( sFont );
|
||||||
|
|
||||||
SetText( sText, sAltText );
|
SetText( sText, sAltText );
|
||||||
|
|
||||||
Actor::LoadFromNode( pNode );
|
Actor::LoadFromNode( pNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,15 +347,21 @@ void BitmapText::SetText( const RString& _sText, const RString& _sAlternateText,
|
|||||||
|
|
||||||
if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels )
|
if( m_sText == sNewText && iWrapWidthPixels==m_iWrapWidthPixels )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_sText = sNewText;
|
m_sText = sNewText;
|
||||||
m_iWrapWidthPixels = iWrapWidthPixels;
|
m_iWrapWidthPixels = iWrapWidthPixels;
|
||||||
|
ClearAttributes();
|
||||||
|
SetTextInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitmapText::SetTextInternal()
|
||||||
|
{
|
||||||
// Break the string into lines.
|
// Break the string into lines.
|
||||||
//
|
//
|
||||||
|
|
||||||
m_wTextLines.clear();
|
m_wTextLines.clear();
|
||||||
|
|
||||||
if( iWrapWidthPixels == -1 )
|
if( m_iWrapWidthPixels == -1 )
|
||||||
{
|
{
|
||||||
split( RStringToWstring(m_sText), L"\n", m_wTextLines, false );
|
split( RStringToWstring(m_sText), L"\n", m_wTextLines, false );
|
||||||
}
|
}
|
||||||
@@ -392,7 +400,7 @@ void BitmapText::SetText( const RString& _sText, const RString& _sAlternateText,
|
|||||||
|
|
||||||
RString sToAdd = " " + sWord;
|
RString sToAdd = " " + sWord;
|
||||||
int iWidthToAdd = m_pFont->GetLineWidthInSourcePixels(L" ") + iWidthWord;
|
int iWidthToAdd = m_pFont->GetLineWidthInSourcePixels(L" ") + iWidthWord;
|
||||||
if( iCurLineWidth + iWidthToAdd <= iWrapWidthPixels ) // will fit on current line
|
if( iCurLineWidth + iWidthToAdd <= m_iWrapWidthPixels ) // will fit on current line
|
||||||
{
|
{
|
||||||
sCurLine += sToAdd;
|
sCurLine += sToAdd;
|
||||||
iCurLineWidth += iWidthToAdd;
|
iCurLineWidth += iWidthToAdd;
|
||||||
@@ -546,12 +554,37 @@ void BitmapText::DrawPrimitives()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<m_aVertices.size(); i+=4 )
|
size_t i = 0;
|
||||||
|
map<size_t,Attribute>::const_iterator iter = m_mAttributes.begin();
|
||||||
|
while( i < m_aVertices.size() )
|
||||||
{
|
{
|
||||||
m_aVertices[i+0].c = m_pTempState->diffuse[0]; // top left
|
// Set the colors up to the next attribute.
|
||||||
m_aVertices[i+1].c = m_pTempState->diffuse[2]; // bottom left
|
size_t iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
|
||||||
m_aVertices[i+2].c = m_pTempState->diffuse[3]; // bottom right
|
iEnd = min( iEnd, m_aVertices.size() );
|
||||||
m_aVertices[i+3].c = m_pTempState->diffuse[1]; // top right
|
for( ; i < iEnd; i += 4 )
|
||||||
|
{
|
||||||
|
m_aVertices[i+0].c = m_pTempState->diffuse[0]; // top left
|
||||||
|
m_aVertices[i+1].c = m_pTempState->diffuse[2]; // bottom left
|
||||||
|
m_aVertices[i+2].c = m_pTempState->diffuse[3]; // bottom right
|
||||||
|
m_aVertices[i+3].c = m_pTempState->diffuse[1]; // top right
|
||||||
|
}
|
||||||
|
if( iter == m_mAttributes.end() )
|
||||||
|
break;
|
||||||
|
// Set the colors according to this attribute.
|
||||||
|
const Attribute &attr = iter->second;
|
||||||
|
++iter;
|
||||||
|
if( attr.length < 0 )
|
||||||
|
iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
|
||||||
|
else
|
||||||
|
iEnd = i + attr.length*4;
|
||||||
|
iEnd = min( iEnd, m_aVertices.size() );
|
||||||
|
for( ; i < iEnd; i += 4 )
|
||||||
|
{
|
||||||
|
m_aVertices[i+0].c = attr.diffuse[0]; // top left
|
||||||
|
m_aVertices[i+1].c = attr.diffuse[2]; // bottom left
|
||||||
|
m_aVertices[i+2].c = attr.diffuse[3]; // bottom right
|
||||||
|
m_aVertices[i+3].c = attr.diffuse[1]; // top right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,12 +626,32 @@ void BitmapText::DrawPrimitives()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* render the glow pass */
|
/* render the glow pass */
|
||||||
if( m_pTempState->glow.a > 0.0001f )
|
if( m_pTempState->glow.a > 0.0001f || m_bHasGlowAttribute )
|
||||||
{
|
{
|
||||||
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
|
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
|
||||||
|
|
||||||
for( unsigned i=0; i<m_aVertices.size(); i++ )
|
size_t i = 0;
|
||||||
m_aVertices[i].c = m_pTempState->glow;
|
map<size_t,Attribute>::const_iterator iter = m_mAttributes.begin();
|
||||||
|
while( i < m_aVertices.size() )
|
||||||
|
{
|
||||||
|
// Set the glow up to the next attribute.
|
||||||
|
size_t iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
|
||||||
|
iEnd = min( iEnd, m_aVertices.size() );
|
||||||
|
for( ; i < iEnd; ++i )
|
||||||
|
m_aVertices[i].c = m_pTempState->glow;
|
||||||
|
if( iter == m_mAttributes.end() )
|
||||||
|
break;
|
||||||
|
// Set the glow according to this attribute.
|
||||||
|
const Attribute &attr = iter->second;
|
||||||
|
++iter;
|
||||||
|
if( attr.length < 0 )
|
||||||
|
iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4;
|
||||||
|
else
|
||||||
|
iEnd = i + attr.length*4;
|
||||||
|
iEnd = min( iEnd, m_aVertices.size() );
|
||||||
|
for( ; i < iEnd; ++i )
|
||||||
|
m_aVertices[i].c = attr.glow;
|
||||||
|
}
|
||||||
DrawChars();
|
DrawChars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,7 +671,70 @@ void BitmapText::SetWrapWidthPixels( int iWrapWidthPixels )
|
|||||||
ASSERT( m_pFont ); // always load a font first
|
ASSERT( m_pFont ); // always load a font first
|
||||||
if( m_iWrapWidthPixels == iWrapWidthPixels )
|
if( m_iWrapWidthPixels == iWrapWidthPixels )
|
||||||
return;
|
return;
|
||||||
SetText( m_sText, "", iWrapWidthPixels );
|
m_iWrapWidthPixels = iWrapWidthPixels;
|
||||||
|
SetTextInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapText::Attribute BitmapText::GetDefaultAttribute() const
|
||||||
|
{
|
||||||
|
Attribute attr;
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
attr.diffuse[i] = GetDiffuses( i );
|
||||||
|
attr.glow = GetGlow();
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitmapText::AddAttribute( size_t iPos, const Attribute &attr )
|
||||||
|
{
|
||||||
|
m_mAttributes[iPos] = attr;
|
||||||
|
m_bHasGlowAttribute = m_bHasGlowAttribute || attr.glow.a > 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitmapText::ClearAttributes()
|
||||||
|
{
|
||||||
|
m_mAttributes.clear();
|
||||||
|
m_bHasGlowAttribute = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitmapText::Attribute::FromStack( lua_State *L, int iPos )
|
||||||
|
{
|
||||||
|
if( lua_type(L, iPos) != LUA_TTABLE )
|
||||||
|
return;
|
||||||
|
|
||||||
|
lua_pushvalue( L, iPos );
|
||||||
|
const int iTab = lua_gettop( L );
|
||||||
|
|
||||||
|
// Get the length.
|
||||||
|
lua_getfield( L, iTab, "Length" );
|
||||||
|
length = lua_tonumber( L, -1 );
|
||||||
|
lua_settop( L, iTab );
|
||||||
|
|
||||||
|
// Get the diffuse colors.
|
||||||
|
lua_getfield( L, iTab, "Diffuses" );
|
||||||
|
if( !lua_isnil(L, -1) )
|
||||||
|
{
|
||||||
|
for( int i = 1; i <= 4; ++i )
|
||||||
|
{
|
||||||
|
lua_rawgeti( L, -i, i );
|
||||||
|
diffuse[i-1].FromStack( L, -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_settop( L, iTab );
|
||||||
|
|
||||||
|
// Get a single diffuse color.
|
||||||
|
lua_getfield( L, iTab, "Diffuse" );
|
||||||
|
if( !lua_isnil(L, -1) )
|
||||||
|
{
|
||||||
|
diffuse[0].FromStack( L, -1 );
|
||||||
|
diffuse[1] = diffuse[2] = diffuse[3] = diffuse[0];
|
||||||
|
}
|
||||||
|
lua_settop( L, iTab );
|
||||||
|
|
||||||
|
// Get the glow color.
|
||||||
|
lua_getfield( L, iTab, "Glow" );
|
||||||
|
glow.FromStack( L, -1 );
|
||||||
|
|
||||||
|
lua_settop( L, iTab - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// lua start
|
// lua start
|
||||||
@@ -646,6 +762,46 @@ public:
|
|||||||
static int rainbowscroll( T* p, lua_State *L ) { p->SetRainbowScroll( BArg(1) ); return 0; }
|
static int rainbowscroll( T* p, lua_State *L ) { p->SetRainbowScroll( BArg(1) ); return 0; }
|
||||||
static int jitter( T* p, lua_State *L ) { p->SetJitter( BArg(1) ); return 0; }
|
static int jitter( T* p, lua_State *L ) { p->SetJitter( BArg(1) ); return 0; }
|
||||||
static int GetText( T* p, lua_State *L ) { lua_pushstring( L, p->GetText() ); return 1; }
|
static int GetText( T* p, lua_State *L ) { lua_pushstring( L, p->GetText() ); return 1; }
|
||||||
|
static int AddAttribute( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
size_t iPos = IArg(1);
|
||||||
|
BitmapText::Attribute attr = p->GetDefaultAttribute();
|
||||||
|
|
||||||
|
attr.FromStack( L, 2 );
|
||||||
|
p->AddAttribute( iPos, attr );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int FindText( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
const vector<wstring> &wTextLines = p->GetLines();
|
||||||
|
const wstring wText = RStringToWstring( SArg(1) );
|
||||||
|
wstring::size_type iStartPos = IArg(2);
|
||||||
|
wstring::size_type iAdditionalPos = 0;
|
||||||
|
|
||||||
|
FOREACH_CONST( wstring, wTextLines, line )
|
||||||
|
{
|
||||||
|
wstring::size_type length = line->length();
|
||||||
|
if( length < iStartPos )
|
||||||
|
{
|
||||||
|
iStartPos -= length;
|
||||||
|
iAdditionalPos += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wstring::size_type iPos = line->find( wText, iStartPos );
|
||||||
|
if( iPos != wstring::npos )
|
||||||
|
{
|
||||||
|
lua_pushnumber( L, iAdditionalPos + iPos );
|
||||||
|
lua_pushnumber( L, wText.length() );
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
iAdditionalPos += length;
|
||||||
|
iStartPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnil( L );
|
||||||
|
lua_pushnil( L );
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
LunaBitmapText()
|
LunaBitmapText()
|
||||||
{
|
{
|
||||||
@@ -657,6 +813,8 @@ public:
|
|||||||
ADD_METHOD( rainbowscroll );
|
ADD_METHOD( rainbowscroll );
|
||||||
ADD_METHOD( jitter );
|
ADD_METHOD( jitter );
|
||||||
ADD_METHOD( GetText );
|
ADD_METHOD( GetText );
|
||||||
|
ADD_METHOD( AddAttribute );
|
||||||
|
ADD_METHOD( FindText );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -665,7 +823,7 @@ LUA_REGISTER_DERIVED_CLASS( BitmapText, Actor )
|
|||||||
// lua end
|
// lua end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2003-2004 Chris Danford, Charles Lohr
|
* (c) 2003-2007 Chris Danford, Charles Lohr, Steve Checkoway
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
/* BitmapText - An actor that holds a Font and draws text to the screen. */
|
/* BitmapText - An actor that holds a Font and draws text to the screen. */
|
||||||
|
|
||||||
#ifndef BITMAPTEXT_H
|
#ifndef BITMAP_TEXT_H
|
||||||
#define BITMAPTEXT_H
|
#define BITMAP_TEXT_H
|
||||||
|
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
class RageTexture;
|
#include <map>
|
||||||
|
|
||||||
|
class RageTexture;
|
||||||
class Font;
|
class Font;
|
||||||
|
|
||||||
class BitmapText : public Actor
|
class BitmapText : public Actor
|
||||||
@@ -36,12 +37,27 @@ public:
|
|||||||
|
|
||||||
void SetHorizAlign( float f );
|
void SetHorizAlign( float f );
|
||||||
|
|
||||||
void GetLines( vector<wstring> &wTextLines ) { wTextLines = m_wTextLines; }
|
void GetLines( vector<wstring> &wTextLines ) const { wTextLines = m_wTextLines; }
|
||||||
|
const vector<wstring> &GetLines() const { return m_wTextLines; }
|
||||||
|
|
||||||
RString GetText() const { return m_sText; }
|
RString GetText() const { return m_sText; }
|
||||||
/* Return true if the string 's' will use an alternate string, if available. */
|
/* Return true if the string 's' will use an alternate string, if available. */
|
||||||
bool StringWillUseAlternate( const RString& sText, const RString& sAlternateText ) const;
|
bool StringWillUseAlternate( const RString& sText, const RString& sAlternateText ) const;
|
||||||
|
|
||||||
|
struct Attribute
|
||||||
|
{
|
||||||
|
Attribute() : length(-1) { }
|
||||||
|
int length;
|
||||||
|
RageColor diffuse[4];
|
||||||
|
RageColor glow;
|
||||||
|
|
||||||
|
void FromStack( lua_State *L, int iPos );
|
||||||
|
};
|
||||||
|
|
||||||
|
Attribute GetDefaultAttribute() const;
|
||||||
|
void AddAttribute( size_t iPos, const Attribute &attr );
|
||||||
|
void ClearAttributes();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Commands
|
// Commands
|
||||||
//
|
//
|
||||||
@@ -61,17 +77,22 @@ protected:
|
|||||||
|
|
||||||
vector<RageSpriteVertex> m_aVertices;
|
vector<RageSpriteVertex> m_aVertices;
|
||||||
vector<RageTexture *> m_pTextures;
|
vector<RageTexture *> m_pTextures;
|
||||||
|
map<size_t, Attribute> m_mAttributes;
|
||||||
|
bool m_bHasGlowAttribute;
|
||||||
|
|
||||||
// recalculate the items in SetText()
|
// recalculate the items in SetText()
|
||||||
void BuildChars();
|
void BuildChars();
|
||||||
void DrawChars();
|
void DrawChars();
|
||||||
void UpdateBaseZoom();
|
void UpdateBaseZoom();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetTextInternal();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) 2001-2004 Chris Danford, Charles Lohr
|
* (c) 2001-2007 Chris Danford, Charles Lohr, Steve Checkoway
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|||||||
Reference in New Issue
Block a user