Compartementalised text rendering of score struct

This commit is contained in:
Pradana AUMARS 2021-06-29 16:20:40 +02:00
parent 2ebcf624de
commit f893c57598
5 changed files with 104 additions and 68 deletions

View File

@ -9,6 +9,8 @@ pong_SOURCES = \
racket.c \
racket.h \
score.c \
score.h
score.h \
text.c \
text.h
pong_CFLAGS = $(SDL_CFLAGS) `pkg-config --cflags SDL2_ttf fontconfig`
pong_LDFLAGS = $(SDL_LIBS) `pkg-config --libs SDL2_ttf fontconfig` -lm

View File

@ -1,84 +1,24 @@
#include <fontconfig/fontconfig.h>
#include "score.h"
static const FcChar8 *SCORE_FONT_FAMILY = "Liberation Mono";
static const FcChar8 *SCORE_FONT_STYLE = "Bold";
static TTF_Font *SCORE_FONT = NULL;
static FcChar8 *SCORE_FONT_FILE = NULL;
static const int SCORE_FONT_PTSIZE = 16;
static const SDL_Color SCORE_FONT_COLOR = { 255, 255, 255 };
Score*
Score_init(int posX, int posY) {
Score *s = malloc(sizeof(Score));
*(int *)&s->POSX = posX;
*(int *)&s->POSY = posY;
s->score = 0;
if (SCORE_FONT == NULL) {
FcConfig *config = FcInitLoadConfigAndFonts();
FcPattern *pat = FcPatternCreate();
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *) 0);
FcFontSet* fs = FcFontList(config, pat, os);
FcChar8 *style, *family;
for (int i=0; fs && i < fs->nfont; ++i) {
FcPattern* font = fs->fonts[i];
if (FcPatternGetString(font, FC_FILE, 0, &SCORE_FONT_FILE) == FcResultMatch
&& FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch
&& FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch
&& strcmp(SCORE_FONT_FAMILY, family) == 0
&& strcmp(SCORE_FONT_STYLE, style) == 0) {
break;
}
}
SCORE_FONT = TTF_OpenFont(SCORE_FONT_FILE, SCORE_FONT_PTSIZE);
FcFontSetDestroy(fs);
FcObjectSetDestroy(os);
FcPatternDestroy(pat);
FcConfigDestroy(config);
if (SCORE_FONT == NULL) {
printf("TTF_OpenFont fail with path '%s'. TTF_Error: %s\n", SCORE_FONT_FILE, TTF_GetError());
free(s);
return NULL;
}
}
s->text = Text_init(posX, posY, SCORE_FONT_STYLE, SCORE_FONT_PTSIZE);
return s;
}
void
Score_free(Score *s) {
if (SCORE_FONT != NULL) {
TTF_CloseFont(SCORE_FONT);
SCORE_FONT = NULL;
}
Text_free(s->text);
free(s);
}
int
Score_render(const Score *s, SDL_Renderer *renderer) {
char score_str[3];
SDL_Rect scoreRect = { s->POSX , s->POSY, SCORE_WIDTH, SCORE_HEIGHT };
sprintf(score_str, "%i", s->score);
SDL_Surface *scoreSurface = TTF_RenderText_Solid(SCORE_FONT, score_str, SCORE_FONT_COLOR);
if (scoreSurface == NULL) {
printf("Text rendering failed. TTF_Error: %s\n", TTF_GetError());
return 1;
}
SDL_Texture *scoreTexture = SDL_CreateTextureFromSurface(renderer, scoreSurface);
if (scoreTexture == NULL) {
printf("Texture rendering failed. SDL_Error: %s\n", SDL_GetError());
SDL_FreeSurface(scoreSurface);
return 1;
}
SDL_RenderCopy(renderer, scoreTexture, NULL, &scoreRect);
SDL_FreeSurface(scoreSurface);
SDL_DestroyTexture(scoreTexture);
Text_render(s->text, renderer, score_str, SCORE_WIDTH, SCORE_HEIGHT);
return 0;
}

