diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-09 10:31:31 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-09 10:31:31 +0200 |
| commit | e47a052277e6c5b2c02df4e4c371a3bdd152513a (patch) | |
| tree | 8558a3e852390da030aa80fd1c35e54f9d5abce8 | |
| parent | 05723736c666d5bcd01eff28b7eb386694b46c02 (diff) | |
valgrind ok
| -rw-r--r-- | src/vkvg_context.c | 2 | ||||
| -rw-r--r-- | src/vkvg_fonts.c | 52 | ||||
| -rw-r--r-- | src/vkvg_fonts.h | 15 | ||||
| -rw-r--r-- | tests/fonts/allfont.c | 20 |
4 files changed, 62 insertions, 27 deletions
diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 2391fd7..29e9a6a 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -38,7 +38,7 @@ static const vkvg_context_save_t CTX_INIT = { }; void _init_ctx(VkvgContext ctx) { - memcpy((void*)&(ctx->curColor), (void*)&CTX_INIT, (void*)&(ctx->pattern) - (void*)&(ctx->curColor)); + memcpy((void*)&(ctx->curColor), (void*)&CTX_INIT, (void*)&(ctx->indCount) - (void*)&(ctx->curColor)); ctx->cmdStarted = false; ctx->curClipState = vkvg_clip_state_none; diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index ef8388b..0401a1c 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -13,19 +13,30 @@ //#include <stdio.h> #ifndef VKVG_USE_FREETYPE +#define STBTT_assert(x) ((void)0) #define STB_TRUETYPE_IMPLEMENTATION #include "stb_truetype.h" #endif static int defaultFontCharSize = 12 << 6; -static inline char* get_face_family_name (FontFace face) { +static inline const char* get_face_family_name (FontFace face) { #ifdef VKVG_USE_FREETYPE return face->face->family_name; #else - return "stb_face"; + int length = 0; + const char *name_ptr = stbtt_GetFontNameString(&face->stbInfo, &length, 1, 0, 0, 1); + return name_ptr; #endif } +static inline uint32_t get_face_glyph_count (FontFace face) { +#ifdef VKVG_USE_FREETYPE + return face->face->num_glyphs; +#else + return face->stbInfo.numGlyphs; +#endif +} + void _fonts_cache_create(VkvgDevice dev, const char* fontDirs) { _font_cache_t* cache = (_font_cache_t*)calloc(1, sizeof(_font_cache_t)); @@ -149,6 +160,8 @@ void _font_face_destroy (VkvgFont font) { hb_font_destroy(face->hb_font); #endif FT_Done_Face(face->face); + + _font_buffer_destroy(font->dev->fontCache, face->fontBuffer); } #endif free(face); @@ -167,7 +180,6 @@ void _font_cache_destroy(VkvgDevice dev) { vkvg_font_destroy(fonts[k]); } } - _font_buffer_destroy(cache, buffs[i]); } array_destroy_FontBuffer(&cache->fontBuffers); @@ -451,8 +463,8 @@ glyph_ref _put_glyph_in_cache(VkvgDevice dev, VkvgFont font, uint32_t gindex) { } vkvg_inline glyph_ref get_cached_glyph (VkvgDevice dev, VkvgFont font, uint32_t gIndex) { glyph_ref gr; - if (vkvg_unlikely (gIndex > font->face->face->num_glyphs)) { - LOGW("glyph index out of bounds: idx:%d glyphsCount: %ld\n", gIndex, font->face->face->num_glyphs); + if (vkvg_unlikely (gIndex > get_face_glyph_count(font->face))) { + LOGW("glyph index out of bounds: idx:%d glyphsCount: %d\n", gIndex, get_face_glyph_count(font->face)); if (!font->charLookup[0].texRef) // load default glyph 0 font->charLookup[0] = _put_glyph_in_cache(dev, font, 0); return font->charLookup[0]; // set default glyph for index @@ -498,7 +510,7 @@ bool try_create_font_face_from_path (VkvgDevice dev, const char *fontFile, int f if (try_get_font_buffer_from_path_hash(cache, fontFileHash, &buffPtr)) { for (int f = 0; f < buffPtr->faces.count; ++f) { - if (buffPtr->faces.elements[f]->face->face_index == faceIndex) { + if (buffPtr->faces.elements[f]->faceIndex == faceIndex) { *face = buffPtr->faces.elements[f]; return true; } @@ -528,6 +540,7 @@ bool try_create_font_face_from_path (VkvgDevice dev, const char *fontFile, int f fclose(file); if (readBytes != buffPtr->bufferSize) { LOGE("Error reading font file: %s\n", fontFile); + free(buffPtr->buffer); free(buffPtr); return false; } @@ -539,6 +552,7 @@ bool try_create_font_face_from_path (VkvgDevice dev, const char *fontFile, int f FontFace newFace = (FontFace)calloc(1, sizeof(vkvg_font_face_t)); newFace->fontBuffer = buffPtr; newFace->queryHashes = array_create_uint64_t(2); + newFace->faceIndex = faceIndex; #ifdef VKVG_USE_FREETYPE if (dev->threadAware) @@ -552,7 +566,9 @@ bool try_create_font_face_from_path (VkvgDevice dev, const char *fontFile, int f newFace->hb_font = hb_ft_font_create(newFace->face, NULL); #endif #else - int result = stbtt_InitFont(&newFace->stbInfo, buffPtr->buffer, 0); + int font_count = stbtt_GetNumberOfFonts(buffPtr->buffer); + int offset = stbtt_GetFontOffsetForIndex(buffPtr->buffer, faceIndex); + int result = stbtt_InitFont(&newFace->stbInfo, buffPtr->buffer, offset); if (!result) { LOGE("stbtt_InitFont error 0x%x creating face in %s at line %d\n", result, __FILE__, __LINE__); return false; @@ -589,14 +605,17 @@ bool try_get_or_create_font_face_from_query (VkvgDevice dev, const char* querySt FcPatternGetInteger (font, FC_INDEX, 0, &index); if (!try_create_font_face_from_path(dev, fontFile, index, face)) { - FcPatternDestroy(request); - return false; + goto exit_failed; } array_add_uint64_t (&(*face)->queryHashes, queryHash); FcPatternDestroy(request); + FcPatternDestroy(font); return true; } +exit_failed: + FcPatternDestroy(request); + FcPatternDestroy(font); #endif return false; } @@ -747,8 +766,10 @@ void text_run_init(VkvgContext ctx, const char* text, int length, VkvgText textR free(tmp); #endif +#ifdef VKVG_USE_FREETYPE if (ctx->dev->threadAware) mtx_unlock(&textRun->font->face->mutex); +#endif unsigned int string_width_in_pixels = 0; for (uint32_t i = 0; i < textRun->glyph_count; ++i) @@ -924,17 +945,17 @@ void* vkvg_font_get_face(VkvgFont font) { #endif } -VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, uint32_t pt26_6) { +VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize) { VkvgFont font = (VkvgFont)calloc(1, sizeof(vkvg_font_t)); if (!font) { LOGE("Create font failed, no memory\n"); return (VkvgFont)&_vkvg_status_no_memory; } - font->charSize = pt26_6; font->face = face; #ifdef VKVG_USE_FREETYPE + font->charSize = (uint32_t)(pointSize * 64.f);; 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); @@ -962,9 +983,10 @@ VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, uint32_t pt26_6) font->texLines = array_create_TexRef(2); #else + font->charSize = pointSize; stbtt_GetFontVMetrics(&face->stbInfo, &font->ascent, &font->descent, &font->lineGap); font->charLookup = (glyph_ref*)calloc(face->stbInfo.numGlyphs, sizeof(glyph_ref)); - font->scale = stbtt_ScaleForMappingEmToPixels(&face->stbInfo, font->charSize); + font->scale = stbtt_ScaleForMappingEmToPixels(&face->stbInfo, font->charSize * dev->vdpi / 72.f); font->height = roundf(font->scale * (font->ascent - font->descent + font->lineGap)); font->ascent = roundf(font->scale * font->ascent); font->descent = roundf(font->scale * font->descent); @@ -982,15 +1004,15 @@ VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, uint32_t pt26_6) } VkvgFont vkvg_font_create_from_file (VkvgDevice dev, const char* fontFilePath, int faceIndex, float pointSize) { - uint32_t pt26_6 = (uint32_t)(pointSize * 64.f); FontFace face = NULL; if (!try_create_font_face_from_path(dev, fontFilePath, faceIndex, &face) || !face) { return NULL; } - return _create_font_from_face(dev, face, pt26_6); + return _create_font_from_face(dev, face, pointSize); } VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { + uint32_t pt26_6 = (uint32_t)(pointSize * 64.f); VkvgFont font = NULL; FontFace face = NULL; @@ -1003,7 +1025,7 @@ VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { if (!face) return NULL; - return _create_font_from_face(dev, face, pt26_6); + return _create_font_from_face(dev, face, pointSize); } diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index a299859..25770c6 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -195,21 +195,20 @@ typedef struct _vkvg_font_face_t *FontFace; typedef struct _vkvg_font_face_t{ FontBuffer fontBuffer; array_uint64_t queryHashes; + int faceIndex; #ifdef VKVG_USE_FREETYPE FT_Face face; /* FreeType face*/ mtx_t mutex; /* Only one font size at a time may use this face */ +#else + stbtt_fontinfo stbInfo; /* stb_truetype structure */ + int ascent; /* unscalled stb font metrics */ + int descent; + int lineGap; #endif #ifdef VKVG_USE_HARFBUZZ hb_font_t* hb_font; /* HarfBuzz font instance*/ #endif array_VkvgFont sizes; /* loaded font size array */ - -#ifndef VKVG_USE_FREETYPE - stbtt_fontinfo stbInfo; /* stb_truetype structure */ - int ascent; /* unscalled stb font metrics */ - int descent; - int lineGap; -#endif } vkvg_font_face_t; CTOR_ARRAY(FontFace) @@ -237,7 +236,7 @@ typedef struct _vkvg_font_t { FT_F26Dot6 charSize; /* Font size in Point as fixed float 26.6 */ FT_Size ftSize; /* FT size rec */ #else - uint32_t charSize; /* Font size in pixel */ + float charSize; /* Font size in pixel */ float scale; /* scale factor for the given size */ int ascent; /* unscalled stb font metrics */ int descent; diff --git a/tests/fonts/allfont.c b/tests/fonts/allfont.c index 3fe67e3..efafa8a 100644 --- a/tests/fonts/allfont.c +++ b/tests/fonts/allfont.c @@ -1,11 +1,16 @@ #include "test.h" #include <fontconfig/fontconfig.h> + +#ifdef VKVG_USE_FREETYPE #include <ft2build.h> #include FT_FREETYPE_H #include FT_SFNT_NAMES_H #include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_IDS_H #include FT_MULTIPLE_MASTERS_H +#endif + +#include <string.h> float fontSize = 28.0f; int curFontStartIdx = 0; @@ -81,7 +86,7 @@ bool try_get_sample_by_fc_lang(const char* fc_lang, char* str) { return true; } - +#ifdef VKVG_USE_FREETYPE void convert_utf16be_to_utf8(const FT_Byte* src, FT_UInt src_len, char* dest, FT_UInt dest_max_len) { FT_UInt d_idx = 0; @@ -140,8 +145,10 @@ bool try_get_sample_string(FcPattern* font_entry, FT_Face face, char* str) { if (!lang_set) return false; FcStrList *lang_list = FcStrListCreate(lang_set); - if (!lang_list) + if (!lang_list) { + FcStrListDone(lang_list); return false; + } while ((lang = FcStrListNext(lang_list))) { if (!lang) @@ -151,11 +158,12 @@ bool try_get_sample_string(FcPattern* font_entry, FT_Face face, char* str) { } FcStrListDone(lang_list); + FcStrSetDestroy(lang_set); return true; } return false; } - +#endif void draw(VkvgSurface surfFont) { if (!font_database) @@ -190,9 +198,13 @@ void draw(VkvgSurface surfFont) { } vkvg_set_font (ctx, font); +#ifdef VKVG_USE_FREETYPE FT_Face face = (FT_Face)vkvg_font_get_face(font); if (!try_get_sample_string(font_entry, face, tmp)) sprintf(tmp, "%s : %s", family_name, style_variant); +#else + sprintf(tmp, "%s : %s", family_name, style_variant); +#endif vkvg_font_extents_t fe = {0}; vkvg_font_extents(ctx, &fe); @@ -220,6 +232,8 @@ void draw(VkvgSurface surfFont) { if (vkvg_font_status(font)) { printf("Font in error %s\n", file_path); fflush(stdout); + //clear font->dev ref to have clean vulkan termination + vkvg_device_destroy(device); continue; } |