better fitting font atlas

This commit is contained in:
Kevin Trogant 2023-06-02 20:37:54 +02:00
parent f6d171a685
commit fb6d8fdc3a

View File

@ -6,8 +6,11 @@
#include "stb_image.h" #include "stb_image.h"
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h" #include "stb_truetype.h"
AssetManager* AssetManager::ptr = nullptr; AssetManager* AssetManager::ptr = nullptr;
constexpr int PADDING = 3;
bool AssetManager::loadTexture(const char* path, Texture* p_texture) bool AssetManager::loadTexture(const char* path, Texture* p_texture)
{ {
ZoneScoped; ZoneScoped;
@ -26,6 +29,26 @@ bool AssetManager::loadTexture(const char* path, Texture* p_texture)
return true; 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<size_t>((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) bool AssetManager::loadFontData(const char* path, float char_height, FontData* p_font)
{ {
ZoneScoped; 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<float>(-y0); font_data.baseline_adjust = font_data.scale_factor * static_cast<float>(-y0);
const int GLYPH_COUNT = (225 - 32) + 1; const int GLYPH_COUNT = (225 - 32) + 1;
font_data.bitmap_size = getBitmapSize(x0, y0, x1, y1, font_data.scale_factor, GLYPH_COUNT);
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;
unsigned char* bitmap_memory = (unsigned char*)malloc(font_data.bitmap_size * font_data.bitmap_size); unsigned char* bitmap_memory = (unsigned char*)malloc(font_data.bitmap_size * font_data.bitmap_size);
stbtt_pack_context context; 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_PackSetOversampling(&context, 1, 1);
stbtt_PackFontRange(&context, stbtt_PackFontRange(&context,
reinterpret_cast<const unsigned char*>(ttf_data.data), reinterpret_cast<const unsigned char*>(ttf_data.data),
@ -110,7 +128,7 @@ bool AssetManager::loadFontBitmap(const char* path, float char_height, Texture*
stbtt_packedchar char_data[226]; stbtt_packedchar char_data[226];
stbtt_pack_context context; 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_PackSetOversampling(&context, 1, 1);
stbtt_PackFontRange(&context, reinterpret_cast<const unsigned char*>(ttf_data.data), stbtt_PackFontRange(&context, reinterpret_cast<const unsigned char*>(ttf_data.data),
0, STBTT_POINT_SIZE(char_height), 32, 225, char_data); 0, STBTT_POINT_SIZE(char_height), 32, 225, char_data);