Try to calculate required font atlas bitmap size

Currently results in HUGE textures
This commit is contained in:
Kevin Trogant 2023-06-02 11:14:34 +02:00
parent f81ea0eba8
commit f6d171a685
4 changed files with 56 additions and 33 deletions

View File

@ -37,25 +37,9 @@ bool AssetManager::loadFontData(const char* path, float char_height, FontData* p
FileBuffer ttf_data = {};
if (!loadFile(path, &ttf_data))
return false;
static unsigned char bitmap_memory[STBTT_PH_VALUE * STBTT_PH_VALUE];
FontData font_data = {};
auto* data = reinterpret_cast<const unsigned char*>(ttf_data.data);
/*stbtt_BakeFontBitmap(data,
0,
char_height,
bitmap_memory,
STBTT_PH_VALUE,
STBTT_PH_VALUE,
32,
225, // latin-1 printable characters range
font_data.char_data);*/
stbtt_pack_context context;
stbtt_PackBegin(&context, bitmap_memory, STBTT_PH_VALUE, STBTT_PH_VALUE, 0, 1, nullptr);
stbtt_PackSetOversampling(&context, 1, 1);
stbtt_PackFontRange(&context, data, 0, STBTT_POINT_SIZE(char_height), 32, 225, font_data.char_data);
stbtt_PackFontRange(&context, data, 0, STBTT_POINT_SIZE(char_height), 8364, 1, font_data.char_data + 225);
stbtt_PackEnd(&context);
font_data.char_height = char_height;
int off = stbtt_GetFontOffsetForIndex(data, 0);
@ -63,6 +47,7 @@ bool AssetManager::loadFontData(const char* path, float char_height, FontData* p
releaseFileBuffer(ttf_data);
return false;
}
stbtt_fontinfo info;
if (!stbtt_InitFont(&info, data, off)) {
releaseFileBuffer(ttf_data);
@ -73,6 +58,37 @@ bool AssetManager::loadFontData(const char* path, float char_height, FontData* p
int x0, y0, x1, y1;
stbtt_GetFontBoundingBox(&info, &x0, &y0, &x1, &y1);
font_data.baseline_adjust = font_data.scale_factor * static_cast<float>(-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;
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_PackSetOversampling(&context, 1, 1);
stbtt_PackFontRange(&context,
reinterpret_cast<const unsigned char*>(ttf_data.data),
0,
STBTT_POINT_SIZE(char_height),
32,
225,
font_data.char_data);
stbtt_PackFontRange(&context,
reinterpret_cast<const unsigned char*>(ttf_data.data),
0,
STBTT_POINT_SIZE(char_height),
8364,
1,
font_data.char_data + 225);
stbtt_PackEnd(&context);
free(bitmap_memory);
*p_font = font_data;
releaseFileBuffer(ttf_data);
m_font_cache[lookup_pair] = font_data;
@ -81,29 +97,30 @@ bool AssetManager::loadFontData(const char* path, float char_height, FontData* p
bool AssetManager::loadFontBitmap(const char* path, float char_height, Texture* p_texture)
{
ZoneScoped;
FontData font_data;
if (!loadFontData(path, char_height, &font_data))
return false;
FileBuffer ttf_data = {};
if (!loadFile(path, &ttf_data))
return false;
static unsigned char bitmap_memory[STBTT_PH_VALUE * STBTT_PH_VALUE];
unsigned char* bitmap_memory = (unsigned char *)malloc(font_data.bitmap_size * font_data.bitmap_size);
stbtt_packedchar char_data[226];
/*stbtt_BakeFontBitmap(reinterpret_cast<const unsigned char*>(ttf_data.data),
0,
char_height,
bitmap_memory,
STBTT_PH_VALUE,
STBTT_PH_VALUE,
32,
225, // latin-1 printable characters range
char_data);*/
stbtt_pack_context context;
stbtt_PackBegin(&context, bitmap_memory, STBTT_PH_VALUE, STBTT_PH_VALUE, 0, 1, nullptr);
stbtt_PackBegin(&context, bitmap_memory, font_data.bitmap_size, font_data.bitmap_size, 0, 1, nullptr);
stbtt_PackSetOversampling(&context, 1, 1);
stbtt_PackFontRange(&context, reinterpret_cast<const unsigned char*>(ttf_data.data),
0, STBTT_POINT_SIZE(char_height), 32, 225, char_data);
stbtt_PackFontRange(&context, reinterpret_cast<const unsigned char*>(ttf_data.data),
0, STBTT_POINT_SIZE(char_height), 8364, 1, char_data + 225);
stbtt_PackEnd(&context);
*p_texture = Texture(STBTT_PH_VALUE, STBTT_PH_VALUE, bitmap_memory, GL_R8);
*p_texture = Texture(font_data.bitmap_size, font_data.bitmap_size, bitmap_memory, GL_R8);
releaseFileBuffer(ttf_data);
free(bitmap_memory);
return true;
}

View File

@ -8,6 +8,8 @@
#include "Renderer.h"
#include "Font.h"
#include <map>
// Predefine, because that saves us from including android headers here
struct AAssetManager;
@ -61,8 +63,10 @@ protected:
virtual ~AssetManager() = default;
AssetManager(const AssetManager&) = delete;
AssetManager& operator=(const AssetManager&) = delete;
private:
// FIXME(Kevin): Temporary workaround
std::map<std::pair<StringHandle, float>, FontData> m_font_cache;
};
const int STBTT_PH_VALUE = 1024;
#endif

View File

@ -20,6 +20,7 @@ struct FontData
int descent;
int line_gap;
float baseline_adjust;
size_t bitmap_size;
};
#endif

View File

@ -97,7 +97,7 @@ int main()
StringHandle smiley = StringRepository::global->internString("smiley_PNG42.png");
StringHandle ttf = StringRepository::global->internString("Milky Honey.ttf");
FontData fd;
AssetManager::ptr->loadFontData("Milky Honey.ttf", 24.f, &fd);
AssetManager::ptr->loadFontData("Milky Honey.ttf", 128.f, &fd);
// ENDE BEISPIELCODE
glfwSwapInterval(1);
@ -192,12 +192,13 @@ int main()
while (*text) {
if (*text >= 32 && *text < 128) {
stbtt_aligned_quad q;
stbtt_GetBakedQuad(fd.char_data, 1024, 1024, *text - 32, &tx, &ty, &q, 1);
stbtt_GetPackedQuad(fd.char_data, fd.bitmap_size, fd.bitmap_size, *text - 32, &tx, &ty, &q, 1);
float w = q.x1 - q.x0, h = q.y1 - q.y0;
Renderer::ptr->addFontRect(q.x0,
q.y0,
w,
h,
1.f, 0.f, 0.f, 1.f,
fd.char_height,
ttf,
StringRepository::global->internString("1"),