Archive

Archive for 01.08.2011

And yet it moves

Good news, everyone. My blog is still alive! It may have seemed somewhat dead recently, perhaps even as dead as that squirrel. I haven’t really posted anything substantial for a while. But now I’m back and ready to get to it once more. Hopefully you’ll enjoy my article on SFML Fonts and Texts, if you haven’t already, which I have finally managed to get to you with fewer than 60 minutes left in the day.

However, you may wonder why I have released video 5 before video 4. I assure you that I can in fact count – though believe it or not, basic numeracy is not as essential for a maths degree as you might expect – and that I simply found myself in the mood to talk about text and fonts rather than video modes and windowing. Nonetheless, that video should be here soon as well, to supplement the article I have already written on the subject.

Categories: Notice

SFML Graphics – Fonts and Text

01.08.2011 12 comments

In this tutorial, I’m going to tell you about another SFML graphics feature – text. By the end, you should be happy loading fonts from files, and using them to display text to the screen. We’ll also briefly discuss the manipulation of text as a graphics object. As we go along, I’ll make some analogies to SFML’s image handling features, to ease the learning process.

The Video

Working with text in SFML

Let’s get straight to it. Open up our Minimal Application project (you know – the one which just created an empty window and cleared it to a constant colour). If you don’t have the source code for this application at hand, you can find it with the corresponding tutorial.

Getting Started

So first, let’s just go ahead and display our first piece of text. Add the following line before the start of your main loop.

sf::Text Text("SFML Coder");

This constructs a text object which contains the text ‘SFML Coder’. Now we just need to display it. Add the following code after the call to sf::Window::Clear(sf::Color&), but before sf::Window::Display(void).

Window.Draw(Text);

And that’s it. Run your app and you should get some text!

But that’s not really it, is it? ;) Sure, we displayed some text, but we should be able to do a whole lot more. Maybe you want to change the font face or size. Maybe you want to scale the text, or apply a colour to it. Maybe you want to apply other transformations to it, such as rotation and translation. Well you can do all these things, and we’ll see how next.

Custom Fonts

Loading a Font

Remember when we worked with images, SFML had two classes: the lightweight and easily copiable sf::Sprite and the resource heavy, slow-to-load sf::Image? Well it’s the same with text. sf::Font does the heavy lifting – loading ‘glyphs’ from font files into memory, while sf::Text worries about drawing things to the screen, without managing the actual pixel data.

Note that this means it’s not advisable to load fonts on the fly and copying of fonts should be avoided where possible. On the other hand, sf::Text can be both copied freely and created mid frame without performance issues.

So. Let’s see how to load a font now. Add this code before you enter the main loop. We’ll create an object of type sf::Font and load a font into it, from the file font.ttf. You’ll need to provide the file font.ttf in the project directory to run your application. Just grab something from your system fonts folder, copy and paste it, and rename it.

sf::Font Font;
if (!Font.LoadFromFile("font.ttf"))
  return 1;

sf::Font‘s default constructor doesn’t do much. The real work happens in sf::Font::LoadFromFile. This function is similar to sf::Image::LoadFromFile: they both return false on failure and true on success, and they both take a single string filename to specify the file from which to load. On failure, we return 1 to end our program signifying failure to the thing that started it (probably the operating system).

Text: The Full Constructor

In fact, sf::Text has a few more parameters in its constructor than we used last time. We passed just one: a constant reference to a string. Now we’ll add an additional two!

sf::Text Text2("SFML Coder", Font, 40U);

The second argument we pass is a reference to a font object. Note that this argument defaults to sf::Font::GetDefaultFont() which returns a reference to a default, inbuilt font which SFML has (Arial). The third argument is an unsigned integer to specify the size of the font. 30 is used by default. (Note the trailing U marks the integral literal 20 as unsigned).

Now replace the line to draw the previous font with this:

Window.Draw(Text2);

And you’ll see that the text is now smaller, and also in whatever font you provided in the directory.

