summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-11-10 16:48:20 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-11-12 12:14:05 -0500
commit283d1f8dff8731c7317f845a7df5f619b623a121 (patch)
treeaa2c729e51a4a7c530a6dca833fc4d414ef560e0
parent112c9d067343d85ffc77f559683c0284381d196e (diff)
pke: FontType pk_bkt_arr
-rw-r--r--editor/editor.cpp60
-rw-r--r--src/font.cpp177
-rw-r--r--src/font.hpp81
-rw-r--r--src/project.cpp16
-rw-r--r--src/serialization-font.cpp4
-rw-r--r--src/serialization-static-ui.cpp4
-rw-r--r--src/serialization.cpp12
-rw-r--r--src/window.cpp14
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);