usbloadergx/source/libwiigui/Text.cpp

351 lines
6.7 KiB
C++
Raw Normal View History

#include "Text.hpp"
Text::Text( const char * t, int s, GXColor c )
: GuiText( t, s, c )
{
maxWidth = 400;
linestodraw = 9;
curLineStart = 0;
FirstLineOffset = 0;
wText = NULL;
if ( !text )
return;
wText = new ( std::nothrow ) wString( text );
if ( !wText )
{
return;
}
if ( wText->size() == 0 )
{
wText->push_back( L' ' );
wText->push_back( 0 );
}
textWidth = ( font ? font : fontSystem )->getWidth( wText->data(), currentSize );
delete [] text;
text = NULL;
SetMaxWidth( maxWidth );
}
Text::Text( const wchar_t * t, int s, GXColor c )
: GuiText( ( wchar_t * ) NULL, s, c )
{
maxWidth = 400;
linestodraw = 9;
curLineStart = 0;
FirstLineOffset = 0;
wText = NULL;
if ( !t )
return;
wText = new ( std::nothrow ) wString( t );
if ( !wText )
{
return;
}
if ( wText->size() == 0 )
{
wText->push_back( L' ' );
wText->push_back( 0 );
}
textWidth = ( font ? font : fontSystem )->getWidth( wText->data(), currentSize );
SetMaxWidth( maxWidth );
}
Text::~Text()
{
if ( wText )
delete wText;
wText = NULL;
TextLines.clear();
ClearDynamicText();
}
void Text::SetText( const char * t )
{
wchar_t * tmp = charToWideChar( t );
if ( !tmp )
return;
if ( wText )
delete wText;
wText = new ( std::nothrow ) wString( tmp );
if ( !wText )
{
return;
}
if ( wText->size() == 0 )
{
wText->push_back( L' ' );
wText->push_back( 0 );
}
textWidth = ( font ? font : fontSystem )->getWidth( wText->data(), currentSize );
delete [] tmp;
ClearDynamicText();
CalcLineOffsets();
}
void Text::SetText( const wchar_t * t )
{
if ( !t )
return;
if ( wText )
delete wText;
wText = new wString( t );
textWidth = ( font ? font : fontSystem )->getWidth( wText->data(), currentSize );
CalcLineOffsets();
}
void Text::SetMaxWidth( int w )
{
maxWidth = w;
curLineStart = 0;
Refresh();
}
void Text::SetTextLine( int line )
{
if ( line < 0 )
line = 0;
else if ( line > ( int ) TextLines.size() - 1 )
line = TextLines.size() - 1;
curLineStart = line;
FillRows();
while ( ( int ) textDyn.size() < linestodraw && curLineStart > 0 )
{
PreviousLine();
}
}
void Text::SetTextPos( int pos )
{
if ( !wText )
return;
int diff = 10000;
for ( u32 i = 0; i < TextLines.size(); i++ )
{
int curDiff = abs( TextLines[i].LineOffset - pos );
if ( curDiff < diff )
{
diff = curDiff;
curLineStart = i;
}
}
FillRows();
while ( ( int ) textDyn.size() < linestodraw && curLineStart > 0 )
{
PreviousLine();
}
}
const wchar_t * Text::GetText()
{
return wText->c_str();
}
std::string Text::GetUTF8String( void ) const
{
return wText->toUTF8();
}
int Text::GetLineOffset( int ind )
{
if ( TextLines.size() == 0 )
return 0;
if ( ind < 0 )
return TextLines[0].LineOffset;
if ( ind >= ( int ) TextLines.size() - 1 )
return TextLines[TextLines.size()-1].LineOffset;
return TextLines[ind].LineOffset;
}
const wchar_t * Text::GetTextLine( int ind )
{
if ( filling || textDyn.size() == 0 )
return NULL;
if ( ind < 0 )
return textDyn[0];
if ( ind >= ( int ) textDyn.size() )
return textDyn[textDyn.size()-1];
return textDyn[ind];
}
void Text::Refresh()
{
CalcLineOffsets();
FillRows();
}
void Text::NextLine()
{
if ( !wText || ( curLineStart + 1 > ( ( int ) TextLines.size() - linestodraw ) ) )
return;
++curLineStart;
FillRows();
}
void Text::PreviousLine()
{
if ( !wText || curLineStart - 1 < 0 )
return;
--curLineStart;
FillRows();
}
void Text::FillRows()
{
if ( !wText )
return;
filling = true;
ClearDynamicText();
for ( int i = 0; i < linestodraw && i < ( int ) TextLines.size(); i++ )
{
if ( i >= ( int ) textDyn.size() )
{
textDyn.resize( i + 1 );
textDyn[i] = new wchar_t[maxWidth];
}
int offset = TextLines[curLineStart+i].LineOffset;
int count = TextLines[curLineStart+i].CharCount + 1;
for ( int n = 0; n < count && offset + n < ( int ) wText->size(); n++ )
textDyn[i][n] = wText->at( offset + n );
textDyn[i][count] = 0;
}
filling = false;
return;
}
void Text::CalcLineOffsets()
{
if ( !wText )
return;
TextLines.clear();
TextLine TmpLine;
TmpLine.CharCount = 0;
TmpLine.LineOffset = 0;
TmpLine.width = 0;
const wchar_t * origTxt = wText->c_str();
int ch = 0;
int lastSpace = -1;
int lastSpaceIndex = -1;
int currWidth = 0;
int i = 0;
while ( origTxt[ch] )
{
currWidth += fontSystem->getCharWidth( origTxt[ch], currentSize, ch > 0 ? origTxt[ch-1] : 0x0000 );
if ( currWidth >= maxWidth )
{
if ( lastSpace > 0 )
{
ch = lastSpace;
}
TmpLine.CharCount = ch - TmpLine.LineOffset;
TmpLine.width = currWidth;
TextLines.push_back( TmpLine );
currWidth = 0;
lastSpace = -1;
i = -1;
TmpLine.LineOffset = ch + 1;
}
else if ( origTxt[ch] == '\n' )
{
TmpLine.CharCount = ch - TmpLine.LineOffset;
TmpLine.width = currWidth;
TextLines.push_back( TmpLine );
currWidth = 0;
lastSpace = -1;
i = -1;
TmpLine.LineOffset = ch + 1;
}
else if ( origTxt[ch] == ' ' )
{
lastSpace = ch;
lastSpaceIndex = i;
}
ch++;
i++;
}
TmpLine.CharCount = ch - TmpLine.LineOffset;
TmpLine.width = currWidth;
if ( TmpLine.CharCount > 0 )
TextLines.push_back( TmpLine );
}
void Text::Draw()
{
if ( textDyn.size() == 0 )
return;
if ( !this->IsVisible() )
return;
GXColor c = color;
c.a = this->GetAlpha();
int newSize = size * GetScale();
if ( newSize != currentSize )
{
currentSize = newSize;
if ( wText )
textWidth = ( font ? font : fontSystem )->getWidth( wText->data(), currentSize );
}
u16 lineheight = newSize + 6;
for ( u32 i = 0; i < textDyn.size(); i++ )
{
if ( !filling )
( font ? font : fontSystem )->drawText( this->GetLeft(), this->GetTop() + i*lineheight, 0, textDyn[i], currentSize, c, style, 0, maxWidth );
}
}