diff --git a/src/AssetManager.c b/src/AssetManager.c index 17783f2..5c0eaac 100644 --- a/src/AssetManager.c +++ b/src/AssetManager.c @@ -972,6 +972,82 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena, return 0; } +INTERNAL FontPack *getMatchingFontPack(AssetManager *assetManager, + const char *const name) +{ + FontPack *result = NULL; + for (i32 i = 0; i < ARRAY_COUNT(assetManager->fontPack); i++) + { + FontPack *checkFontPack = &assetManager->fontPack[i]; + if (common_strcmp(checkFontPack->name, name) == 0) + { + result = checkFontPack; + break; + } + } + + return result; +} + +Font *asset_getFontCreateSizeOnDemand(AssetManager *assetManager, + MemoryArena_ *persistentArena, + MemoryArena_ *transientArena, char *name, + i32 size) +{ + + Font *result = asset_getFont(assetManager, name, size); + + if (result == NULL) + { + FontPack *pack = getMatchingFontPack(assetManager, name); + if (pack != NULL) + { + for(i32 i = 0; i < pack->fontIndex; i++) + { + Font *checkFont = &pack->font[i]; + if (checkFont->size == size) + { + result = checkFont; + break; + } + } + + if (result == NULL) + { + asset_loadTTFont(assetManager, persistentArena, transientArena, + pack->filePath, name, size); + + result = asset_getFont(assetManager, name, size); + } + } + else + { + // TODO(doyle): Logging + } + } + + return result; +} + +Font *asset_getFont(AssetManager *assetManager, char *name, i32 size) +{ + Font *result = NULL; + FontPack *pack = getMatchingFontPack(assetManager, name); + + if (pack != NULL) { + for (i32 j = 0; j < ARRAY_COUNT(pack->font); j++) + { + if (pack->font[j].fontHeight == size) + { + result = &pack->font[j]; + break; + } + } + } + + return result; +} + /* Individual glyph bitmap generated from STB used for creating a font sheet */ typedef struct GlyphBitmap { @@ -982,8 +1058,54 @@ typedef struct GlyphBitmap const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *persistentArena, - MemoryArena_ *transientArena, const char *filePath) + MemoryArena_ *transientArena, char *filePath, + char *name, i32 targetFontHeight) { + /* + **************************************** + * Initialise assetmanager font reference + **************************************** + */ + FontPack *fontPack = NULL; + for (i32 i = 0; i < assetManager->fontPackIndex; i++) + { + FontPack *checkFontPack = &assetManager->fontPack[i]; + if (common_strcmp(checkFontPack->name, name) == 0) + { + fontPack = checkFontPack; + break; + } + } + + if (fontPack == NULL) { + fontPack = &assetManager->fontPack[assetManager->fontPackIndex++]; + fontPack->name = name; + fontPack->filePath = filePath; + ASSERT(assetManager->fontPackIndex < + ARRAY_COUNT(assetManager->fontPack)); + } + + Font *font = NULL; + for (i32 j = 0; j < fontPack->fontIndex; j++) + { + Font *checkFont = &fontPack->font[j]; + if (checkFont->fontHeight == targetFontHeight) + { + font = &fontPack->font[j]; + break; + } + } + + if (font == NULL) + { + font = &fontPack->font[fontPack->fontIndex++]; + ASSERT(fontPack->fontIndex < ARRAY_COUNT(fontPack->font)); + } + else + { + return 0; + } + TempMemory tempRegion = memory_begin_temporary_region(transientArena); PlatformFileRead fontFileRead = {0}; @@ -995,12 +1117,6 @@ const i32 asset_loadTTFont(AssetManager *assetManager, stbtt_InitFont(&fontInfo, fontFileRead.buffer, stbtt_GetFontOffsetForIndex(fontFileRead.buffer, 0)); - /* - **************************************** - * Initialise assetmanager font reference - **************************************** - */ - Font *font = &assetManager->font; font->codepointRange = V2i(32, 127); v2 codepointRange = font->codepointRange; const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x); @@ -1009,8 +1125,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, memory_pushBytes(transientArena, numGlyphs * sizeof(GlyphBitmap)); v2 largestGlyphDimension = V2(0, 0); - const f32 targetFontHeight = 15.0f; - f32 scaleY = stbtt_ScaleForPixelHeight(&fontInfo, targetFontHeight); + font->fontHeight = targetFontHeight; + f32 scaleY = stbtt_ScaleForPixelHeight(&fontInfo, (f32)targetFontHeight); i32 ascent, descent, lineGap; stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); diff --git a/src/Asteroid.c b/src/Asteroid.c index 5d8c1d6..dd2ad5f 100644 --- a/src/Asteroid.c +++ b/src/Asteroid.c @@ -29,7 +29,7 @@ void initAssetManager(GameState *state) i32 result = asset_loadTTFont(assetManager, arena, &state->transientArena, - "C:/Windows/Fonts/Arialbd.ttf"); + "C:/Windows/Fonts/Arialbd.ttf", "Arial", 15); } { // Init shaders assets @@ -642,8 +642,8 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, state->init = TRUE; - debug_init(&state->persistentArena, windowSize, - state->assetManager.font); + Font *arial15 = asset_getFont(&state->assetManager, "Arial", 15); + debug_init(&state->persistentArena, windowSize, *arial15); } for (u32 i = world->asteroidCounter; i < world->numAsteroids; i++) @@ -1002,8 +1002,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, V2(0, 0), 0, NULL, V4(0, 0, 0, 0.5f), renderflag_no_texture); + Font *arial15 = asset_getFontCreateSizeOnDemand( + assetManager, &state->persistentArena, transientArena, "Arial", 15); + Font *arial25 = asset_getFontCreateSizeOnDemand( + assetManager, &state->persistentArena, transientArena, "Arial", 40); + v2 titleP = V2(20, renderer->size.h - 100); - renderer_staticString(renderer, transientArena, &assetManager->font, + renderer_staticString(renderer, transientArena, arial25, "Asteroids", titleP, V2(0, 0), 0, V4(1, 0, 0, 1), 0); @@ -1013,7 +1018,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, #if 1 userInterface_button(uiState, transientArena, assetManager, renderer, - &assetManager->font, *inputBuffer, 0, buttonRect, + arial15, *inputBuffer, 0, buttonRect, "test button"); #endif diff --git a/src/include/Dengine/AssetManager.h b/src/include/Dengine/AssetManager.h index f7938a5..ff61f3d 100644 --- a/src/include/Dengine/AssetManager.h +++ b/src/include/Dengine/AssetManager.h @@ -19,7 +19,9 @@ typedef struct AssetManager /* Primitive Array */ u32 shaders[shaderlist_count]; - Font font; + FontPack fontPack[4]; + i32 fontPackIndex; + } AssetManager; #define MAX_TEXTURE_SIZE 1024 @@ -78,9 +80,17 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena, const char *const fragmentPath, const enum ShaderList type); +Font *asset_getFontCreateSizeOnDemand(AssetManager *assetManager, + MemoryArena_ *persistentArena, + MemoryArena_ *transientArena, char *name, + i32 size); +Font *asset_getFont(AssetManager *assetManager, char *name, + i32 size); const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena_ *persistentArena, - MemoryArena_ *transientArena, const char *filePath); + MemoryArena_ *transientArena, char *filePath, + char *name, i32 targetFontHeight); + const v2 asset_stringDimInPixels(const Font *const font, const char *const string); diff --git a/src/include/Dengine/Assets.h b/src/include/Dengine/Assets.h index f27137b..1aa53bc 100644 --- a/src/include/Dengine/Assets.h +++ b/src/include/Dengine/Assets.h @@ -148,6 +148,13 @@ typedef struct CharMetrics typedef struct Font { + // NOTE(doyle): In stb_font we scale the loaded font to this target height + // and so this is used as a general font "size" notion + union { + i32 fontHeight; + i32 size; + }; + TexAtlas *atlas; FontMetrics metrics; @@ -159,6 +166,14 @@ typedef struct Font v2 codepointRange; v2 maxSize; - } Font; + +// NOTE(doyle): A font pack is a singular font at different sizes +typedef struct FontPack +{ + char *name; + char *filePath; + Font font[4]; + i32 fontIndex; +} FontPack; #endif