Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Text local bounds  (Read 8797 times)

0 Members and 1 Guest are viewing this topic.

user31182

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
sf::Text local bounds
« on: January 04, 2019, 08:58:17 pm »
Hi,

Question about how to interpret the result of getLocalBounds() when called for an sf::Text object.

I've got 4 strings which I am calling getLocalBounds() on, and the results are:

[left, top, width, height]

[ 0, 3, 32, 8 ]
[ 0, 3, 35, 8 ]
[ 0, 3, 33, 8 ]
[ 0, 3, 122, 11 ]

The top variable is always 3. I would have expected it to be zero. What is the interpretation of this?

 Thanks

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: sf::Text local bounds
« Reply #1 on: January 04, 2019, 09:39:15 pm »
It's 'free space' above your text. If you put in a few dots there will be more of that than if you put in a few tall letters there. I assume it's so that your string when displayed doesn't jump up and down as the highest letter changes.

Try this code to see:
#include <SFML/Graphics.hpp>

int main(int argc, char ** argv)
{
    sf::RenderWindow app(sf::VideoMode(800u, 600u), "font");
    sf::Font font;
    font.loadFromFile("DejaVuSans.ttf");
    sf::Text txt("", font);

    while(app.isOpen())
    {
        sf::Event eve;
        while(app.pollEvent(eve))
        {
            switch(eve.type)
            {
            case sf::Event::Closed:
                app.close();
                break;
            case sf::Event::TextEntered:
                txt.setString(txt.getString() + eve.text.unicode);
                break;
            }//switch
        }//while

        app.clear();

        sf::FloatRect r = txt.getLocalBounds();
        sf::RectangleShape sha;
        sha.setFillColor(sf::Color(0x7f7f7fff));
        sha.setPosition(sf::Vector2f(r.left, r.top));
        sha.setSize(sf::Vector2f(r.width, r.height));
        app.draw(sha);
        app.draw(txt);
        app.display();
    }//while

    return 0;
}

It actually behaves funny with width when there are leading or trailing spaces. Laurent?
« Last Edit: January 04, 2019, 09:41:45 pm by FRex »
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::Text local bounds
« Reply #2 on: January 05, 2019, 04:39:12 pm »
sf::Text, unlike other SFML entities, is aligned on its baseline, not on its top. I'm pretty sure it is explained somewhere in the documentation. So no, you can't expect "top" to be always zero for this class.

Quote
It actually behaves funny with width when there are leading or trailing spaces. Laurent?
How exactly does it behave in this case?
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: sf::Text local bounds
« Reply #3 on: January 05, 2019, 04:56:45 pm »
They behave like they have some width but 0 height and spread the bounding box out.

If you have some visible characters in the string then leading spaces will make the left be before first space and not before first real character and trailing spaces will increase the width.

You can check in my program above by putting in many spaces and then one @ or other big letter and more spaces. They change the bounding box width and left a lot despite adding no visible vertices.

Vertices of a text with many leading and trailing spaces would be bound perfectly by a bounding box of same text with no trailing or leading spaces, they are the same except for being offset to the right but that should increase 'left' (which I think is always 0 now?) and trailing spaces shouldn't add to width at all.

A string made of just spaces (so a 0 glyph one) has 0 height, 0 left, non 0 top (I didn't look into why yet), and width that increases with the amount of spaces.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::Text local bounds
« Reply #4 on: January 05, 2019, 09:09:32 pm »
Looks perfectly fine to me. A space is not visible but it has a width. If spaces took 0 width then they would be useless.

And who said that the bounding box should match the visible pixels? A transparent sprite has a valid bounding box as well, not an empty one.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: sf::Text local bounds
« Reply #5 on: January 05, 2019, 09:44:04 pm »
Quote
A space is not visible but it has a width. If spaces took 0 width then they would be useless.
Having width for the purpose of putting other letters in place is fine, but they shouldn't affect bounding box width if they are trailing or leading. Leading spaces should make bounding box left increase, not its width.

Quote
And who said that the bounding box should match the visible pixels?
It's kinda implied by the fact that's how it works in case of top (especially the non-0 top actually) and height (for one line strings, newlines act funny too). :-X

I'm just pointing an oddity out. I don't mind it or propose a change/fix.
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: sf::Text local bounds
« Reply #6 on: January 05, 2019, 10:25:02 pm »
Having width for the purpose of putting other letters in place is fine, but they shouldn't affect bounding box width if they are trailing or leading. Leading spaces should make bounding box left increase, not its width.
I disagree with this in SFML's case. A space is a character like any other, so the character 'n' will take up the space of 'n' and so will a space take up ' ' of space.
How a leading space affects the positioning of the text etc is part of some advanced type setting, which doesn't really fit into SFML - like what if I want custom tab stops and special indenting for paragraph starts and anything Word offers for text placing, etc? ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: sf::Text local bounds
« Reply #7 on: January 05, 2019, 10:52:28 pm »
This is about bounding box, not about how leading spaces indent text.

I'm just saying that it feels weird that text class takes special care in case of top to not set it always to 0 and match the pixels of the string with it but left and width don't match the pixels because 'who said they would'.

To me bounding box of "@       " should logically be the same as one for "@". And for "       @" the same as for "@" except for the higher left caused by the padding from spaces.

There's no real reason why both axes don't use same strategy (either match pixels or left/top = 0) other than a quirk of current implementation.

I know the bounding box isn't always minimal in SFML (actually - Sprite and Text don't say either way, VertexArray says it's minimal and Shape says it might not be minimal) so I won't say it again but come on. :P
« Last Edit: January 05, 2019, 10:59:23 pm by FRex »
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: sf::Text local bounds
« Reply #8 on: January 05, 2019, 11:03:45 pm »
Except space itself is a character that has a width, which is what Laurent and I have been trying to point out.
'@     ' should have the same width + the width of 'n' as '@     n' as a space is an actual character with width, same as '@nnnnnnn' takes up space, because 'n' has a width.
Or as a better demonstration, if you take a font that uses space as a printable character (think the dots to indicate a space in Word for example) or take the underline or strike-through decorations, should the bounding box not be adjusted for the now visible space character or visible decorations?

The bounding box, doesn't represent what you can see printed, but it represents how much space, characters take up.

The supposed inconsistency with top you mentioned, isn't an inconsistency, because there's no space character with a fixed height in existence, instead the reasoning for the different position is due to text alignment on the baseline.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/