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

Author Topic: Get the maximum possible height of single line sf::Text  (Read 1801 times)

0 Members and 1 Guest are viewing this topic.

vokazoo

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • Email
Get the maximum possible height of single line sf::Text
« on: June 17, 2024, 04:16:55 pm »
Hello,

According to this picture https://en.wikipedia.org/wiki/X-height#/media/File:Typography_Line_Terms.svg, I noticed that sf::Text::getCharacterSize() returns the distance between ascender height and baseline. However, I need to find the maximum height, from the picture it being the distance between ascender height and descender height (or just the height below baseline to the end).

The practical problem I'm having with this is when trying to vertically centre multi-line text in a text box. Global or local bounds cannot be used for this as they depend on the exact string the text is holding. For example, if I have text box with height of 100px, and text's character size is set to 30px, I would think the text box can hold 3 rows of text, but that's not true because the distance between the top of first line and the top of second line is greater than 30px. In other words I need the distance between the same point (for example top, or baseline) of two adjacent lines.

What would be the way to do this?
Thanks

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10976
    • View Profile
    • development blog
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #1 on: June 18, 2024, 08:57:00 am »
There isn't a function to directly get this information, as such you'll have to rely on the glyph information for specific characters.
U+2588 (█) should expand across the whole line, but this is "implementation" defined, meaning some fonts might not properly implement it for stylistic choices. You could also go with say M and p and get the combined height of them.

Note that if you use multiple lines, you'll also have to account for the line spacing between the lines.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

vokazoo

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #2 on: June 18, 2024, 09:45:33 am »
Thanks for the answer,

Unfortunately, many fonts don't have that character and even those that do have it, not always fill the full height, so it can't be used as a substitute for a function that would return this info. "Mp" is also unreliable and inconsistent between fonts.

I guess my only choice is to find the height of all characters from a font in advance individually (with local/global bounds), then save the maximum for each font.

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #3 on: June 18, 2024, 11:48:48 am »
This is why I created https://github.com/SFML/SFML/pull/3053
The information exists, SFML just doesn't expose it.

I've used "Êg" for finding the line height.
You can also check the getLineSpacing in the Font class. It will usually be close or equal to the size you need (unless the font is broken for multi-line texts).
TGUI: C++ SFML GUI

vokazoo

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #4 on: June 18, 2024, 02:40:31 pm »
That is exactly what I'm looking for!

But how can I use it? Do I need to use this whole branch of SFML just for font ascend/descent, or is it possible to just add it to an existing project? Not sure how all of that works. Thanks

texus

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • TGUI
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #5 on: June 18, 2024, 07:00:03 pm »
I wouldn't recommend using the branch I created. You could download the code from https://github.com/texus/SFML/tree/feature/font-ascent-descent and compile it with CMake if you want to, but I don't intend to keep the branch up-to-date with new changes being made into SFML.
The pull request that I linked to is something that will hopefully be merged into SFML at some point. I don't know how much they care about this functionality, I imagine that it has a low priority for now while they focus on API breaking changes for the SFML 3.0 release and might only properly look into this in a later update (e.g. SFML 3.1).

While having access the the ascent and descent allows fine control over the position of your text, maybe you don't necessarily need them right now.

Are you rendering the lines as a single sf::Text object (which contains newlines in its string)?
In that case you know that the distance between each line is exactly `font->getLineSpacing(characterSize)` (unless you called setLineSpacing on the sf::Text object, in which case you need to multiply it with that factor).

If you are rendering each line with a different sf::Text object then you can still use `font->getLineSpacing(characterSize)` to position them below each other. This will only fail with broken fonts, so unless you allow the user to set custom fonts you can ignore that.

In either case you may want to move the text or each line slightly upwards to compensate for the difference between characterSize and ascent (if you feel like text is always positioned slightly too low). The following code will get the ascent from the Ê character if it exists in the font, otherwise it assumes that characterSize equals the ascent and hope for the best.
Code: [Select]
float topOffset = 0;
if (font->hasGlyph(U'\u00CA'))
  topOffset -= font->getGlyph(U'\u00CA', characterSize, false, 0).bounds.height;
« Last Edit: June 18, 2024, 07:01:55 pm by texus »
TGUI: C++ SFML GUI

vokazoo

  • Newbie
  • *
  • Posts: 13
    • View Profile
    • Email
Re: Get the maximum possible height of single line sf::Text
« Reply #6 on: June 18, 2024, 07:26:08 pm »
Thank you for clearing that up for me.  :)

 sf::Font::getLineSpacing() will probably be good enough for now, though it'd still be nice to have actual ascend/descent values.