Controlling Text Attributes after Construction

So an object of type sf::Text has a size, a font and a textual string associated with it, which could be set during construction. Such an object also has a style (bold, italic, underlined, normal, or a combination thereof). This cannot be set by the constructor, but it can be accessed afterwards via get/set methods. Indeed the other three things (the text string, the size and the font) can also be manipulated using get/set functions:

  • to access the font (face): sf::Text::GetFont() and sf::Text::SetFont(const sf::Font&)
  • to access the font size: sf::Text::GetCharacterSize() and sf::Text::SetCharacterSize(unsigned)
  • to access the text string: sf::Text::GetString() and sf::Text::SetString(const sf::string&)
  • to access the style: sf::Text::GetStyle() and sf::Text::SetStyle(unsigned long)
Note that all the text styles are located within the enumeration sf::Text::Style. For example, let’s create a third sf::Text, using it’s default constructor and then setting it’s properties using set methods.
sf::Text Text3;
Text3.SetFont(Font);
Text3.SetCharacterSize(20U);
Text3.SetString("http://www.youtube.com/sfmlcoder/");
Text3.SetStyle(sf::Text::Bold | sf::Text::Underlined);

Manipulating Text

Now sf::Text is derived from sf::Drawable, just like sf::Sprite. That means that all the manipulations we could perform on a sprite (translation, rotation, scaling and applying colours) can equally be applied to a text object. You can get and set its position using sf::Drawable::GetPosition() and sf::Drawable::SetPosition(const sf::Vector2f&) respectively. Similarly, there are functions for rotation and scaling, as well as relative transformations. Then you can use sf::Drawable::SetColor(const sf::Color&) to apply a colour to the text.

I shan’t say too much more on this subject, as I provided some examples in the Images and Sprites tutorial, and you can also read more here. Just remember, of course, that all these manipulations are applied to the sf::Text object and not the sf::Font object.

Here’s a brief example of possible manipulations applied to our last sf::Text object.

</p>

<pre>Text3.Move(400.0f, 300.0f);
Text3.Scale(2.0f, 1.8f);
Text3.SetColor(sf::Color(255, 0, 0));</pre>
<p style="text-align: justify;">

Complete Source Code

Below is the complete source code for this tutorial.

#include <SFML/Graphics.hpp>

int main()
{
	sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "SFMLCoder Tutorial - Text and Fonts");

    sf::Text Text("SFML Coder");

    sf::Font Font;
    if (!Font.LoadFromFile("font.ttf"))
        return 1;
    sf::Text Text2("http://sfmlcoder.wordpress.com/", Font, 40U);

    sf::Text Text3;
    Text3.SetFont(Font);
    Text3.SetCharacterSize(20U);
    Text3.SetString("http://www.youtube.com/sfmlcoder/");
    Text.SetStyle(sf::Text::Bold | sf::Text::Underlined);

    Text3.Move(400.0f, 300.0f);
    Text3.Scale(2.0f, 1.8f);
    Text3.SetColor(sf::Color(255, 0, 0));

	while (Window.IsOpened())
	{
		sf::Event Event;
		while (Window.PollEvent(Event))
		{
			switch (Event.Type)
			{
			case sf::Event::Closed:
				Window.Close();
				break;
			default:
				break;
			}
		}

		Window.Clear();
		Window.Draw(Text); // replace with Text2 or Text3 to display them instead
		Window.Display();
	}

	return 0;
}

Still working on the theme…

I’ve received some feedback on the new theme, and on the whole, it seems people preferred the old one. And to be honest, I’m starting to think it’s better myself. It’s certainly nice to have the extensive feed options and the Twitter button to help you follow me on Twitter. But before I switch back, I have one more theme I’d like to try. It’s got a black background with white text, so it may be a bad idea. Let me know what you think!

Categories: Notice
Follow

Get every new post delivered to your Inbox.

Join 77 other followers