void RichLabel::SplitLabel( const Gwen::UnicodeString & text, Gwen::Font* pFont, const DividedText & txt, int & x, int & y, int & lineheight ) { Gwen::Utility::Strings::UnicodeList lst; Gwen::Utility::Strings::Split( text, U" ", lst, true ); if ( lst.size() == 0 ) { return; } int iSpaceLeft = Width() - x; // Does the whole word fit in? { Gwen::Point StringSize = GetSkin()->GetRender()->MeasureText( pFont, text ); if ( iSpaceLeft > StringSize.x ) { return CreateLabel( text, txt, x, y, lineheight, true ); } } // If the first word is bigger than the line, just give up. { Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, lst[0] ); if ( WordSize.x >= iSpaceLeft ) { CreateLabel( lst[0], txt, x, y, lineheight, true ); if ( lst[0].size() >= text.size() ) { return; } Gwen::UnicodeString LeftOver = text.substr( lst[0].size() + 1 ); return SplitLabel( LeftOver, pFont, txt, x, y, lineheight ); } } Gwen::UnicodeString strNewString = U""; for ( size_t i = 0; i < lst.size(); i++ ) { Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, strNewString + lst[i] ); if ( WordSize.x > iSpaceLeft ) { CreateLabel( strNewString, txt, x, y, lineheight, true ); x = 0; y += lineheight; break;; } strNewString += lst[i]; } if ( strNewString.size() >= text.size() ) return; Gwen::UnicodeString LeftOver = text.substr( strNewString.size() + 1 ); return SplitLabel( LeftOver, pFont, txt, x, y, lineheight ); }
void Gwen::Utility::Strings::Split( const Gwen::UnicodeString& str, const Gwen::UnicodeString& seperator, Strings::UnicodeList& outbits, bool bLeave ) { int iOffset = 0; int iLength = str.length(); int iSepLen = seperator.length(); size_t i = str.find( seperator, 0 ); while ( i != std::wstring::npos ) { outbits.push_back( str.substr( iOffset, i-iOffset ) ); iOffset = i + iSepLen; i = str.find( seperator, iOffset ); if ( bLeave ) iOffset -= iSepLen; } outbits.push_back( str.substr( iOffset, iLength-iOffset ) ); }
void Text::RefreshSizeWrap() { RemoveAllChildren(); for( TextLines::const_iterator it = m_Lines.begin(), end = m_Lines.end(); it != end; ++it ) { Text *t = *it; delete t, t = 0; } m_Lines.clear(); std::vector<Gwen::UnicodeString> words; SplitWords( GetText().GetUnicode(), L' ', words ); // Adding a bullshit word to the end simplifies the code below // which is anything but simple. words.push_back( L"" ); if ( !GetFont() ) { Debug::AssertCheck( 0, "Text::RefreshSize() - No Font!!\n" ); return; } Point pFontSize = GetSkin()->GetRender()->MeasureText( GetFont(), L" " ); int w = GetParent()->Width(); int x = 0, y = 0; Gwen::UnicodeString strLine; std::vector<Gwen::UnicodeString>::iterator it = words.begin(); for ( it; it != words.end(); ++it ) { bool bFinishLine = false; bool bWrapped = false; // If this word is a newline - make a newline (we still add it to the text) if ( (*it).c_str()[0] == L'\n' ) bFinishLine = true; // Does adding this word drive us over the width? { strLine += (*it); Gwen::Point p = GetSkin()->GetRender()->MeasureText( GetFont(), strLine ); if ( p.x > Width() ) { bFinishLine = true; bWrapped = true; } } // If this is the last word then finish the line if ( --words.end() == it ) { bFinishLine = true; } if ( bFinishLine ) { Text* t = new Text( this ); t->SetFont( GetFont() ); t->SetString( strLine.substr( 0, strLine.length() - (*it).length() ) ); t->RefreshSize(); t->SetPos( x, y ); m_Lines.push_back( t ); // newline should start with the word that was too big strLine = *it; // Position the newline y += pFontSize.y; x = 0; //if ( strLine[0] == L' ' ) x -= pFontSize.x; } } // Size to children height and parent width { Point childsize = ChildrenSize(); SetSize( w, childsize.y ); } InvalidateParent(); Invalidate(); }
void Text::RefreshSizeWrap() { RemoveAllChildren(); for ( TextLines::iterator it = m_Lines.begin(); it != m_Lines.end(); ++it ) { delete *it; } m_Lines.clear(); std::vector<Gwen::UnicodeString> words; SplitWords( GetText().GetUnicode(), words ); // Adding a bullshit word to the end simplifies the code below // which is anything but simple. words.push_back( L"" ); if ( !GetFont() ) { Debug::AssertCheck( 0, "Text::RefreshSize() - No Font!!\n" ); return; } Point pFontSize = GetSkin()->GetRender()->MeasureText( GetFont(), L" " ); int w = GetParent()->Width() - GetParent()->GetPadding().left-GetParent()->GetPadding().right; int x = 0, y = 0; Gwen::UnicodeString strLine; for ( std::vector<Gwen::UnicodeString>::iterator it = words.begin(); it != words.end(); ++it ) { bool bFinishLine = false; bool bWrapped = false; // If this word is a newline - make a newline (we still add it to the text) if ( ( *it ).c_str() [0] == L'\n' ) { bFinishLine = true; } // Does adding this word drive us over the width? { strLine += ( *it ); Gwen::Point p = GetSkin()->GetRender()->MeasureText( GetFont(), strLine ); if ( p.x > w ) { bFinishLine = true; bWrapped = true; } } // If this is the last word then finish the line if ( --words.end() == it ) { bFinishLine = true; } if ( bFinishLine ) { Text* t = new Text( this ); t->SetFont( GetFont() ); t->SetTextColor( m_Color ); if(bWrapped) { t->SetString( strLine.substr( 0, strLine.length() - (*it).length() ) ); // newline should start with the word that was too big strLine = *it; } else { t->SetString( strLine.substr( 0, strLine.length()) ); //new line is empty strLine.clear(); } t->RefreshSize(); t->SetPos( x, y ); m_Lines.push_back( t ); // newline should start with the word that was too big // strLine = *it; // Position the newline y += pFontSize.y; x = 0; //if ( strLine[0] == L' ' ) x -= pFontSize.x; } } // Size to children height and parent width Point childsize = ChildrenSize(); { SetSize( w, childsize.y ); } // Align the text within the parent int y_offset = 0; for ( TextLines::iterator it = m_Lines.begin(); it != m_Lines.end(); ++it ) { Text* text = *it; const Rect & bounds = GetInnerBounds(); int x = 0; int y = 0; if ( m_iAlign & Pos::Left ) { x = bounds.x; } if ( m_iAlign & Pos::Right ) { x = bounds.x + ( bounds.w - text->Width() ); } if ( m_iAlign & Pos::CenterH ) { x = bounds.x + ( bounds.w - text->Width() ) * 0.5; } if ( m_iAlign & Pos::Top ) { y = bounds.y; } if ( m_iAlign & Pos::Bottom ) { y = bounds.y + ( bounds.h - childsize.y ); } if ( m_iAlign & Pos::CenterV ) { y = bounds.y + ( bounds.h - childsize.y ) * 0.5; } text->SetPos( x, y + y_offset ); y_offset += text->Height(); } InvalidateParent(); Invalidate(); }