summaryrefslogtreecommitdiff
path: root/src/font.c
diff options
context:
space:
mode:
authorMenase Teshale <osome3717@gmail.com>2026-08-24 10:53:14 +0300
committerMenase Teshale <osome3717@gmail.com>2026-08-24 10:53:14 +0300
commit790249cc59bdf646ee38a081ebe392c33ae5b732 (patch)
tree45ca1026b88e4d0dc7709d041cb15455ccea508d /src/font.c
parent15b194df64db5850757d195344e682bb8ec4c138 (diff)
Started working on fonts
Diffstat (limited to 'src/font.c')
-rw-r--r--src/font.c178
1 files changed, 178 insertions, 0 deletions
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 <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#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;
+}