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

Author Topic: Spacing error  (Read 6294 times)

0 Members and 3 Guests are viewing this topic.

ineed.help

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: Spacing error
« Reply #15 on: June 01, 2014, 12:26:46 pm »
Sorry about that.

I have another problem, though:
int main()
{
        std::string msg = "abcdefghijklmnopqrstuvwxyz";
        color = sf::Color(0, 0, 0);
        xPosition = 0; yPosition = 250;

        for (int i = 0; i < msg.length(); i++)
        {
                currentChar = msg[i];

                glyph = font.getGlyph(currentChar, fontSize, false);

                temporarySprite.setTexture(font.getTexture(24));
                temporarySprite.setTextureRect(glyph.textureRect);
                temporarySprite.setColor(color);
                if (i >= 1) { xPosition += font.getKerning(previousChar, currentChar, fontSize); }

                /////////////////////////////////////////
                // other unimportant stuff ... ... ... //
                /////////////////////////////////////////

                // THIS PART IS WHERE THE ERROR IS, I BELIEVE
                temporarySprite.setPosition(xPosition, yPosition);

                message.push_back(temporarySprite);

                xPosition += glyph.advance;

                previousChar = currentChar;
        }
}

When using this code, the output is:


As you can see, the characters aren't in their correct positions. I tried using the following code:
temporarySprite.setPosition(xPosition, yPosition + (font.getGlyph('A', fontSize, false).bounds.height - glyph.bounds.height));

Now, the output is:


As you can see, it is mostly fixed, but some letters are still not correctly positioned. I don't know what to do.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Spacing error
« Reply #16 on: June 01, 2014, 12:49:58 pm »
Your code is assuming that the "bottom" of a glyph is always on the baseline.  As you can see, this is not true for letters like p and q which have so-called "descenders".

If you read the documentation carefully, you'll notice that sf::Glyph::bounds is "Bounding rectangle of the glyph, in coordinates relative to the baseline. "  You should be able to figure it out from there.

ineed.help

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: Spacing error
« Reply #17 on: June 01, 2014, 01:54:57 pm »
... Yes, I know. I have read the documentation, but I still can't understand it. Do I use Glyph::textureRect instead? English is my second language, so I don't always understand exactly what everything means.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Spacing error
« Reply #18 on: June 01, 2014, 02:07:43 pm »
textureRect is the coordinates in the font texture where the glyph is rendered.  That's completely separate from the coordinates in your window that you want the glyph to be drawn to.  This is true of all computer graphics, which is why people normally talk about a texture's "texels" in "u/v coordinates" to clearly distinguish them from the actual monitor's pixels in x/y coordinates.  You're using the correct texels, but drawing them to the wrong pixels, so this is all about how you're using the bounds rectangle. 

Specifically, you need to be using top instead of height.  Because the rectangle's coordinates are relative to the baseline, the "top" member represents the distance between the baseline and the top of the glyph.  The "height" member represents the total height of the glyph, but the baseline could be anywhere inside the glyph so that doesn't tell you what the vertical offset should be.


By the way, if you have trouble understanding our explanations, it might be easier to just look at the function in sf::Text that does all of this stuff.
« Last Edit: June 01, 2014, 02:15:59 pm by Ixrec »

ineed.help

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: Spacing error
« Reply #19 on: June 01, 2014, 02:37:54 pm »
I don't think I fully understand, but after some tweaking I got this:

temporarySprite.setPosition(xPosition, yPosition + glyph.bounds.top);

... And it seems to work perfectly. (EDIT: So thank you very much for the help!)