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

Author Topic: Fonts and .ttf Metrics  (Read 9347 times)

0 Members and 1 Guest are viewing this topic.

NeomerArcana

  • Newbie
  • *
  • Posts: 12
    • View Profile
Fonts and .ttf Metrics
« on: April 21, 2014, 12:40:05 pm »
Hi,

I've had an ongoing problem with SFML which I've also noticed in SFGUI. Basically, it's that a lot of .ttf fonts include accented unicode characters which gives the font a large Ascent and Descent value in the font metrics. Most programs I think ignore this stuff when typing text and sort of recalculate it on their own, but not the case in SFML (and therefore SFGUI).

So for example, outputting text in SFML at position 0,0 makes the text appear to be more at like 0,20 because of the whitespace above to make room for ascent characters. But if I then .getLocalBounds() on the object the local bounds do not start at 0,0 (my guess is because it calculates the ACTUAL bounds of the displayed text?).

I've tried downloading FontForge to manually edit the various Ascender and Descender values for my font, but it doesn't seem to have much of an effect. Changing the EM size seems to have an effect, but it's like SFML (or maybe it's FreeType behind the scenes) is ignoring it.

Does anyone know how I can edit the font, what specific values to change, to get it to use whatever value I want to decide where the "top" of the text could be? Currently the "top" is like the top of an accented uppercase A, but I want it to be the top of a regular A.

Is there anything I can do to the source of SFML to change the way it reads the font as well (if it's needed)?

AlexxanderX

  • Full Member
  • ***
  • Posts: 128
    • View Profile
    • AlexanderX
Re: Fonts and .ttf Metrics
« Reply #1 on: April 21, 2014, 01:28:03 pm »
I found this trick and works well for me:
text.setGlobalBounds(text.getGlobalBounds.left, text.getGlobalBounds().top);
Here you can find my blog and tutorials about SFML - http://alexanderx.net/ (died...) - http://web.archive.org/web/20160110002847/http://alexanderx.net/

G.

  • Hero Member
  • *****
  • Posts: 1592
    • View Profile
Re: Fonts and .ttf Metrics
« Reply #2 on: April 21, 2014, 01:48:36 pm »
Would positioning your text at x - left and y - top good enough?
I found this trick and works well for me:
text.setGlobalBounds(text.getGlobalBounds.left, text.getGlobalBounds().top);
?????????? setGlobalBounds doesn't even exist, what is this non-sense?

NeomerArcana

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Fonts and .ttf Metrics
« Reply #3 on: April 21, 2014, 02:12:35 pm »
I guess I could just offset the position, the issue I have is that I'd like to not use a workaround and instead understand the reason so I can adjust my font file.

In SFGUI I'm unable to offset the text on a button anyway, which is why I've asked.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Fonts and .ttf Metrics
« Reply #4 on: April 21, 2014, 03:17:26 pm »
SFML computes a glyph's height based on its isolated (not considering the rest of the character set) FreeType bitmap size here. Based on the required glyphs for a given sf::Text the AABB is computed and returned either with .getLocalBounds() or .getGlobalBounds(). I tried various examples and even inspected the allocated texture rectangles in SFML and SFGUI and couldn't find any empty space above or below any glyphs even though SFGUI uses a unicode font by default.

Maybe you could provide the font and a small example program for us to test? It would make searching for a possible bug easier.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

NeomerArcana

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Fonts and .ttf Metrics
« Reply #5 on: April 22, 2014, 11:41:04 am »
Yes of course, here's the code. You will see that it prints "Penguin" in red text and retrieves the local bounds of the text to then draw a green box.

The text is positioned at 0,0 yet it doesn't appear there. You can also see that the local bounds don't start at 0,0 (from the console output).

The font is attached. I've tried this with several different fonts that I've downloaded from various websites. I've also tried it with "arial.ttf" taken, unmodified, directly from my C:/Windows/Fonts directory. Same problem persists.

This all leads me to think it's some issue with the way .ttf fonts are loaded. But I don't know enough about font file formats or FreeType to work it out.

#include <SFML/Graphics.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(1600, 900), "Pirate Game", sf::Style::Titlebar | sf::Style::Close);
   
        sf::Font f;
        f.loadFromFile("BOOTERFZ.ttf");
        sf::Text t("Penguin", f, 500);
        t.setPosition(0,0);
        t.setColor(sf::Color(255,0,0));
        sf::FloatRect ff = t.getLocalBounds();
        sf::RectangleShape r(sf::Vector2f(ff.width,ff.height));
        r.setPosition(ff.left,ff.top);
        r.setFillColor(sf::Color(0,255,0));
        std::cout << ff.left << ", " << ff.top << ", " << ff.width << ", " << ff.height << std::endl;
       
        while(window.isOpen())
        {
            sf::Event event;
            while(window.pollEvent(event))
            {
                if(event.type == sf::Event::Closed)
                {
                    window.close();
                }
            }
            window.clear();

            window.draw(r);
            window.draw(t);
            window.display();
        }

    return 0;
}
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Fonts and .ttf Metrics
« Reply #6 on: April 22, 2014, 11:51:59 am »
What is the problem exactly? You obviously understand that glyphs are aligned on their baseline and not on their top position, thus producing some space at the top which matches the height of the highest glyph in the font (like an accentuated capital letter). You also understand that the bounding box of the text is not positioned at (0, 0) to reflect this fact.

