Archive
Video Modes and Windowing: Videos up at last
I have finally recorded and released the videos to go alongside the Video Modes and Windowing tutorial. They are now embedded in that post, and also in this one, so you can find them easily. Enjoy!
SFML Graphics – Fonts and Text
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)
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;
}
Video Modes and Windowing
Hello, and welcome. Today we’re going to discuss windowing and video modes in more detail. That is, we shall see how we can manipulate windows, and control their attributes. Also, of course, we discuss video modes, and how we can best use them.
