Add variable font size generation

This commit is contained in:
Doyle Thai 2016-11-27 18:23:43 +11:00
parent ad14d6d822
commit c61b2022ce
4 changed files with 163 additions and 17 deletions

View File

@ -972,6 +972,82 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena,
return 0; 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 */ /* Individual glyph bitmap generated from STB used for creating a font sheet */
typedef struct GlyphBitmap typedef struct GlyphBitmap
{ {
@ -982,8 +1058,54 @@ typedef struct GlyphBitmap
const i32 asset_loadTTFont(AssetManager *assetManager, const i32 asset_loadTTFont(AssetManager *assetManager,
MemoryArena_ *persistentArena, 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); TempMemory tempRegion = memory_begin_temporary_region(transientArena);
PlatformFileRead fontFileRead = {0}; PlatformFileRead fontFileRead = {0};
@ -995,12 +1117,6 @@ const i32 asset_loadTTFont(AssetManager *assetManager,
stbtt_InitFont(&fontInfo, fontFileRead.buffer, stbtt_InitFont(&fontInfo, fontFileRead.buffer,
stbtt_GetFontOffsetForIndex(fontFileRead.buffer, 0)); stbtt_GetFontOffsetForIndex(fontFileRead.buffer, 0));
/*
****************************************
* Initialise assetmanager font reference
****************************************
*/
Font *font = &assetManager->font;
font->codepointRange = V2i(32, 127); font->codepointRange = V2i(32, 127);
v2 codepointRange = font->codepointRange; v2 codepointRange = font->codepointRange;
const i32 numGlyphs = CAST(i32)(codepointRange.y - codepointRange.x); 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)); memory_pushBytes(transientArena, numGlyphs * sizeof(GlyphBitmap));
v2 largestGlyphDimension = V2(0, 0); v2 largestGlyphDimension = V2(0, 0);
const f32 targetFontHeight = 15.0f; font->fontHeight = targetFontHeight;
f32 scaleY = stbtt_ScaleForPixelHeight(&fontInfo, targetFontHeight); f32 scaleY = stbtt_ScaleForPixelHeight(&fontInfo, (f32)targetFontHeight);
i32 ascent, descent, lineGap; i32 ascent, descent, lineGap;
stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);

View File

@ -29,7 +29,7 @@ void initAssetManager(GameState *state)
i32 result = i32 result =
asset_loadTTFont(assetManager, arena, &state->transientArena, asset_loadTTFont(assetManager, arena, &state->transientArena,
"C:/Windows/Fonts/Arialbd.ttf"); "C:/Windows/Fonts/Arialbd.ttf", "Arial", 15);
} }
{ // Init shaders assets { // Init shaders assets
@ -642,8 +642,8 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
state->init = TRUE; state->init = TRUE;
debug_init(&state->persistentArena, windowSize, Font *arial15 = asset_getFont(&state->assetManager, "Arial", 15);
state->assetManager.font); debug_init(&state->persistentArena, windowSize, *arial15);
} }
for (u32 i = world->asteroidCounter; i < world->numAsteroids; i++) 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), V2(0, 0), 0, NULL, V4(0, 0, 0, 0.5f),
renderflag_no_texture); 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); 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), "Asteroids", titleP, V2(0, 0), 0, V4(1, 0, 0, 1),
0); 0);
@ -1013,7 +1018,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
#if 1 #if 1
userInterface_button(uiState, transientArena, assetManager, renderer, userInterface_button(uiState, transientArena, assetManager, renderer,
&assetManager->font, *inputBuffer, 0, buttonRect, arial15, *inputBuffer, 0, buttonRect,
"test button"); "test button");
#endif #endif

View File

@ -19,7 +19,9 @@ typedef struct AssetManager
/* Primitive Array */ /* Primitive Array */
u32 shaders[shaderlist_count]; u32 shaders[shaderlist_count];
Font font; FontPack fontPack[4];
i32 fontPackIndex;
} AssetManager; } AssetManager;
#define MAX_TEXTURE_SIZE 1024 #define MAX_TEXTURE_SIZE 1024
@ -78,9 +80,17 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena_ *arena,
const char *const fragmentPath, const char *const fragmentPath,
const enum ShaderList type); 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, const i32 asset_loadTTFont(AssetManager *assetManager,
MemoryArena_ *persistentArena, MemoryArena_ *persistentArena,
MemoryArena_ *transientArena, const char *filePath); MemoryArena_ *transientArena, char *filePath,
char *name, i32 targetFontHeight);
const v2 asset_stringDimInPixels(const Font *const font, const v2 asset_stringDimInPixels(const Font *const font,
const char *const string); const char *const string);

View File

@ -148,6 +148,13 @@ typedef struct CharMetrics
typedef struct Font 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; TexAtlas *atlas;
FontMetrics metrics; FontMetrics metrics;
@ -159,6 +166,14 @@ typedef struct Font
v2 codepointRange; v2 codepointRange;
v2 maxSize; v2 maxSize;
} Font; } 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 #endif