summaryrefslogtreecommitdiff
path: root/src/font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/font.cpp')
-rw-r--r--src/font.cpp177
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);
}