SDL

SDL and font handling

#include <stdio.h>

#include "SDL.h"
#include "SDL_ttf.h"

int main()
{
    SDL_Init(SDL_INIT_VIDEO);
    if(SDL_Init(SDL_INIT_VIDEO) != 0) {
        fprintf(stderr, "Could not init SDL: %s\n", SDL_GetError());
        return 1;
    }
    if(TTF_Init() != 0) {
        fprintf(stderr, "Couldn't init SDL_ttf: %s\n", TTF_GetError());
        return 1;
    }
    TTF_Font *font = TTF_OpenFont("DejaVuSans.ttf", 72);
    if(!font) {
        fprintf(stderr, "Couldn't load font\n");
        return 1;
    }
    SDL_Window *screen = SDL_CreateWindow("My application",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            640, 480,
            0);
    if(!screen) {
        fprintf(stderr, "Could not create window\n");
        return 1;
    }
    SDL_Renderer *renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE);
    if(!renderer) {
        fprintf(stderr, "Could not create renderer\n");
        return 1;
    }

    SDL_Color col_white;
    col_white.r = 255;
    col_white.g = 255;
    col_white.b = 255;
    col_white.a = 255;
    SDL_Surface *text = TTF_RenderUTF8_Blended(font, "Hello world", col_white);

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, text);
    SDL_FreeSurface(text);
    text = NULL;
    SDL_Rect dest;
    dest.x = 10;
    dest.y = 10;
    SDL_QueryTexture(texture, NULL, NULL, &dest.w, &dest.h);
    SDL_RenderCopy(renderer, texture, NULL, &dest);
    SDL_DestroyTexture(texture);
    texture = NULL;
    SDL_RenderPresent(renderer);
    SDL_Delay(3000);

    SDL_DestroyWindow(screen);
    TTF_CloseFont(font);
    font = NULL;
    TTF_Quit();
    SDL_Quit();
    return 0;
}

Refactoring

#include <stdio.h>
#include <string>
#include <stdexcept>

#include "SDL.h"
#include "SDL_ttf.h"

class SDL_Schedule {
	public:
		SDL_Schedule(const std::string& filename);
		~SDL_Schedule();
		void render();

	private:
		TTF_Font *font;
		SDL_Window *screen;
		SDL_Renderer *renderer;
		SDL_Color col_white;
		SDL_Rect dest;
};

SDL_Schedule::SDL_Schedule(const std::string& filename)
{
	SDL_Init(SDL_INIT_VIDEO);
	if(SDL_Init(SDL_INIT_VIDEO) != 0) {
		fprintf(stderr, "Could not init SDL: %s\n", SDL_GetError());
		throw std::runtime_error("error");
	}
	if(TTF_Init() != 0) {
		fprintf(stderr, "Couldn't init SDL_ttf: %s\n", TTF_GetError());
		throw std::runtime_error("error");
	}
	font = TTF_OpenFont("DejaVuSans.ttf", 72);
	if(!font) {
		fprintf(stderr, "Couldn't load font\n");
		throw std::runtime_error("error");
	}
	screen = SDL_CreateWindow("My application",
			SDL_WINDOWPOS_UNDEFINED,
			SDL_WINDOWPOS_UNDEFINED,
			640, 480,
			0);
	if(!screen) {
		fprintf(stderr, "Could not create window\n");
		throw std::runtime_error("error");
	}
	renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE);
	if(!renderer) {
		fprintf(stderr, "Could not create renderer\n");
		throw std::runtime_error("error");
	}

	col_white.r = 255;
	col_white.g = 255;
	col_white.b = 255;
	col_white.a = 255;
}

SDL_Schedule::~SDL_Schedule()
{
	SDL_DestroyWindow(screen);
	TTF_CloseFont(font);
	TTF_Quit();
	SDL_Quit();
}

void SDL_Schedule::render()
{
	SDL_Surface *text = TTF_RenderUTF8_Blended(font, "Hello world", col_white);
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer);
	SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, text);
	SDL_FreeSurface(text);
	text = NULL;
	SDL_Rect dest;
	dest.x = 10;
	dest.y = 10;
	SDL_QueryTexture(texture, NULL, NULL, &dest.w, &dest.h);
	SDL_RenderCopy(renderer, texture, NULL, &dest);
	SDL_DestroyTexture(texture);
	texture = NULL;
	SDL_RenderPresent(renderer);
}

