diff options
Diffstat (limited to 'src/font.cpp')
| -rw-r--r-- | src/font.cpp | 177 |
1 files changed, 76 insertions, 101 deletions
diff --git a/src/font.cpp b/src/font.cpp index 33b35b8..bcbab0f 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -28,14 +28,12 @@ const char *PKE_PROJECT_FONT_SPACING_LINE_HEIGHT = "spacing_line_height: "; const char *PKE_PROJECT_FONT_SPACING_UNDERLINE_Y = "spacing_underline_y: "; const char *PKE_PROJECT_FONT_SPACING_UNDERLINE_THICKNESS = "spacing_underline_thickness: "; -TypeSafeInt_B(FontTypeIndex); TypeSafeInt_B(FONT_GLYPH_CHAR_FLAG); +TypeSafeInt_B(FONT_RENDER_FLAG); TypeSafeInt_B(FONT_RENDER_SURFACE_AREA_TYPE_FLAG); -struct FontTypeData { - FontType *arr_ft = nullptr; - uint64_t unused_fts = 0xFFFFFFFFFFFFFFFF; - FontTypeIndex n_ft{0}; +static struct FontTypeData { + pk_bkt_arr_t<FontType> fonts{}; pk_membucket *bkt; } ftd; @@ -51,7 +49,7 @@ struct FontInstanceBufferItem { float padding[3]; }; -void FontType_Unload(FontTypeIndex idx); +void FontType_Unload(FontTypeHandle font_type_handle); uint32_t utf8_to_unicode(const char* str, uint32_t &out) { uint32_t i = 0; @@ -325,15 +323,9 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta } void FontType_Init() { - FontTypeIndex fti; + FontTypeHandle fti; ftd.bkt = pk_mem_bucket_create(__FILE__, PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); - ftd.n_ft = FontTypeIndex{8}; - ftd.arr_ft = pk_new_arr<FontType>(8, ftd.bkt); - for (FontTypeIndex_T i = 0; i < 8; ++i) { - FontType *ft = &ftd.arr_ft[i]; - ft->glyphs = nullptr; - new (&ft->renders) pk_bkt_arr_t<FontRender>{pk_bkt_arr_handle_MAX, ftd.bkt, ftd.bkt}; - } + new (&ftd.fonts) pk_bkt_arr_t<FontType> (pk_bkt_arr_handle_MAX, ftd.bkt, ftd.bkt); union pke_asset_details ak_img_details { .texture = { .width = 952, @@ -355,16 +347,18 @@ void FontType_Init() { spacing.line_height = 1.125; spacing.underline_y = 0.0625; fti = FontType_RegisterFont(cstring_to_pk_cstr("fnt_mquin_7y"), ah_img, ah_glyphs, &msdf_s, &spacing); - ftd.arr_ft[static_cast<FontTypeIndex_T>(fti)].entity_flags |= ENTITY_FLAG_DO_NOT_SERIALIZE; + ftd.fonts[fti].entity_flags |= ENTITY_FLAG_DO_NOT_SERIALIZE; } void FontType_Teardown() { - int i; - for (i = (int)(FontTypeIndex_T)ftd.n_ft-1; i >= 0; --i) { - if ((ftd.unused_fts & (1llu << i)) != 0) continue; - FontType_Unload(FontTypeIndex{(FontTypeIndex_T)i}); + bool b; + pk_iter_t<FontType> iter_ft{}; + b = pk_bkt_arr_iter_begin(&ftd.fonts, &iter_ft); + while (b == true) { + FontType_Unload(iter_ft->font_type_handle); + b = pk_bkt_arr_iter_increment(&ftd.fonts, &iter_ft); } - if (ftd.arr_ft != nullptr) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)ftd.n_ft, ftd.bkt); + pk_bkt_arr_teardown(&ftd.fonts); pk_mem_bucket_destroy(ftd.bkt); ftd.bkt = nullptr; } @@ -377,19 +371,18 @@ void FontType_Tick(double delta) { (void)delta; VkResult vkResult; uint32_t index; - FontType *ft; - for (FontTypeIndex_T i = 0; i < (FontTypeIndex_T)ftd.n_ft; ++i) { - - if ((ftd.unused_fts & (1llu << i)) != 0) continue; + bool b; + pk_iter_t<FontType> ft{}; + b = pk_bkt_arr_iter_begin(&ftd.fonts, &ft); + while (b) { index = 0; - ft = &ftd.arr_ft[i]; pk_bkt_arr_t<FontRender>::FN_Iter iter_fn; iter_fn.func = [&ft, &index](FontRender *fr) { if (fr->isMarkedForRemoval == true) { if (fr->text.reserved > 0) { pk_delete_arr<char>(fr->text.val, fr->text.reserved); } - pk_bkt_arr_free_handle(&ft->renders, fr->fr_handle); + pk_bkt_arr_free_handle(&ft->renders, fr->font_render_handle); ft->gr.should_update_instance_buffer = true; return; } @@ -398,16 +391,19 @@ void FontType_Tick(double delta) { pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); if (ft->isMarkedForRemoval == true) { - FontType_Unload(FontTypeIndex{i}); + FontType_Unload(FontTypeHandle{ft.id.bkt.b, ft.id.bkt.i}); + b = pk_bkt_arr_iter_increment(&ftd.fonts, &ft); continue; } if (pkeSettings.rt.was_framebuffer_resized == false && ft->gr.should_update_instance_buffer == false) { + b = pk_bkt_arr_iter_increment(&ftd.fonts, &ft); continue; } if (index == 0) { ft->bindings.instance_counter = 0; + b = pk_bkt_arr_iter_increment(&ftd.fonts, &ft); continue; } ft->gr.should_update_instance_buffer = false; @@ -492,13 +488,14 @@ void FontType_Tick(double delta) { } PKVK_EndBuffer(tmpBufferDetails); pk_arr_reset(&fibis); + + b = pk_bkt_arr_iter_increment(&ftd.fonts, &ft); } } void FontType_Serialize(std::ostream &stream, FontType *ft) { FontTypeSpacing sp{}; FontTypeMSDFSettings msdf{}; - memset(&sp, 0, sizeof(sp)); NULL_CHAR_ARR(handleStr, AssetKeyLength + 2); const Asset *txtr = AM_Get(ft->fontTextureAssetHandle); const Asset *glyphs = AM_Get(ft->glyphDetailsAssetHandle); @@ -546,7 +543,6 @@ void FontType_Deserialize(std::istream &stream) { pk_cstr title; AssetKey fontTextureKey; AssetKey glyphDetailsKey; - memset(&sp, 0, sizeof(sp)); while (memset(readLine, 0, 128), stream.getline(readLine, 128)) { if (strcmp("", readLine) == 0) { FontType_RegisterFont(title, AM_GetHandle(fontTextureKey), AM_GetHandle(glyphDetailsKey), &msdf, &sp); @@ -631,68 +627,46 @@ void FontType_Deserialize(std::istream &stream) { } } -FontType* FontType_Get(FontTypeIndex idx) { - assert((ftd.unused_fts & (1llu << FontTypeIndex_T(idx))) == 0); - return &ftd.arr_ft[static_cast<FontTypeIndex_T>(idx)]; +FontType* FontType_Get(FontTypeHandle font_type_handle) { + assert(pk_bkt_arr_handle_validate(&ftd.fonts, font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + return &ftd.fonts[font_type_handle]; } FontType* FontType_GetByTitle(const pk_cstr title) { assert(title.val != nullptr); - for (FontTypeIndex_T i = 0; i < (FontTypeIndex_T)ftd.n_ft; ++i) { - if ((ftd.unused_fts & (1llu << i)) != 0) continue; - if (ftd.arr_ft[i].title.val == title.val) - return &ftd.arr_ft[i]; - if (strcmp(ftd.arr_ft[i].title.val, title.val) == 0) - return &ftd.arr_ft[i]; + bool b; + pk_iter_t<FontType> iter_ft{}; + b = pk_bkt_arr_iter_begin(&ftd.fonts, &iter_ft); + while(b) { + if (iter_ft->title.val == title.val || strcmp(iter_ft->title.val, title.val) == 0) + return (FontType*)iter_ft.data; + b = pk_bkt_arr_iter_increment(&ftd.fonts, &iter_ft); } return nullptr; } -FontType* FontType_GetFonts(uint64_t &idx_unused) { - idx_unused = ftd.unused_fts; - return ftd.arr_ft; +pk_bkt_arr* FontType_GetFonts() { + return &ftd.fonts; } -FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing) { +FontTypeHandle FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing) { VkResult vkResult; const Asset *fontTexture = nullptr; const Asset *glyphs = nullptr; - FontTypeIndex idx{0}; - FontTypeIndex_T idx_t; + FontTypeHandle font_type_handle; FontType *ft; - uint16_t u; assert(fontTextureHandle != AssetHandle_MAX); assert(glyphsHandle != AssetHandle_MAX); assert(msdf_settings != nullptr); assert(spacing != nullptr); - for (u = 0; u < (FontTypeIndex_T)ftd.n_ft; ++u) { - if ((ftd.unused_fts & (1llu << u)) != 0) { - idx_t = u; - idx = FontTypeIndex{idx_t}; - ftd.unused_fts &= ~(1llu << idx_t); - break; - } - } - - if (idx >= ftd.n_ft) { - if (idx_t >= PKE_FONT_MAX_FONT_TYPES) { - throw "[font.cpp] out of font type slots"; - } - ftd.n_ft = FontTypeIndex{8}; - FontType *arr = pk_new_arr<FontType>((FontTypeIndex_T)ftd.n_ft, ftd.bkt); - if (idx > FontTypeIndex{0}) { - memcpy(arr, ftd.arr_ft, sizeof(FontType) * (FontTypeIndex_T)idx); - } - if (ftd.arr_ft != nullptr && ftd.arr_ft != CAFE_BABE(FontType)) pk_delete_arr<FontType>(ftd.arr_ft, (FontTypeIndex_T)idx, ftd.bkt); - ftd.arr_ft = arr; - } - fontTexture = AM_Get(fontTextureHandle); - idx_t = (FontTypeIndex_T)idx; - ft = &ftd.arr_ft[idx_t]; + font_type_handle = FontTypeHandle {pk_bkt_arr_new_handle(&ftd.fonts)}; + ft = &ftd.fonts[font_type_handle]; + new (ft) FontType {}; + ft->font_type_handle = font_type_handle; ft->title = title; ft->fontTextureAssetHandle = fontTextureHandle; ft->glyphDetailsAssetHandle = glyphsHandle; @@ -823,13 +797,13 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle AM_Release(fontTextureHandle); AM_Release(glyphsHandle); - return idx; + return font_type_handle; } -void FontType_Unload(FontTypeIndex idx) { - assert((ftd.unused_fts & (1llu << (FontTypeIndex_T)idx)) == 0); +void FontType_Unload(FontTypeHandle font_type_handle) { + assert(pk_bkt_arr_handle_validate(&ftd.fonts, font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); - FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)idx]; + FontType *ft = &ftd.fonts[font_type_handle]; if (ft->renders.head_r.b > 0 || ft->renders.head_r.i > 0) { pk_bkt_arr_t<FontRender>::FN_Iter iter_fn{}; @@ -915,7 +889,6 @@ void FontType_Unload(FontTypeIndex idx) { ft->title.val = nullptr; ft->title.length = 0; } - ftd.unused_fts |= (1llu << (FontTypeIndex_T)idx); new (ft) FontType{}; } @@ -961,22 +934,22 @@ void FontType_cstr_to_unicode(const FontType &ft, pk_arr_t<uint32_t> &arr, const // However, the new buffer is exactly the length it needs to be and no greater. // Consider using a heuristic to allocate a buffer larger than needed. // At the time of writing, the only way to do this is to un-register text. -FontTypeRender FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { +FontTypeRender FontType_AddStringRender(FontTypeHandle font_type_handle, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) { assert(settings != nullptr); - FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)idx_ft]; + FontType *ft = &ftd.fonts[font_type_handle]; FontRender *fr; FontTypeRender ret{}; uint32_t i, count; - ret.index_ft = idx_ft; - ret.handle_fr = (FontRenderHandle)pk_bkt_arr_new_handle(&ft->renders); - fr = &ft->renders[ret.handle_fr]; + ret.font_type_handle = font_type_handle; + ret.font_render_handle = FontRenderHandle{pk_bkt_arr_new_handle(&ft->renders)}; + fr = &ft->renders[ret.font_render_handle]; new (fr) FontRender{}; fr->uuid = uuid; ECS_CreateEntity(fr, parent); - fr->index_ft = idx_ft; - fr->fr_handle = ret.handle_fr; + fr->font_type_handle = font_type_handle; + fr->font_render_handle = ret.font_render_handle; fr->settings = *settings; fr->text = str; @@ -1006,32 +979,32 @@ FontTypeRender FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&st return ret; } -FontRender *FontType_GetFontRender(FontTypeRender frh) { - if ((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) != 0) { +FontRender *FontType_GetFontRender(FontTypeRender ftr) { + if (pk_bkt_arr_handle_validate(&ftd.fonts, ftr.font_type_handle) != PK_BKT_ARR_HANDLE_VALIDATION_VALID) { return nullptr; } - FontType *ft = &ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; - if (pk_bkt_arr_handle_validate(&ft->renders, frh.handle_fr) != PK_BKT_ARR_HANDLE_VALIDATION_VALID) { + FontType *ft = &ftd.fonts[ftr.font_type_handle]; + if (pk_bkt_arr_handle_validate(&ft->renders, ftr.font_render_handle) != PK_BKT_ARR_HANDLE_VALIDATION_VALID) { return nullptr; } - return &ft->renders[frh.handle_fr]; + return &ft->renders[ftr.font_render_handle]; } -void FontType_UpdateStringRender(FontTypeRender frh, FontRenderSettings *settings) { +void FontType_UpdateStringRender(FontTypeRender ftr, FontRenderSettings *settings) { assert(settings != nullptr); - assert((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) == 0); - FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)frh.index_ft]; - assert(pk_bkt_arr_handle_validate(&ft->renders, frh.handle_fr) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + assert(pk_bkt_arr_handle_validate(&ftd.fonts, ftr.font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + FontType *ft = &ftd.fonts[ftr.font_type_handle]; + assert(pk_bkt_arr_handle_validate(&ft->renders, ftr.font_render_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); ft->gr.should_update_instance_buffer = true; - ft->renders[frh.handle_fr].settings = *settings; + ft->renders[ftr.font_render_handle].settings = *settings; } -void FontType_UpdateStringRenderText(FontTypeRender frh, pk_cstr &&cstr) { +void FontType_UpdateStringRenderText(FontTypeRender ftr, pk_cstr &&cstr) { uint32_t i, count; - assert((ftd.unused_fts & (1llu << (FontTypeIndex_T)frh.index_ft)) == 0); - FontType &ft = ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)]; - assert(pk_bkt_arr_handle_validate(&ft.renders, frh.handle_fr) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); - FontRender &fr = ft.renders[frh.handle_fr]; + assert(pk_bkt_arr_handle_validate(&ftd.fonts, ftr.font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + FontType *ft = &ftd.fonts[ftr.font_type_handle]; + assert(pk_bkt_arr_handle_validate(&ft->renders, ftr.font_render_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + FontRender &fr = ft->renders[ftr.font_render_handle]; pk_cstr old_str = fr.text; if (window == NULL) { return; @@ -1040,7 +1013,7 @@ void FontType_UpdateStringRenderText(FontTypeRender frh, pk_cstr &&cstr) { glyph_indices.bkt = pkeSettings.mem_bkt.game_transient; pk_arr_reserve(&glyph_indices, PK_MAX(1, fr.n_glyphs + (cstr.length - old_str.length))); - FontType_cstr_to_unicode(ft, glyph_indices, cstr); + FontType_cstr_to_unicode(*ft, glyph_indices, cstr); // TODO specific bucket count = glyph_indices.next; @@ -1053,15 +1026,17 @@ void FontType_UpdateStringRenderText(FontTypeRender frh, pk_cstr &&cstr) { if (fr.text.reserved > 0 && fr.text.val != NULL) pk_delete_arr<char>(fr.text.val, fr.text.reserved, ftd.bkt); fr.text = cstr; - ft.gr.should_update_instance_buffer = true; + ft->gr.should_update_instance_buffer = true; } -void FontType_RemoveStringRender(FontTypeRender handle) { +void FontType_RemoveStringRender(FontTypeRender ftr) { FontRender *fr; - FontType *ft = &ftd.arr_ft[(FontTypeIndex_T)handle.index_ft]; + assert(pk_bkt_arr_handle_validate(&ftd.fonts, ftr.font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + FontType *ft = &ftd.fonts[ftr.font_type_handle]; + assert(pk_bkt_arr_handle_validate(&ft->renders, ftr.font_render_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); // hack, but works ft->gr.should_update_instance_buffer = true; - fr = &ft->renders[handle.handle_fr]; + fr = &ft->renders[ftr.font_render_handle]; ECS_MarkForRemoval(fr); } |
