From fb6d8fdc3a95b316f890045d33956d7feae8bb36 Mon Sep 17 00:00:00 2001 From: Kevin Trogant Date: Fri, 2 Jun 2023 20:37:54 +0200 Subject: [PATCH] better fitting font atlas --- app/src/main/cpp/AssetManager.cpp | 34 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/app/src/main/cpp/AssetManager.cpp b/app/src/main/cpp/AssetManager.cpp index ee7a04e..0f4af65 100644 --- a/app/src/main/cpp/AssetManager.cpp +++ b/app/src/main/cpp/AssetManager.cpp @@ -6,8 +6,11 @@ #include "stb_image.h" #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" + AssetManager* AssetManager::ptr = nullptr; +constexpr int PADDING = 3; + bool AssetManager::loadTexture(const char* path, Texture* p_texture) { ZoneScoped; @@ -26,6 +29,26 @@ bool AssetManager::loadTexture(const char* path, Texture* p_texture) return true; } +/* Calculate required bitmap size for a given font bounding box, scale factor and glyph count */ +static size_t getBitmapSize(int x0, int y0, int x1, int y1, float scale_factor, int glyph_count) +{ + + float w = scale_factor * (x1 - x0); + float h = scale_factor * (y1 - y0); + float glyph_size = ceilf((w > h) ? w : h); + float glyphs_per_row = ceilf(sqrtf((float)glyph_count)); + + size_t size = static_cast((glyph_size + PADDING) * glyphs_per_row); + + /* Round up to nearest power of two, iff it's smaller than 4096 */ + for (size_t bit = 0; bit < 12 /* => 4096 */; ++bit) { + if ((1uLL << bit) >= size) { + return 1uLL << bit; + } + } + return size; +} + bool AssetManager::loadFontData(const char* path, float char_height, FontData* p_font) { ZoneScoped; @@ -60,17 +83,12 @@ bool AssetManager::loadFontData(const char* path, float char_height, FontData* p font_data.baseline_adjust = font_data.scale_factor * static_cast(-y0); const int GLYPH_COUNT = (225 - 32) + 1; - - float w = font_data.scale_factor * (x1 - x0); - float h = font_data.scale_factor * (y1 - y0); - size_t size = (int)ceilf((w > h) ? w : h); - size *= GLYPH_COUNT; - font_data.bitmap_size = size; + font_data.bitmap_size = getBitmapSize(x0, y0, x1, y1, font_data.scale_factor, GLYPH_COUNT); unsigned char* bitmap_memory = (unsigned char*)malloc(font_data.bitmap_size * font_data.bitmap_size); stbtt_pack_context context; - stbtt_PackBegin(&context, bitmap_memory, font_data.bitmap_size, font_data.bitmap_size, 0, 1, nullptr); + stbtt_PackBegin(&context, bitmap_memory, font_data.bitmap_size, font_data.bitmap_size, 0, PADDING, nullptr); stbtt_PackSetOversampling(&context, 1, 1); stbtt_PackFontRange(&context, reinterpret_cast(ttf_data.data), @@ -110,7 +128,7 @@ bool AssetManager::loadFontBitmap(const char* path, float char_height, Texture* stbtt_packedchar char_data[226]; stbtt_pack_context context; - stbtt_PackBegin(&context, bitmap_memory, font_data.bitmap_size, font_data.bitmap_size, 0, 1, nullptr); + stbtt_PackBegin(&context, bitmap_memory, font_data.bitmap_size, font_data.bitmap_size, 0, PADDING, nullptr); stbtt_PackSetOversampling(&context, 1, 1); stbtt_PackFontRange(&context, reinterpret_cast(ttf_data.data), 0, STBTT_POINT_SIZE(char_height), 32, 225, char_data);