Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] Podział sf::String na linie o wybranej maksymalnej długości.

Ostatnio zmodyfikowano 2012-08-06 16:37
Autor Wiadomość
akwes
Temat założony przez niniejszego użytkownika
[SFML] Podział sf::String na linie o wybranej maksymalnej długości.
» 2012-08-06 15:43:09
Witam.

Szukam sposobu jak wpisać ciągły tekst w prostokąt, przez łamanie go znakiem nowej linii.

// ascii art
Dane:

Szerokość prostokąta: =====================
Linia tekstu: To jest losowania linia, która musi zostać podzielona na kilka mniejszych o odpowiedniej długości.

Efektem powinno być:

===================
To jest losowania linia, która\n
musi zostać podzielona na kilka\n
mniejszych o odpowiedniej\n
długości.


Czyli ogólnie algorytm, który w odpowiednie miejsca wstawi '\n' i złamie string.

Można to zrobić ręcznie, ale każda zmiana pozycji, rozmiaru czcionki lub kroju czcionki zmusi do ponownego klepania i sprawdzania czy tekst dobrze się łamie. Chcę tego uniknąć.

Obliczenie rozmiaru znaku i na podstawie tego obliczanie złamań będzie działać tylko dla czcionek typu courier (stałej szerokości). Nie wszystkie czcionki takie są.

Jedyne co wymyśliłem to:

1. Podzielić std::string na wyrazy.
2. Do sf::String (początkowo pustego) dodać kolejny wyraz.
3. Jeżeli sf:String::GetRect().GetWidth() będzie większe niż zakładana szerokość to przed wyrazem wstawić '\n' i wrócić do 2. Jeżeli brak nowych wyrazów to zwrócić std::string.

Jednak wydaje mi się to mało eleganckie. Ktoś ma pomysły na lepszą metodę?

P-61850
waxx
» 2012-08-06 16:30:37
Masz z mojej gry:

C/C++
static std::vector < std::string > ParseString( const sf::String & str, int len )
{
    std::vector < std::string > lines;
   
    std::string text = str.GetText();
    std::string cur = "";
    std::string tr = "";
    std::vector < std::string > words = Functions::StringSplit( text, " " );
    while( tr.length() < text.length() )
    {
        sf::String s = sf::String( str );
        for( int i = 0; i < words.size(); i++ )
        {
            std::string future = cur +( cur.length() > 0 ? " "
                : "" ) + words[ i ];
            s.SetText( future );
            if( s.GetRect().GetWidth() > len ) break;
            else {
               
                tr +=( tr.length() > 0 ? " "
                    : "" ) + words[ i ];
                words.erase( words.begin() + i );
                cur = future;
                i = - 1;
            }
        }
        lines.push_back( cur );
        cur = "";
    }
   
    return lines;
}

static std::vector < std::string > StringSplit( std::string str, std::string delim )
{
    std::vector < std::string > results;
    int cutAt;
    while(( cutAt = str.find_first_of( delim ) ) != str.npos )
    {
        if( cutAt > 0 )
        {
            results.push_back( str.substr( 0, cutAt ) );
        }
        str = str.substr( cutAt + 1 );
    }
    if( str.length() > 0 )
    {
        results.push_back( str );
    }
    return results;
}
P-61852
akwes
Temat założony przez niniejszego użytkownika
» 2012-08-06 16:37:09
Dzięki wielkie ;D
P-61853
« 1 »
  Strona 1 z 1