SFML community forums

Help => Graphics => Topic started by: TheBoff on June 04, 2010, 08:43:51 pm

Title: Possible sf::String.GetRect() Bug
Post by: TheBoff on June 04, 2010, 08:43:51 pm
Hello All!

I've been writing a bit of a GUI library, and for it I need to know the bounds of an sf::String. I'm using the GetRect() method for this, but the rect it produces is somewhat taller than the actual text:

(http://dl.dropbox.com/u/234754/text%20bug.png)

The red rect is rendered using the rect returned from get rect. It is not anything to do with letters with tails, as the problem still occurs there. Using a smaller font size reduces the gap.

Is this deliberate behaviour, and if not, what can I do?[/img]
Title: Possible sf::String.GetRect() Bug
Post by: Laurent on June 04, 2010, 08:50:25 pm
It is. The returned height is the base character height (the one you set with SetSize), not the max of the string's characters.
Title: Possible sf::String.GetRect() Bug
Post by: TheBoff on June 05, 2010, 09:58:54 pm
For the record I use this function to do the job. If it becomes a bottleneck, I will only check characters at the start and ends of lines, rather than looping through all of them, but it's not going to be called very often at all, so...

Also, there are a couple of hacks for the width detection, which I couldn't get quite right.

Code: [Select]

sf::FloatRect get_string_area(const sf::String& str) {
const sf::Font& font = str.GetFont();
const std::string& text = str.GetText();
float right, bottom;
sf::FloatRect r; //Start with relative positions to begin with
for (uint char_i = 0; char_i < text.length(); ++char_i) {
const sf::Vector2f& pos = str.GetCharacterPos(char_i);
const sf::IntRect& glyph_rect = font.GetGlyph(text[char_i]).Rectangle;
const sf::Vector2f size(glyph_rect.GetWidth(), glyph_rect.GetHeight());
right = pos.x + size.x; bottom = pos.y + size.y;
if (pos.y < r.Top) { r.Top = pos.y; }
if (pos.x < r.Left) { r.Left = pos.x; }
if (right > r.Right) { r.Right = right; }
if (bottom > r.Bottom) { r.Bottom = bottom; }
}
const sf::FloatRect& str_r = str.GetRect();
sf::Vector2f pos = str.GetPosition();
pos.y += str_r.GetHeight() - r.GetHeight(); //Deals with the offset
pos.x += (str_r.GetWidth() - r.GetWidth()) / 2;
r.Left += pos.x + 2; r.Right += pos.x; //The plus 2 is a hack.
r.Top += pos.y; r.Bottom += pos.y;
return r;
}