int main(int argc, char** argv)
{
	if(argc != 2) {
		fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
		return 1;
	}
	SDL_Schedule sched(argv[1]);
	sched.render();
	SDL_Delay(3000);

	return 0;
}

Displaying the labels

#include <stdio.h>
#include <string>
#include <stdexcept>
#include <array>
#include <fstream>
#include <sstream>
#include <vector>

#include "SDL.h"
#include "SDL_ttf.h"

const int width  = 640;
const int height = 480;
const int num_labels = 23;

class SDL_Schedule {
    public:
        SDL_Schedule(const std::string& filename);
        ~SDL_Schedule();
        void render();

    private:
        TTF_Font *font;
        SDL_Window *screen;
        SDL_Renderer *renderer;
        SDL_Color col_white;
        SDL_Color col_yellow;
        SDL_Rect dest;
        std::string file;
        std::array<SDL_Rect, num_labels> rects;
};

SDL_Schedule::SDL_Schedule(const std::string& filename)
    : file(filename)
{
    SDL_Init(SDL_INIT_VIDEO);
    if(SDL_Init(SDL_INIT_VIDEO) != 0) {
        fprintf(stderr, "Could not init SDL: %s\n", SDL_GetError());
        throw std::runtime_error("error");
    }
    if(TTF_Init() != 0) {
        fprintf(stderr, "Couldn't init SDL_ttf: %s\n", TTF_GetError());
        throw std::runtime_error("error");
    }
    font = TTF_OpenFont("DejaVuSans.ttf", 36);
    if(!font) {
        fprintf(stderr, "Couldn't load font\n");
        throw std::runtime_error("error");
    }
    screen = SDL_CreateWindow("My application",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            width, height,
            0);
    if(!screen) {
        fprintf(stderr, "Could not create window\n");
        throw std::runtime_error("error");
    }
    renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE);
    if(!renderer) {
        fprintf(stderr, "Could not create renderer\n");
        throw std::runtime_error("error");
    }

    col_white.r = 255;
    col_white.g = 255;
    col_white.b = 255;
    col_white.a = 255;

    col_yellow.r = 255;
    col_yellow.g = 255;
    col_yellow.b = 0;
    col_yellow.a = 255;

    rects[0].x = 10;
    rects[0].y = 10;
    rects[1].y = 10;
    for(int i = 0; i < (num_labels - 2) / 3; i++) {
        rects[i * 3 + 2].x = 10;
        rects[i * 3 + 2].y = 80 + 55 * i;
        rects[i * 3 + 3].x = 100;
        rects[i * 3 + 3].y = 80 + 55 * i;
        rects[i * 3 + 4].y = 80 + 55 * i;
    }

}

SDL_Schedule::~SDL_Schedule()
{
    SDL_DestroyWindow(screen);
    TTF_CloseFont(font);
    TTF_Quit();
    SDL_Quit();
}

void SDL_Schedule::render()
{
    std::ifstream ifs(file);
    std::string contents((std::istreambuf_iterator<char>(ifs)),
            (std::istreambuf_iterator<char>()));
    std::stringstream ss(contents);
    std::string to;
    std::vector<std::string> res;
    while(std::getline(ss, to, '\n')) {
        res.push_back(to);
    }
    if(res.size() != num_labels) {
        throw std::runtime_error("Invalid number of labels\n");
    }

    SDL_RenderClear(renderer);
    for(int i = 0; i < num_labels; i++) {
        auto col = i < 2 ? col_yellow : col_white;
        SDL_Surface *text = TTF_RenderUTF8_Blended(font, res[i].c_str(), col);
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, text);
        SDL_FreeSurface(text);
        text = NULL;
        SDL_QueryTexture(texture, NULL, NULL, &rects[i].w, &rects[i].h);
        if(i % 3 == 1) {
            rects[i].x = width - rects[i].w - 10;
        }
        SDL_RenderCopy(renderer, texture, NULL, &rects[i]);
        SDL_DestroyTexture(texture);
        texture = NULL;
    }
    SDL_RenderPresent(renderer);
}

int main(int argc, char** argv)
{
    if(argc != 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return 1;
    }
    SDL_Schedule sched(argv[1]);
    sched.render();
    SDL_Delay(3000);

    return 0;
}