Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFML renderer MeasureText issues (width of space character) #60

Open
Walley7 opened this issue Jun 13, 2013 · 3 comments
Open

SFML renderer MeasureText issues (width of space character) #60

Walley7 opened this issue Jun 13, 2013 · 3 comments

Comments

@Walley7
Copy link

Walley7 commented Jun 13, 2013

SFML2 returns a width of 0 for the space glyph, which end up connecting to issues caused with multi line labels (all text ends up on the same line due to bounds not incrementing correctly). This may apply to SFML as well, though I haven't checked.

A semi hacky solution (tested to solve the multi line problem, but not much beyond that) is the following MeasureText function (the last 4 lines in the else statement being the brunt of the fix):

Gwen::Point Gwen::Renderer::SFML2::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
{
    // If the font doesn't exist, or the font size should be changed
    if ( !pFont->data || fabs( pFont->realsize - pFont->size * Scale() ) > 2 )
    {
        FreeFont( pFont );
        LoadFont( pFont );
    }
    
    const sf::Font* pSFFont = reinterpret_cast( pFont->data );
    
    sf::FloatRect sz;
    
    // MULTI LINE FIX: problem was SFML measuring spaces as having no dimensions
    if (text != L" ") {
        sf::Text sfStr;
        sfStr.setString( text );
        sfStr.setFont( *pSFFont );
        sfStr.setScale( Scale(), Scale() );
        sfStr.setCharacterSize( pFont->realsize );
        sz = sfStr.getLocalBounds();
    }
    else {
        sf::Text sfStr;
        sfStr.setString( text );
        sfStr.setFont( *pSFFont );
        sfStr.setScale( Scale(), Scale() );
        sfStr.setCharacterSize( pFont->realsize );
        sz = sfStr.getLocalBounds();
    
        // SFML gives 0 dimensions for a space, use advance and line spacing instead
        sz.left = 0.0f;
        sz.top = 0.0f;
        sz.width = pSFFont->getGlyph(L' ', pFont->realsize, false).advance;
        sz.height = pSFFont->getLineSpacing(pFont->realsize);
    }
    
    return Gwen::Point( sz.left + sz.width, sz.top + sz.height );
}
@Wizzard033
Copy link
Contributor

The fix seems to work for LabelMultiline but makes TextBox crash.

@Wizzard033
Copy link
Contributor

Here's the fix on the fix:

Gwen::Point Gwen::Renderer::SFML2::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
{
    // If the font doesn't exist, or the font size should be changed
    if ( !pFont->data || fabs( pFont->realsize - pFont->size * Scale() ) > 2 )
    {
        FreeFont( pFont );
        LoadFont( pFont );
    }

    const sf::Font* pSFFont = reinterpret_cast<sf::Font*>( pFont->data );

    sf::FloatRect sz;

    if (pSFFont) {
        if ( text != L" " ) {
            sf::Text sfStr;
            sfStr.setString( text );
            sfStr.setFont( *pSFFont );
            sfStr.setScale( Scale(), Scale() );
            sfStr.setCharacterSize( pFont->realsize );
            sz = sfStr.getLocalBounds();
        }

        // SFML gives 0 dimensions for a space, use line spacing instead
        sz.height = pSFFont->getLineSpacing( pFont->realsize );
    }

    return Gwen::Point( sz.left + sz.width, sz.top + sz.height );
}

@Wizzard033
Copy link
Contributor

The text in text entries was moving up/down depending on what character was typed and not handling trailing and preceding spaces properly. Final fix?

Gwen::Point Gwen::Renderer::SFML2::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
{
    // If the font doesn't exist, or the font size should be changed
    if ( !pFont->data || fabs( pFont->realsize - pFont->size * Scale() ) > 2 )
    {
        FreeFont( pFont );
        LoadFont( pFont );
    }

    const sf::Font* pSFFont = reinterpret_cast<sf::Font*>( pFont->data );

    Gwen::Point sz;

    if ( pSFFont ) {
        for ( Gwen::UnicodeString::const_iterator it = text.begin(); it != text.end(); ++it ) {
            sz.x += pSFFont->getGlyph( *it, pFont->realsize, false ).advance * Scale();
        }
        sz.y = pSFFont->getLineSpacing( pFont->realsize ) * Scale();
    }

    return sz;
}

(I ninja-edited a multiplication by Scale())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants