diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-11-10 16:48:20 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-11-12 12:14:05 -0500 |
| commit | 283d1f8dff8731c7317f845a7df5f619b623a121 (patch) | |
| tree | aa2c729e51a4a7c530a6dca833fc4d414ef560e0 | |
| parent | 112c9d067343d85ffc77f559683c0284381d196e (diff) | |
pke: FontType pk_bkt_arr
| -rw-r--r-- | editor/editor.cpp | 60 | ||||
| -rw-r--r-- | src/font.cpp | 177 | ||||
| -rw-r--r-- | src/font.hpp | 81 | ||||
| -rw-r--r-- | src/project.cpp | 16 | ||||
| -rw-r--r-- | src/serialization-font.cpp | 4 | ||||
| -rw-r--r-- | src/serialization-static-ui.cpp | 4 | ||||
| -rw-r--r-- | src/serialization.cpp | 12 | ||||
| -rw-r--r-- | src/window.cpp | 14 |
8 files changed, 195 insertions, 173 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp index a1b8613..7245e22 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -1208,6 +1208,49 @@ void RecordImGuiPlayerInput() { ImGui::End(); } +void RecordImGuiFont() { + pk_iter_t<FontType> iter_ft{}; + bool b; + if (!ImGui::Begin("Fonts")) { + ImGui::End(); + return; + } + static ImGuiTableFlags tableFlags{ + ImGuiTableFlags_Borders | + ImGuiTableFlags_Resizable | + ImGuiTableFlags_RowBg + }; + + pk_bkt_arr_t<FontType> &fonts_base = *static_cast<pk_bkt_arr_t<FontType>*>(FontType_GetFonts()); + + if (ImGui::BeginTable("Font list", 3, tableFlags)) { + ImGui::TableSetupColumn("Title"); + ImGui::TableSetupColumn("MSDF settings"); + ImGui::TableSetupColumn("Spacing"); + ImGui::TableHeadersRow(); + b = pk_bkt_arr_iter_begin(&fonts_base, &iter_ft); + while(b) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Title: %s", iter_ft->title.val); + ImGui::TableSetColumnIndex(1); + ImGui::Text("minimum_scale: %f", iter_ft->msdf_settings.minimum_scale); + ImGui::Text("px_range: %f", iter_ft->msdf_settings.px_range); + ImGui::TableSetColumnIndex(2); + ImGui::Text("geometry_scale: %f", iter_ft->spacing.geometry_scale); + ImGui::Text("em_size: %f", iter_ft->spacing.em_size); + ImGui::Text("ascender_y: %f", iter_ft->spacing.ascender_y); + ImGui::Text("descender_y: %f", iter_ft->spacing.descender_y); + ImGui::Text("line_height: %f", iter_ft->spacing.line_height); + ImGui::Text("underline_y: %f", iter_ft->spacing.underline_y); + ImGui::Text("underline_thickness: %f", iter_ft->spacing.underline_thickness); + b = pk_bkt_arr_iter_increment(&fonts_base, &iter_ft); + } + ImGui::EndTable(); + } + ImGui::End(); +} + void RecordImGuiCameras() { bool b; pk_bkt_arr *bkt_arr_cams; @@ -1423,10 +1466,10 @@ void RecordImGuiUITree() { selected_ui_box = box; FontRenderSettings frs{}; if (type == PKE_UI_BOX_TYPE_TEXT) { - box->type_data->text.font_type_render = FontType_AddStringRender(FontTypeIndex(0), std::move(cstring_to_pk_cstr("")), &frs, box); + box->type_data->text.font_type_render = FontType_AddStringRender(FontTypeHandle{0,0}, std::move(cstring_to_pk_cstr("")), &frs, box); } if (type == PKE_UI_BOX_TYPE_BUTTON_TEXT) { - box->type_data->button_text.font_type_render = FontType_AddStringRender(FontTypeIndex(0), std::move(cstring_to_pk_cstr("")), &frs, box); + box->type_data->button_text.font_type_render = FontType_AddStringRender(FontTypeHandle{0,0}, std::move(cstring_to_pk_cstr("")), &frs, box); } is_creating_new_box = false; is_child = false; @@ -1548,7 +1591,7 @@ void RecordImGuiUIEdit() { ImGui::Text("Type: Text"); ImGui::Separator(); FontRender fr = *FontType_GetFontRender(selected_ui_box->type_data->text.font_type_render); - ImGui::Text("FontRender: %.4hu:%.4hu", fr.fr_handle.b, fr.fr_handle.i); + ImGui::Text("FontRender: %.4hu:%.4hu", fr.font_render_handle.b, fr.font_render_handle.i); const int buffer_len = 1024; char *text_buffer = pk_new_arr<char>(buffer_len, pkeSettings.mem_bkt.game_transient); size_t len = fr.text.length; @@ -1562,14 +1605,14 @@ void RecordImGuiUIEdit() { cstr.reserved = len+1; cstr.length = len; cstr.val = s; - FontType_UpdateStringRenderText({fr.index_ft, {fr.fr_handle}}, std::move(cstr)); + FontType_UpdateStringRenderText({fr.font_type_handle, fr.font_render_handle}, std::move(cstr)); changed = true; } ImGui::SameLine(); ImGui::Text("(%.4zu/%4i)", len, buffer_len); changed_sub = RecordImGui_FontRenderSettings(fr.settings, false); if (changed_sub) { - FontType_UpdateStringRender({fr.index_ft, {fr.fr_handle}}, &fr.settings); + FontType_UpdateStringRender({fr.font_type_handle, fr.font_render_handle}, &fr.settings); } changed |= changed_sub; } @@ -1639,7 +1682,7 @@ void RecordImGuiUIEdit() { ImGui::Text("Type: Button Text"); ImGui::Separator(); FontRender fr = *FontType_GetFontRender(selected_ui_box->type_data->button_text.font_type_render); - ImGui::Text("FontRender: %.4hu:%.4hu", fr.fr_handle.b, fr.fr_handle.i); + ImGui::Text("FontRender: %.4hu:%.4hu", fr.font_render_handle.b, fr.font_render_handle.i); const int buffer_len = 1024; char *text_buffer = pk_new_arr<char>(buffer_len, pkeSettings.mem_bkt.game_transient); size_t len = fr.text.length; @@ -1653,14 +1696,14 @@ void RecordImGuiUIEdit() { cstr.reserved = len+1; cstr.length = len; cstr.val = s; - FontType_UpdateStringRenderText({fr.index_ft, {fr.fr_handle}}, std::move(cstr)); + FontType_UpdateStringRenderText({fr.font_type_handle, fr.font_render_handle}, std::move(cstr)); changed = true; } ImGui::SameLine(); ImGui::Text("(%.4zu/%4i)", len, buffer_len); changed_sub = RecordImGui_FontRenderSettings(fr.settings, false); if (changed_sub) { - FontType_UpdateStringRender({fr.index_ft, {fr.fr_handle}}, &fr.settings); + FontType_UpdateStringRender({fr.font_type_handle, fr.font_render_handle}, &fr.settings); } changed |= changed_sub; } @@ -2248,6 +2291,7 @@ void PkeEditor_RecordImGui() { RecordImGuiEntityTypes(); RecordImGuiAssets(); RecordImGuiPlayerInput(); + RecordImGuiFont(); } } 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); } diff --git a/src/font.hpp b/src/font.hpp index cdbc309..001745b 100644 --- a/src/font.hpp +++ b/src/font.hpp @@ -9,9 +9,10 @@ #define PKE_FONT_MAX_FONT_TYPES 64 -TypeSafeInt_H(FontTypeIndex, uint16_t, 0xFFFF); +struct FontTypeHandle : pk_bkt_arr_handle {}; struct FontRenderHandle : pk_bkt_arr_handle {}; +constexpr FontTypeHandle FontTypeHandle_MAX = FontTypeHandle{ pk_bkt_arr_handle_MAX_constexpr }; constexpr FontRenderHandle FontRenderHandle_MAX = FontRenderHandle{ pk_bkt_arr_handle_MAX_constexpr }; TypeSafeInt_H(FONT_GLYPH_CHAR_FLAG, uint8_t, 0xFF); @@ -42,13 +43,13 @@ const FONT_RENDER_SURFACE_AREA_TYPE_FLAG FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CEN = FONT_RENDER_SURFACE_AREA_TYPE_FLAG((1u << 0) | (1u << 1)); struct FontTypeRender { - FontTypeIndex index_ft; - FontRenderHandle handle_fr; + FontTypeHandle font_type_handle; + FontRenderHandle font_render_handle; }; constexpr FontTypeRender FontTypeRender_MAX = { - .index_ft = FontTypeIndex_MAX, - .handle_fr = { pk_bkt_arr_handle_MAX }, + .font_type_handle = FontTypeHandle_MAX, + .font_render_handle = FontRenderHandle_MAX, }; struct FontGlyphChar { @@ -72,37 +73,37 @@ struct FontRenderSettings { }; struct FontRender : public Entity_Base { uint32_t *glyph_indices = nullptr; - FontTypeIndex index_ft = FontTypeIndex{0}; - FontRenderHandle fr_handle = FontRenderHandle_MAX; + FontTypeHandle font_type_handle = FontTypeHandle_MAX; + FontRenderHandle font_render_handle = FontRenderHandle_MAX; uint32_t n_glyphs = 0; uint32_t buffer_start_index = 0; FontRenderSettings settings{}; pk_cstr text{}; }; struct FontTypeMSDFSettings { - float minimum_scale; - float px_range; + float minimum_scale = 0.f; + float px_range = 0.f; }; struct FontTypeSpacing { - double geometry_scale; - double em_size; - double ascender_y; - double descender_y; - double line_height; - double underline_y; - double underline_thickness; + double geometry_scale = 0.f; + double em_size = 0.f; + double ascender_y = 0.f; + double descender_y = 0.f; + double line_height = 0.f; + double underline_y = 0.f; + double underline_thickness = 0.f; }; struct FontType : public Entity_Base { - pk_cstr title; - AssetHandle fontTextureAssetHandle; - AssetHandle glyphDetailsAssetHandle; - FontGlyphChar *glyphs; - glm::vec2 atlas_size; - uint32_t n_glyphs; - pk_bkt_arr_t<FontRender> renders; - FontTypeIndex index_ft = FontTypeIndex{0}; - struct FontTypeMSDFSettings msdf_settings; - struct FontTypeSpacing spacing; + pk_cstr title{}; + AssetHandle fontTextureAssetHandle = AssetHandle_MAX; + AssetHandle glyphDetailsAssetHandle = AssetHandle_MAX; + FontGlyphChar *glyphs = nullptr; + glm::vec2 atlas_size = glm::vec2(0,0); + uint32_t n_glyphs = 0; + pk_bkt_arr_t<FontRender> renders{}; + FontTypeHandle font_type_handle = FontTypeHandle_MAX; + struct FontTypeMSDFSettings msdf_settings{}; + struct FontTypeSpacing spacing{}; struct FontTypeGraphics { VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE; @@ -111,14 +112,14 @@ struct FontType : public Entity_Base { VkImageView textureImageView = VK_NULL_HANDLE; VkDescriptorPool vkDescriptorPool = VK_NULL_HANDLE; VkDescriptorSet vkDescriptorSet = VK_NULL_HANDLE; - bool should_update_instance_buffer; + bool should_update_instance_buffer = false; } gr; struct FontTypeBindings { - BufferBindingDetails bd_vertex; - BufferBindingDetails bd_uv; - BufferBindingDetails bd_atlas_size; - BufferBindingDetails bd_index; - BufferBindingDetails bd_instance; + BufferBindingDetails bd_vertex{}; + BufferBindingDetails bd_uv{}; + BufferBindingDetails bd_atlas_size{}; + BufferBindingDetails bd_index{}; + BufferBindingDetails bd_instance{}; uint32_t index_count = 0; uint32_t instance_counter = 0; uint32_t instance_buffer_max_count = 0; @@ -130,14 +131,14 @@ void FontType_Teardown(); void FontType_Tick(double delta); void FontType_Serialize(std::ostream &stream, FontType *ft); void FontType_Deserialize(std::istream &stream); -FontType* FontType_Get(FontTypeIndex idx); +FontType* FontType_Get(FontTypeHandle font_type_handle); FontType* FontType_GetByTitle(const pk_cstr title); -FontType* FontType_GetFonts(uint64_t &idx_unused); -FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing); -FontTypeRender FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr, pk_uuid uuid = pk_uuid_zed); -FontRender *FontType_GetFontRender(FontTypeRender frh); -void FontType_UpdateStringRender(FontTypeRender frh, FontRenderSettings *settings); -void FontType_UpdateStringRenderText(FontTypeRender frh, pk_cstr &&cstr); -void FontType_RemoveStringRender(FontTypeRender frh); +pk_bkt_arr* FontType_GetFonts(); +FontTypeHandle FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing); +FontTypeRender FontType_AddStringRender(FontTypeHandle font_type_handle, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr, pk_uuid uuid = pk_uuid_zed); +FontRender *FontType_GetFontRender(FontTypeRender ftr); +void FontType_UpdateStringRender(FontTypeRender ftr, FontRenderSettings *settings); +void FontType_UpdateStringRenderText(FontTypeRender ftr, pk_cstr &&cstr); +void FontType_RemoveStringRender(FontTypeRender ftr); #endif /* PKE_FONT_TYPE_HPP */ diff --git a/src/project.cpp b/src/project.cpp index e1c3333..32f6503 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -396,8 +396,10 @@ void PkeProject_Save(const char *filePath) { bool b; pk_iter_t<Asset> iter_asset{}; pk_iter_t<EntityType> iter_ent_type{}; + pk_iter_t<FontType> iter_font_type{}; pk_bkt_arr *bkt_arr_assets; pk_bkt_arr *bkt_arr_ent_types; + pk_bkt_arr *bkt_arr_font_types; const char *saveFilePath = filePath == nullptr ? PKE_PROJ_DEFAULT_FILENAME : filePath; std::ostringstream stream{}; @@ -452,16 +454,14 @@ void PkeProject_Save(const char *filePath) { b = pk_bkt_arr_iter_increment(bkt_arr_ent_types, &iter_ent_type); } - uint64_t idx_unused; - FontType *fonts = FontType_GetFonts(idx_unused); - for (uint64_t u = 0; u < PKE_FONT_MAX_FONT_TYPES; ++u) { - if ((idx_unused & (1llu << u)) != 0) continue; - FontType *ft = &fonts[(FontTypeIndex_T)u]; - if (ft->title.val == nullptr) continue; - if (PK_HAS_FLAG(ft->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) continue; + bkt_arr_font_types = FontType_GetFonts(); + b = pk_bkt_arr_iter_begin(bkt_arr_font_types, &iter_font_type); + while(b) { + if (PK_HAS_FLAG(iter_font_type->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) continue; stream << PKE_PROJ_FILE_OBJ_FONT << std::endl; - FontType_Serialize(stream, ft); + FontType_Serialize(stream, iter_font_type); stream << PKE_PROJ_FILE_OBJ_END << std::endl; + b = pk_bkt_arr_iter_increment(bkt_arr_font_types, &iter_font_type); } stream << PKE_PROJ_FILE_END << std::endl; diff --git a/src/serialization-font.cpp b/src/serialization-font.cpp index 328aa94..501d6ed 100644 --- a/src/serialization-font.cpp +++ b/src/serialization-font.cpp @@ -41,7 +41,7 @@ pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr) } { kve.key = SRLZTN_UI_FONT_RENDER_FONT_TYPE_TITLE; - FontType *ft = FontType_Get(fr->index_ft); + FontType *ft = FontType_Get(fr->font_type_handle); len = snprintf(nullptr, 0, "%s", ft->title.val); s = pk_new_arr<char>(len+1, h->bkt); sprintf(s, "%s", ft->title.val); @@ -109,7 +109,7 @@ void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container // parent is set later - up to the parent to take ownership assert(font_type_ent != nullptr); - FontType_AddStringRender(font_type_ent->index_ft, std::move(str), &frs, nullptr, uuid); + FontType_AddStringRender(font_type_ent->font_type_handle, std::move(str), &frs, nullptr, uuid); } pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs) { diff --git a/src/serialization-static-ui.cpp b/src/serialization-static-ui.cpp index 373bc16..ba67fbd 100644 --- a/src/serialization-static-ui.cpp +++ b/src/serialization-static-ui.cpp @@ -139,7 +139,7 @@ void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_conta FontRender *fr = static_cast<FontRender *>(ECS_GetEntityByUUID(font_render_uuid)); - data->font_type_render = {fr->index_ft, {fr->fr_handle}}; + data->font_type_render = {fr->font_type_handle, fr->font_render_handle}; } void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data::pke_ui_box_type_data_button_text *data) { @@ -163,7 +163,7 @@ void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_conta FontRender *fr = static_cast<FontRender *>(ECS_GetEntityByUUID(font_render_uuid)); - data->font_type_render = {fr->index_ft, {fr->fr_handle}}; + data->font_type_render = {fr->font_type_handle, fr->font_render_handle}; } void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data::pke_ui_box_type_data_button_image *data) { diff --git a/src/serialization.cpp b/src/serialization.cpp index a09a332..ac6aebc 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -69,6 +69,7 @@ void pke_deserialize_project_from_stream(std::istream &i, srlztn_deserialize_hel void pke_serialize_scene(srlztn_serialize_helper *h) { bool b; pk_bkt_arr *bkt_arr_instance; + pk_iter_t<FontType> iter_ft{}; pk_iter_t<CompInstance> iter_instance{}; pk_iter_t<PkeCamera> iter_cam{}; @@ -80,16 +81,15 @@ void pke_serialize_scene(srlztn_serialize_helper *h) { pke_serialize_input_set(h, &sets[i]); } - uint64_t idx_unused; - FontType *fonts = FontType_GetFonts(idx_unused); - for (FontTypeIndex_T b = 0; b < PKE_FONT_MAX_FONT_TYPES; ++b) { - if ((idx_unused & (1llu << b)) != 0) continue; - FontType *ft = &fonts[b]; + pk_bkt_arr_t<FontType> *fonts = static_cast<pk_bkt_arr_t<FontType>*>(FontType_GetFonts()); + b = pk_bkt_arr_iter_begin(fonts, &iter_ft); + while(b) { pk_bkt_arr_t<FontRender>::FN_Iter iter_fn{}; iter_fn.func = [&h](FontRender *fr) { pke_serialize_font_render(h, fr); }; - pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); + pk_bkt_arr_iterate(&iter_ft->renders, iter_fn.invoke, &iter_fn); + b = pk_bkt_arr_iter_increment(fonts, &iter_ft); } pke_ui_box_count_T box_count; diff --git a/src/window.cpp b/src/window.cpp index b93d8ab..c921103 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3861,13 +3861,14 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { vkCmdSetScissor(commandBuffer, 0, 1, &scissor); // 2d - font glyphs - uint64_t idx_unused; - FontType *fts = FontType_GetFonts(idx_unused); - for (uint32_t u = 0; u < 64; ++u) { - if ((idx_unused & (1llu << u)) != 0) continue; - FontType *ft = &fts[(FontTypeIndex_T)u]; - if (ft->bindings.instance_counter == 0) + pk_iter_t<FontType> ft{}; + pk_bkt_arr *fonts = FontType_GetFonts(); + b = pk_bkt_arr_iter_begin(fonts, &ft); + while(b) { + if (ft->bindings.instance_counter == 0) { + b = pk_bkt_arr_iter_increment(fonts, &ft); continue; + } vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.font_glyph); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.txtr, 0, 1, &ft->gr.vkDescriptorSet, 0, {}); @@ -3879,6 +3880,7 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { vkCmdBindVertexBuffers(commandBuffer, ft->bindings.bd_instance.firstBinding, ft->bindings.bd_instance.bindingCount, &ft->bindings.bd_instance.buffer, ft->bindings.bd_instance.offsets); vkCmdDrawIndexed(commandBuffer, ft->bindings.index_count, ft->bindings.instance_counter, 0, 0, 0); + b = pk_bkt_arr_iter_increment(fonts, &ft); } vkCmdEndRendering(commandBuffer); |
