#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; }