So, if I understood what you want ;) you should just subtract (bounds.left, bounds.top) from the text position to have it aligned visually to the required position. No?
Laurent Gomila - SFML developer

NeomerArcana

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Fonts and .ttf Metrics
« Reply #7 on: April 22, 2014, 12:00:28 pm »
Thanks for your reply Laurent, and thanks for all your effort in SFML.

I don't think it's using the highest glyph character.

sf::Text t(L"ÙPenguin", f, 50);

Using this string is giving me the same problem. I've looked in FontForge and this character is just below the Ascender, so there should definitely not be that much whitespace above.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Fonts and .ttf Metrics
« Reply #8 on: April 22, 2014, 03:12:21 pm »
Don't try to understand how much space there is. Talking about the highest glyph was just an example, the actual rule is probably different. All you have to know is that the glyphs are aligned on the baseline, and as a consequence, there is extra space at the top.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Fonts and .ttf Metrics
« Reply #9 on: April 22, 2014, 06:35:52 pm »
Actually Laurent, NeomerArcana has a point. Depending on how the font was designed there can be a bit too much extra space at the "top" of a glyph. SFML requests from freetype that it set its pixel size using FT_Set_Pixel_Sizes. In sf::Text, it is assumed that the character size of the font is exactly the same as its ascent. In cases where this is not the case, such as this font, it will leave some room between the ascent (nominally the height of the highest glyph) and the "true" top of the virtual space that the font uses in its definition.

I don't know how strict these font designing guidelines are, but I can imagine that many such fonts exist that don't truly fill up all the vertical room given to them, instead relying on the software to position based on ascent, descent and line gap which is what SFML already does for line spacing by using freetype's height (ascent - descent + line gap) field.

This picture shows the uncorrected and corrected positions:


The patch is simply to subtract the missing space that SFML currently assumes to be 0 from the glyph's own vertical offset:
 src/SFML/Graphics/Font.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp
index 954c8b5..0cf7b3d 100644
--- a/src/SFML/Graphics/Font.cpp
+++ b/src/SFML/Graphics/Font.cpp
@@ -445,6 +445,11 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) c
 
     int width  = bitmap.width;
     int height = bitmap.rows;
+    int ascender = face->size->metrics.ascender >> 6;
+
+    // Offset to make up for empty space between ascender and virtual top of the typeface
+    int ascenderOffset = characterSize - ascender;
+
     if ((width > 0) && (height > 0))
     {
         // Leave a small padding around characters, so that filtering doesn't
@@ -459,7 +464,7 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) c
 
         // Compute the glyph's bounding box
         glyph.bounds.left   = bitmapGlyph->left - padding;
-        glyph.bounds.top    = -bitmapGlyph->top - padding;
+        glyph.bounds.top    = -bitmapGlyph->top - padding - ascenderOffset;
         glyph.bounds.width  = width + 2 * padding;
         glyph.bounds.height = height + 2 * padding;
Of course, with this patch, fonts that have non-standard ascender definitions that don't cover the whole height of the glyphs will be incorrectly displayed, but I can imagine that that will be the case with any other software that uses the font as well.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Fonts and .ttf Metrics
« Reply #10 on: April 22, 2014, 07:02:51 pm »
I thought I had used all the font metrics correctly, that was not the case. Thanks for the explanation and the patch.

Remember to apply it as soon as you have push access to the repository :P
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Fonts and .ttf Metrics
« Reply #11 on: April 22, 2014, 07:20:12 pm »
Remember to apply it as soon as you have push access to the repository :P
Why can't you apply it? It would be much simpler and it would have gotten reviewed ;D.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Fonts and .ttf Metrics
« Reply #12 on: April 22, 2014, 07:49:14 pm »
Consider it reviewed. There's nothing else I can do due to my limited time, remember? :P

Moreover, I'm currently reviewing the blending modes branch, and I'm too lazy I don't have time to stash my modifications to switch to master.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Fonts and .ttf Metrics
« Reply #13 on: April 22, 2014, 10:26:08 pm »
You'll still have to do the honours this time:
https://github.com/SFML/SFML/pull/576
... since I still can't do it myself ;D.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Fonts and .ttf Metrics
« Reply #14 on: April 22, 2014, 10:42:22 pm »
Fair enough.

Thanks ;)
Laurent Gomila - SFML developer

 

anything