summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-07 22:29:57 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-07 22:29:57 +0200
commit748bd9b738df2a789811a02c76bacd4855959d65 (patch)
tree7a8f55d98ef6bc72d214fcd67c4298eb1a7cfa3f
parent1d1d49ea314f2e5a644b1ed9ac4908234a02e3de (diff)
call ft_fone_face only if no more memory face is in use, debug array_del by reference
-rw-r--r--include/vkvg.h16
-rw-r--r--src/vkvg_fonts.c41
-rw-r--r--src/vkvg_fonts.h4
-rw-r--r--src/vkvg_internal.h18
-rw-r--r--tests/fonts/allfont.c8
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),