diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-07 22:29:57 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-07 22:29:57 +0200 |
| commit | 748bd9b738df2a789811a02c76bacd4855959d65 (patch) | |
| tree | 7a8f55d98ef6bc72d214fcd67c4298eb1a7cfa3f | |
| parent | 1d1d49ea314f2e5a644b1ed9ac4908234a02e3de (diff) | |
call ft_fone_face only if no more memory face is in use, debug array_del by reference
| -rw-r--r-- | include/vkvg.h | 16 | ||||
| -rw-r--r-- | src/vkvg_fonts.c | 41 | ||||
| -rw-r--r-- | src/vkvg_fonts.h | 4 | ||||
| -rw-r--r-- | src/vkvg_internal.h | 18 | ||||
| -rw-r--r-- | tests/fonts/allfont.c | 8 |
5 files changed, 52 insertions, 35 deletions
diff --git a/include/vkvg.h b/include/vkvg.h index 8ad8d0c..011230a 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -88,17 +88,19 @@ extern "C" { #endif #define VKVG_LOG_ERR 0x00000001 -#define VKVG_LOG_DEBUG 0x00000002 +#define VKVG_LOG_WARN 0x00000002 +#define VKVG_LOG_DEBUG 0x00000004 -#define VKVG_LOG_INFO_PTS 0x00000004 -#define VKVG_LOG_INFO_PATH 0x00000008 -#define VKVG_LOG_INFO_CMD 0x00000010 -#define VKVG_LOG_INFO_VBO 0x00000020 -#define VKVG_LOG_INFO_IBO 0x00000040 +#define VKVG_LOG_INFO_PTS 0x00000008 +#define VKVG_LOG_INFO_PATH 0x00000010 +#define VKVG_LOG_INFO_CMD 0x00000020 +#define VKVG_LOG_INFO_VBO 0x00000040 +#define VKVG_LOG_INFO_IBO 0x00000080 #define VKVG_LOG_INFO_VAO (VKVG_LOG_INFO_VBO | VKVG_LOG_INFO_IBO) -#define VKVG_LOG_THREAD 0x00000080 +#define VKVG_LOG_THREAD 0x00000100 #define VKVG_LOG_DBG_ARRAYS 0x00001000 #define VKVG_LOG_STROKE 0x00010000 +#define VKVG_LOG_FONT 0x00100000 #define VKVG_LOG_FULL 0xffffffff #define VKVG_LOG_INFO 0x00008000 //(VKVG_LOG_INFO_PTS|VKVG_LOG_INFO_PATH|VKVG_LOG_INFO_CMD|VKVG_LOG_INFO_VAO) diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 7d619b1..2a48645 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -190,7 +190,7 @@ void _flush_chars_to_tex(VkvgDevice dev, vkvg_font_t* f) { return; tex_ref_t l = *f->texLines.elements[f->texLines.count - 1]; - LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n", f->penX, l.penY); + LOG(VKVG_LOG_FONT, "_flush_chars_to_tex pen(%d, %d)\n", f->penX, l.penY); vkWaitForFences(dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX); ResetFences(dev->vkDev, 1, &cache->uploadFence); @@ -271,10 +271,13 @@ void _font_buffer_destroy (vkvg_font_face_t* face) { void _font_face_destroy (FontFace face) { array_destroy_VkvgFont(&face->sizes); array_destroy_uint64_t(&face->queryHashes); - FT_Done_Face(face->face); mtx_destroy(&face->mutex); - array_del_FontFace(&face->fontBuffer->faces, face->index); + array_del_FontFace(&face->fontBuffer->faces, face); + if (face->fontBuffer->faces.count == 0) { + LOG(VKVG_LOG_FONT, "Done face: %s\n", face->face->family_name); + FT_Done_Face(face->face); + } free(face); } void _font_cache_destroy(VkvgDevice dev) { @@ -354,7 +357,7 @@ char_ref _prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) { #else FT_Error res = FT_Load_Glyph(f->face->face, gindex, FT_LOAD_RENDER); if (res) { - LOG(VKVG_LOG_ERR, "FT_Load_Glyph error 0x%x for glyph index %d\n", res, gindex); + LOG(VKVG_LOG_WARN, "FT_Load_Glyph error 0x%x for glyph index %d\n", res, gindex); FT_Load_Glyph(f->face->face, 0, FT_LOAD_RENDER); } #endif @@ -534,7 +537,7 @@ bool _tryResolveFontNameWithFontConfig(VkvgDevice dev, const char* fontString, F return true; } } - LOG(VKVG_LOG_INFO, "Font buffer without a face\n"); + LOG(VKVG_LOG_FONT, "Font buffer without a face\n"); } else { buffPtr = (FontBuffer)calloc(1, sizeof(vkvg_font_buffer_t)); buffPtr->fontPathHash = fontFileHash; @@ -564,17 +567,16 @@ bool _tryResolveFontNameWithFontConfig(VkvgDevice dev, const char* fontString, F } FontFace newFace = (FontFace)calloc(1, sizeof(vkvg_font_face_t)); - newFace->index = buffPtr->faces.count; newFace->fontBuffer = buffPtr; newFace->queryHashes = array_create_uint64_t(2); - array_add_uint64_t(&newFace->queryHashes, queryHash); if (dev->threadAware) mtx_init(&newFace->mutex, mtx_plain); #ifdef VKVG_USE_FREETYPE - if (cache->fontBuffers.count > 654 && cache->fontBuffers.elements[654] == buffPtr) { - printf("test\n"); - } + /*if (cache->fontBuffers.count > 654 && cache->fontBuffers.elements[654] == buffPtr && buffPtr->faces.count > 0) { + printf("= FontBuffer 654: face count = %d\n", buffPtr->faces.count); + fflush(stdout); + }*/ FT_Error res = FT_New_Memory_Face(cache->library, buffPtr->buffer, buffPtr->bufferSize, index, &newFace->face); if (res) { @@ -598,10 +600,11 @@ bool _tryResolveFontNameWithFontConfig(VkvgDevice dev, const char* fontString, F newSize.lineGap = roundf(newSize.scale * font->lineGap); #endif array_add_FontFace(&buffPtr->faces, newFace); + array_add_uint64_t(&newFace->queryHashes, queryHash); *face = newFace; + FcPatternDestroy(request); return true; } - FcPatternDestroy(request); return false; } #endif @@ -977,23 +980,25 @@ VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { font->face = face; #ifdef VKVG_USE_FREETYPE - if (!(face->face->face_flags & (FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_SFNT))) { + if (!(face->face->face_flags & FT_FACE_FLAG_SCALABLE) || !(face->face->face_flags & FT_FACE_FLAG_SFNT)) { char tmp[1024]; ft_face_flags_to_string (face->face->face_flags, tmp, 1024); - LOG(VKVG_LOG_ERR, "Unsuported font flags: %s\n", tmp); + LOG(VKVG_LOG_WARN, "Unsuported font flags: %s\n", tmp); free(font); return (VkvgFont)&_vkvg_status_null_pointer; + } else { + char tmp[1024]; + ft_face_flags_to_string (face->face->face_flags, tmp, 1024); + LOG(VKVG_LOG_FONT, "loading %s\n\tflags: %s\n", face->face->family_name, tmp); } if (!face->sizes.size) face->sizes = array_create_VkvgFont(5);//new face, FT_CHECK_RES(FT_New_Size (face->face, &font->ftSize)); FT_CHECK_RES(FT_Activate_Size(font->ftSize)); - - font->eltIndex = array_add_VkvgFont(&face->sizes, font); FT_CHECK_RES(FT_Set_Char_Size(face->face, 0, font->charSize, dev->hdpi, dev->vdpi)); - font->ftSize = face->face->size; + //font->ftSize = face->face->size; font->charLookup = (char_ref*)calloc(face->face->num_glyphs, sizeof(char_ref)); if (FT_IS_SCALABLE(face->face)) @@ -1015,6 +1020,8 @@ VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { #ifdef VKVG_USE_HARFBUZZ font->hb_font = hb_ft_font_create(face->face, NULL); #endif + array_add_VkvgFont(&face->sizes, font); + _init_next_line_in_tex_cache(dev, font); atomic_init(&font->references, 1); return font; @@ -1050,7 +1057,7 @@ void vkvg_font_destroy(VkvgFont font) { } array_destroy_TexRef(&font->texLines); - array_del_VkvgFont(&font->face->sizes , font->eltIndex); + array_del_VkvgFont(&font->face->sizes , font); if (font->face->sizes.count == 0) _font_face_destroy(font->face); diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index 85bb3bc..43a4604 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -174,6 +174,7 @@ DIAGNOSTIC_DISABLE_UNUSED CTOR_ARRAY(TexRef) CTOR_ARRAY(uint64_t) CTOR_ARRAY(VkvgFont) +ARRAY_DEL_ELT(VkvgFont) typedef struct _tex_page_t { array_TexRef lines; @@ -187,7 +188,6 @@ typedef struct _vkvg_font_face_t* FontFace; /* Font identification structure */ typedef struct _vkvg_font_face_t{ - uint32_t index; /* index in face list of containing font buffer */ FontBuffer fontBuffer; array_uint64_t queryHashes; #ifdef VKVG_USE_FREETYPE @@ -205,6 +205,7 @@ typedef struct _vkvg_font_face_t{ } vkvg_font_face_t; CTOR_ARRAY(FontFace) +ARRAY_DEL_ELT(FontFace) typedef struct _vkvg_font_buffer_t { uint64_t fontPathHash; @@ -222,7 +223,6 @@ typedef struct _vkvg_font_t { atomic_int references; // reference count FontFace face; - uint32_t eltIndex; // index in face->sizes[] array #ifdef VKVG_USE_FREETYPE FT_F26Dot6 charSize; /* Font size in Point as fixed float 26.6 */ FT_Size ftSize; /* FT size rec */ diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 3e7c7ca..8cc3db2 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -166,14 +166,22 @@ static void array_destroy_##type (array_##type* arr) { \ arr->elements = NULL; \ arr->count = 0; \ arr->size = 0; \ -} \ -static void array_del_##type (array_##type* arr, uint32_t index) { \ - if (index >= arr->count) \ +} +#define ARRAY_DEL_ELT(type) \ +static void array_del_##type (array_##type* arr, type elt) { \ + uint32_t i; \ + for (i = 0; i < arr->count; i++) { \ + if (arr->elements[i] == elt) \ + break; \ + } \ + if (i == arr->count) { \ return; \ - if (index < arr->count - 1) \ - memcpy (&arr->elements[index], &arr->elements[index + 1], arr->count - index - 1); \ + } \ + if (i < arr->count - 1) \ + memmove (&arr->elements[i], &arr->elements[i + 1], (arr->count - i - 1) * sizeof(type)); \ arr->count--; \ } + #define CTOR_ARRAY(type) CTOR_ARRAY_EXP(type,* 2) #include "vectors.h" diff --git a/tests/fonts/allfont.c b/tests/fonts/allfont.c index 747b068..b71b2a4 100644 --- a/tests/fonts/allfont.c +++ b/tests/fonts/allfont.c @@ -34,7 +34,7 @@ static const LocaleSample script_samples[] = { { "th", "เป็นมนุษย์สุดประเสริฐเลิศคุณค่า" }, // Thai { "hy", "Ֆիզիկոս Մկրտիչը օճառաջուր ցողելով բժշկում է գնդապետ Հայկի փքված ձախ թևը։" }, // Armenian { "agr", "Agatjai juuk tusha numpanum ijuaku jintanum pujawai" }, // Aguaruna (Latin script variation) - { "aa", "Afari fanta asat darih doro dahanik xisbisa" }, // Afar (Latin script variation) + //{ "aa", "Afari fanta asat darih doro dahanik xisbisa" }, // Afar (Latin script variation) { "bem", "Abantu bonse bafyalwa abalubuka no kulingana mu mucinshi" }, // Bemba (Bantu Latin script) { "pa", "ਘੁਮਿਆਰ ਨੇ ਮਿੱਟੀ ਚੁੱਕ ਕੇ ਇੱਕ ਬਹੁਤ ਹੀ ਸੁੰਦਰ ਘੜਾ ਬਣਾਇਆ।" }, // Punjabi (Gurmukhi script) { "te", "కచ్ఛపము మందగమనముతో చెరువు వైపు వెళుతోంది." }, // Telugu (Telugu script) @@ -65,7 +65,7 @@ static const LocaleSample script_samples[] = { void get_sample_by_fc_lang(const char* fc_lang, char* str) { const char* sample = NULL; if (fc_lang) { - for (int i = 1; i < 38; i++) { + for (int i = 1; i < 37; i++) { if (strncmp(fc_lang, script_samples[i].lang_code, strlen(script_samples[i].lang_code)) == 0) { sample = script_samples[i].sample_text; break; @@ -249,7 +249,7 @@ static void mouse_button_callback(GLFWwindow* window, int but, int state, int mo } int main(int argc, char* argv[]) { - vkh_log_level = VKVG_LOG_ERR; + vkh_log_level = VKVG_LOG_ERR | VKVG_LOG_WARN | VKVG_LOG_FONT; _parse_args(argc, argv); VkEngine e = vkengine_create ( @@ -262,7 +262,7 @@ int main(int argc, char* argv[]) { vkengine_set_scroll_callback(e, scroll_callback); vkvg_device_create_info_t info = { - 4, false, + 1, false, vkh_app_get_inst(e->app), vkh_device_get_phy(e->dev), vkh_device_get_vkdev(e->dev), |