From 790249cc59bdf646ee38a081ebe392c33ae5b732 Mon Sep 17 00:00:00 2001 From: Menase Teshale Date: Mon, 24 Aug 2026 10:53:14 +0300 Subject: Started working on fonts --- src/font.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/font.c (limited to 'src/font.c') diff --git a/src/font.c b/src/font.c new file mode 100644 index 0000000..999c3da --- /dev/null +++ b/src/font.c @@ -0,0 +1,178 @@ +#include "font.h" +#include +#include +#include +#include + +#define FILE_NAME_SIZE 300 + +void free_sprite_font(sprite_font* font) { + free(font->characters); + SDL_DestroyTexture(font->spritesheet); + + memset(font, 0, sizeof(sprite_font)); +} + +int get_string_parameter(const char* line, const char* parameter, const char** start) { + *start = strstr(line, parameter); + if ((*start) == NULL) + return -1; + + *start += strlen(parameter); + if ((*start)[0] != '\"') { + return -1; + } + + int length = 0; + while ((*start)[length+1] != '\0' && (*start)[length+1] != '\"') length++; + + (*start)++; + return length; +} + +char parse_character_tag(const char* character_tag) { + if (strncmp(character_tag, "space", 5) == 0) + return ' '; + + return character_tag[0]; +} + +bool get_int_parameter(const char* line, const char* parameter, int* value) { + const char* start = strstr(line, parameter); + if (start == NULL) { + return false; + } + start += strlen(parameter); + + int c = 0; + bool negative = false; + + if (start[0] == '-') { + negative = true; + start++; + } + + for(int i = 0; start[i] >= '0' && start[i] <= '9'; i++) { + c *= 10; c += start[i] - '0'; + } + + *value = negative ? -c : c; + return true; +} + +bool load_sprite_font(const char* filename, sprite_font* font) { + if (font->characters || font->spritesheet) { + SDL_Log("Trying to reallocate font causing memory leak, exitting!"); + exit(EXIT_FAILURE); + } + + FILE* f = fopen(filename, "r"); + if (f == NULL) { + SDL_Log("Failed to open sprite font file %s, error: %s, exitting!", + filename, + strerror(errno) + ); + exit(EXIT_FAILURE); + } + + char line[PARSER_LINE_SIZE]; + if (fgets(line, sizeof(line), f) == NULL || + strncmp(line, "info", 4) != 0) { + SDL_Log("File %s is not a valid font file, exitting!", + filename); + fclose(f); + exit(EXIT_FAILURE); + } + + char font_name[FONT_NAME_SIZE]; + const char* font_name_start; + int font_name_length = + SDL_min(get_string_parameter(line, "face=", &font_name_start), + FONT_NAME_SIZE-1 + ); + + strncpy(font_name, font_name_start, font_name_length); + font_name[font_name_length] = '\0'; + + int char_size = 0, char_count = 0; + font_char* characters_unarranged = NULL; + + while (fgets(line, PARSER_LINE_SIZE, f) != NULL) { + + if (strncmp(line, "chars", 5) == 0) { + int total_char_count; + + if(!get_int_parameter(line, "count=", &total_char_count)) + continue; + + char_size = total_char_count; + characters_unarranged = + realloc(characters_unarranged, char_size * sizeof(font_char)); + + if (characters_unarranged == NULL) { + SDL_Log("Failed to allocate space while loading font %s, error %s, exitting!", + filename, + strerror(errno)); + exit(EXIT_FAILURE); + } + } + + else if (strncmp(line, "char", 4) == 0) { + font_char new_font_char; + + int val; + + if (!get_int_parameter(line, "x=", &val)) + continue; + new_font_char.x = val; + + if (!get_int_parameter(line, "y=", &val)) + continue; + new_font_char.y = val; + + if (!get_int_parameter(line, "width=", &val)) + continue; + new_font_char.width = val; + + if (!get_int_parameter(line, "height=", &val)) + continue; + new_font_char.height = val; + + if (!get_int_parameter(line, "xoffset=", &val)) + continue; + new_font_char.x_offset = val; + + if (!get_int_parameter(line, "yoffset=", &val)) + continue; + new_font_char.y_offset = val; + + if (!get_int_parameter(line, "xadvance=", &val)) + continue; + new_font_char.x_advance = val; + + const char* character_tag; + if (get_string_parameter(line, "letter=", &character_tag) <= 0) + continue; + new_font_char.character = parse_character_tag(character_tag); + + if (char_count >= char_size) { + char_size = char_count+1; + characters_unarranged = + realloc(characters_unarranged, char_size * sizeof(font_char)); + } + + if (characters_unarranged == NULL) { + SDL_Log("Failed to allocate space while loading font %s, error %s, exitting!", + filename, + strerror(errno)); + exit(EXIT_FAILURE); + } + + characters_unarranged[char_count] = new_font_char; + char_count++; + } + } + + fclose(f); + return true; +} -- cgit v1.2.3