View File

@ -1,16 +1,16 @@
#ifndef SCORE_H
#define SCORE_H
#include <SDL.h>
#include <SDL_ttf.h>
#include "text.h"
static const int SCORE_WIDTH = 50;
static const int SCORE_HEIGHT = 50;
static const FcChar8 *SCORE_FONT_STYLE = "Bold";
static const int SCORE_FONT_PTSIZE = 16;
typedef struct Score {
const int POSX;
const int POSY;
int score;
Text *text;
} Score;
Score* Score_init(int posX, int posY);

72
src/text.c Normal file
View File

@ -0,0 +1,72 @@
#include "text.h"
Text*
Text_init(int posX, int posY, const FcChar8 *TEXT_FONT_STYLE, int TEXT_FONT_PTSIZE) {
Text *t = malloc(sizeof(Text));
*(int *)&t->POSX = posX;
*(int *)&t->POSY = posY;
if (TEXT_FONT == NULL) {
FcConfig *config = FcInitLoadConfigAndFonts();
FcPattern *pat = FcPatternCreate();
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *) 0);
FcFontSet* fs = FcFontList(config, pat, os);
FcChar8 *style, *family;
for (int i=0; fs && i < fs->nfont; ++i) {
FcPattern* font = fs->fonts[i];
if (FcPatternGetString(font, FC_FILE, 0, &TEXT_FONT_FILE) == FcResultMatch
&& FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch
&& FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch
&& strcmp(TEXT_FONT_FAMILY, family) == 0
&& strcmp(TEXT_FONT_STYLE, style) == 0) {
break;
}
}
TEXT_FONT = TTF_OpenFont(TEXT_FONT_FILE, TEXT_FONT_PTSIZE);
FcFontSetDestroy(fs);
FcObjectSetDestroy(os);
FcPatternDestroy(pat);
FcConfigDestroy(config);
if (TEXT_FONT == NULL) {
printf("TTF_OpenFont fail with path '%s'. TTF_Error: %s\n", TEXT_FONT_FILE, TTF_GetError());
free(t);
return NULL;
}
}
return t;
}
void
Text_free(Text *t) {
if (TEXT_FONT != NULL) {
TTF_CloseFont(TEXT_FONT);
TEXT_FONT = NULL;
}
free(t);
}
int
Text_render(const Text* text, SDL_Renderer *renderer, const char *str, int width, int height) {
SDL_Rect textRect = { text->POSX , text->POSY, width, height };
SDL_Surface *textSurface = TTF_RenderText_Solid(TEXT_FONT, str, TEXT_FONT_COLOR);
if (textSurface == NULL) {
printf("Text rendering failed. TTF_Error: %s\n", TTF_GetError());
return 1;
}
SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
if (textTexture == NULL) {
printf("Texture rendering failed. SDL_Error: %s\n", SDL_GetError());
SDL_FreeSurface(textSurface);
return 1;
}
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
SDL_FreeSurface(textSurface);
SDL_DestroyTexture(textTexture);
return 0;
}

22
src/text.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TEXT_H
#define TEXT_H
#include <SDL.h>
#include <SDL_ttf.h>
#include <fontconfig/fontconfig.h>
static const FcChar8 *TEXT_FONT_FAMILY = "Liberation Mono";
static TTF_Font *TEXT_FONT = NULL;
static FcChar8 *TEXT_FONT_FILE = NULL;
static const SDL_Color TEXT_FONT_COLOR = { 255, 255, 255 };
typedef struct Text {
const int POSX;
const int POSY;
} Text;
Text* Text_init(int posX, int posY, const FcChar8 *font_style, int font_ptsize);
void Text_free(Text* text);
int Text_render(const Text* text, SDL_Renderer *renderer, const char *str, int width, int height);
#endif