From 4a967356128c49ad615d786c65a8c0cc672aca7b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 16 Oct 2021 21:02:15 +0200 Subject: Create font atlas with optimal size --- src/graphics/font.c | 55 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/graphics/font.c b/src/graphics/font.c index 9a1d637..20d9dfa 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -34,17 +34,6 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int f return -1; } - /* TODO: Optimize */ - self->font_atlas.width = 1024; - self->font_atlas.height = 1024; - self->font_atlas.atlas = malloc(self->font_atlas.width * self->font_atlas.height); - if(!self->font_atlas.atlas) { - fprintf(stderr, "Error: failed to load font %s, error: out of memory\n", filepath); - mgl_filedata_free(&filedata); - mgl_font_unload(self); - return -1; - } - self->num_packed_chars = 256; self->packed_chars = malloc(self->num_packed_chars * sizeof(stbtt_packedchar)); if(!self->packed_chars) { @@ -54,25 +43,47 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int f return -1; } - stbtt_pack_context pc; + bool atlas_created = false; + /* TODO: Optimize */ + /* Find optimal size for atlas, starting from small to large */ + for(int i = 0; i < 4; ++i) { + self->font_atlas.width = (8 + (8 * i)) * self->size; + self->font_atlas.height = (8 + (8 * i)) * self->size; + unsigned char *new_atlas = realloc(self->font_atlas.atlas, self->font_atlas.width * self->font_atlas.height); + if(!new_atlas) { + fprintf(stderr, "Error: failed to load font %s, error: out of memory\n", filepath); + mgl_filedata_free(&filedata); + mgl_font_unload(self); + return -1; + } + self->font_atlas.atlas = new_atlas; + + stbtt_pack_context pc; + + if(!stbtt_PackBegin(&pc, self->font_atlas.atlas, self->font_atlas.width, self->font_atlas.height, self->font_atlas.width, 1, NULL)) { + fprintf(stderr, "Error: failed to load font %s, error: stbtt_PackBegin failed\n", filepath); + mgl_filedata_free(&filedata); + mgl_font_unload(self); + return -1; + } + + if(!stbtt_PackFontRange(&pc, filedata.data, 0, self->size, 0, self->num_packed_chars, self->packed_chars)) { + stbtt_PackEnd(&pc); + continue; + } - if(!stbtt_PackBegin(&pc, self->font_atlas.atlas, self->font_atlas.width, self->font_atlas.height, self->font_atlas.width, 1, NULL)) { - fprintf(stderr, "Error: failed to load font %s, error: stbtt_PackBegin failed\n", filepath); - mgl_filedata_free(&filedata); - mgl_font_unload(self); - return -1; + stbtt_PackEnd(&pc); + atlas_created = true; + break; } - if(!stbtt_PackFontRange(&pc, filedata.data, 0, self->size, 0, self->num_packed_chars, self->packed_chars)) { - fprintf(stderr, "Error: failed to load font %s, error: stbtt_PackFontRange failed\n", filepath); + if(!atlas_created) { + fprintf(stderr, "Error: failed to load font %s, error: failed to create atlas\n", filepath); mgl_filedata_free(&filedata); mgl_font_unload(self); - stbtt_PackEnd(&pc); return -1; } - stbtt_PackEnd(&pc); - if(mgl_texture_load_from_memory(&self->texture, self->font_atlas.atlas, self->font_atlas.width, self->font_atlas.height, MGL_TEXTURE_ALPHA, NULL) != 0) { fprintf(stderr, "Error: failed to load font %s, error: mgl_texture_load_from_memory failed\n", filepath); mgl_filedata_free(&filedata); -- cgit v1.2.3