SDL 2.0 Lesson Cycle: Lesson 6 - Downloading Fonts with SDL_ttf

image

From a translator:

This is a continuation of a series of translations of Twinklebear tutorials, available in the original here . The translation is partly free and may contain minor amendments or additions from the translator. Translation of the first two lessons - authorshipInvalidPointerand the third and fourth for k1-801.


List of lessons:


Downloading fonts using SDL_ttf


In this tutorial, we will learn how to display True Type font fonts using the SDL_ttf extension library. Installing the library is identical to installing SDL_image in Lesson 3 , but instead of “image” we simply write “ttf” (Windows users should also copy the included freetype dll). So download SDL_ttf , take a look at the documentation and start the tutorial!

The first thing we need to work with SDL_ttf is the ttf font. Using BitFontMaker , the author made a rather awful font that you can download from the repositorybut if you already have your own beautiful font, you can use it. This font provides only simple ASCII characters, so if you try to display non-ASCII characters, you most likely will not succeed. The code for this lesson will be written based on lesson 5, as usual you can download it from Github . Images, sliced ​​sprites and drawings will be changed in this tutorial.

Display text


SDL_ttf provides several ways to display fonts of various speed and quality, as well as the ability to display UTF8 and Unicode characters. The documentation provides a good overview of the various display methods, so you should read and learn more about them, when and which method you want to use depending on your quality and speed requirements. In this tutorial we will use TTF_RenderText_Blended, as we have no time limits and want our text to be beautiful. Various text display functions accept RGB SDL_Color color , which we can use to select the color of the text to be drawn.

Unfortunately, SDL_ttf can only display on the surface, so you have to take an extra step after rendering the text to create a texture from it that we can draw using the renderer. Of course, you will still need to download the font, which we will use, which is done using TTF_OpenFont , where you can also specify the desired font size.

Writing a renderText Function


To make our life easier, we’ll create a renderText function that will receive text, a file containing the TTF font, color, desired size and renderer to load the final texture. The function opens the font, displays the text, converts it to a texture and returns the texture. Since problems can arise, you need to check each library call for errors and correctly handle them, for example, clean resources, log errors and return nullptr so that we know that something bad has happened. SDL_ttf reports all its errors through SDL_GetError, so you can continue to use logSDLError to log errors.

Keeping these requirements in mind, let's write the renderText function:

/**
*      
* @param message ,   
* @param fontFile ,   
* @param color ,     
* @param fontSize  
* @param renderer ,     
* @return SDL_Texture,     nullptr,  -   
*/
SDL_Texture* renderText(const std::string &message, const std::string &fontFile,
        SDL_Color color, int fontSize, SDL_Renderer *renderer)
{
        // 
        TTF_Font *font = TTF_OpenFont(fontFile.c_str(), fontSize);
        if (font == nullptr){
                logSDLError(std::cout, "TTF_OpenFont");
                return nullptr;
        }       
        //       TTF_RenderText,
        //    
        SDL_Surface *surf = TTF_RenderText_Blended(font, message.c_str(), color);
        if (surf == nullptr){
                TTF_CloseFont(font);
                logSDLError(std::cout, "TTF_RenderText");
                return nullptr;
        }
        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
        if (texture == nullptr){
                logSDLError(std::cout, "CreateTexture");
        }
        //   
        SDL_FreeSurface(surf);
        TTF_CloseFont(font);
        return texture;
}

Performance warning


It is very important to note that every time we want to display text, we reopen and close the font, which is suitable in our case, since we display the text once, but if we want to display a lot of text and / or too often, then it’s best to keep font open as much as we need. Our version of renderText for this more frequent case will accept TTF_Font * instead of the name of the font file and will not open and close, since the life of the font file will be adjusted separately.

Initialize SDL_ttf


As with SDL, we need to initialize the library before using it. This is done using TTF_Init , which will return 0 if successful. To initialize SDL_ttf, we only call this function after initializing the SDL and check the return value to make sure everything is fine.

if (TTF_Init() != 0){
        logSDLError(std::cout, "TTF_Init");
        SDL_Quit();
        return 1;
}

Using renderText


With our convenient renderText function, we can display text in one simple call. For this tutorial, display the text “TTF fonts are cool!” white, size 64 in the font that we downloaded before. Then we can request the width and height in the same way as for any other texture, and calculate the x / y coordinates to draw a message in the center of the window.

const std::string resPath = getResourcePath("Lesson6");
//   "TTF fonts are cool!"
//   RGBA
SDL_Color color = { 255, 255, 255, 255 };
SDL_Texture *image = renderText("TTF fonts are cool!", resPath + "sample.ttf",
        color, 64, renderer);
if (image == nullptr){
        cleanup(renderer, window);
        TTF_Quit();
        SDL_Quit();
        return 1;
}
//    ,     
int iW, iH;
SDL_QueryTexture(image, NULL, NULL, &iW, &iH);
int x = SCREEN_WIDTH / 2 - iW / 2;
int y = SCREEN_HEIGHT / 2 - iH / 2;

Draw the text


In the end, we can draw the texture, as we did before using the renderTexture function.

//:     
SDL_RenderClear(renderer);
//    ,     ,  
//    
renderTexture(image, renderer, x, y);
SDL_RenderPresent(renderer);

If everything went according to plan, you will see something like this:

image

End of lesson 6


This is all you need to know to start using SDL_ttf! Be sure to check out the documentation to see what this library is capable of. As usual, if you have problems with the lesson, you can write in the comments.

The author became busy with other projects and could not write lessons anymore, so this was the last lesson from the cycle. You can watch Lazy Foo's tutorials or read examples and documentation from the SDL wiki .

All Articles