summaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-27 09:00:37 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-27 09:00:37 +0100
commit7ff0e5d3085aa830f7fe3b32fb5ce1d9c265ae04 (patch)
tree6ad6c1f12c9af2d2d5893670f7ea292ae1dfbe5c /src
parentb51886c9fe9b591ff7f373c0719fbc51cf0a29e6 (diff)
vkvg_font_size_t holding pixel sized font, lightweight vkvg_font_t with only ptSizedev
Diffstat (limited to 'src')
-rw-r--r--src/svg/svg-parse.c2
-rw-r--r--src/vkvg_context.c10
-rw-r--r--src/vkvg_device.c1
-rw-r--r--src/vkvg_device_internal.c2
-rw-r--r--src/vkvg_fonts.c306
-rw-r--r--src/vkvg_fonts.h61
6 files changed, 226 insertions, 156 deletions
diff --git a/src/svg/svg-parse.c b/src/svg/svg-parse.c
index 6500fe4..748a397 100644
--- a/src/svg/svg-parse.c
+++ b/src/svg/svg-parse.c
@@ -1570,7 +1570,7 @@ void process_element(svg_context *const svg, SvgPresentationAttributes *const at
if (attribs->font_family_len > 0) {
char fam[1024];
sprintf(fam, "%.*s", attribs->font_family_len, attribs->font_family);
- font = vkvg_font_create(svg->surf, fam, attribs->font_size_pt);
+ font = vkvg_font_create(svg->dev, fam, attribs->font_size_pt);
vkvg_set_font(svg->ctx, font);
vkvg_font_destroy(font);
}
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 1711fbe..a9f470f 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -1238,13 +1238,13 @@ void vkvg_select_font_face(VkvgContext ctx, const char* name) {
if (vkvg_status(ctx))
return;
RECORD(ctx, VKVG_CMD_SET_FONT_FACE, name);
- vkvg_set_font(ctx, vkvg_font_create(ctx->pSurf, name, 12));
+ vkvg_set_font(ctx, vkvg_font_create(ctx->dev, name, 12));
}
void vkvg_load_font_from_path(VkvgContext ctx, const char* path, uint32_t size) {
if (vkvg_status(ctx))
return;
RECORD(ctx, VKVG_CMD_SET_FONT_PATH, name);
- vkvg_set_font(ctx, vkvg_font_create_from_file(ctx->pSurf, path, 0, size));
+ vkvg_set_font(ctx, vkvg_font_create_from_file(ctx->dev, path, 0, size));
}
void vkvg_set_font_size(VkvgContext ctx, uint32_t size) {
if (vkvg_status(ctx))
@@ -1276,7 +1276,7 @@ void vkvg_text_extents(VkvgContext ctx, const char* text, vkvg_text_extents_t* e
void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) {
if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
return;
- _font_cache_font_extents(ctx->currentFont, extents);
+ _font_cache_font_extents(ctx, extents);
}
void vkvg_show_text(VkvgContext ctx, const char* text) {
if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
@@ -1295,7 +1295,7 @@ VkvgText vkvg_text_create(VkvgContext ctx, const char* text) {
LOGE("vkvg_text_create error, no memory\n");
return NULL;
}
- text_run_init(tr, ctx->currentFont, ctx->textDirection, text, -1);
+ text_run_init(tr, ctx, text, -1);
return tr;
}
VkvgText vkvg_text_create_with_length(VkvgContext ctx, const char* text, uint32_t length) {
@@ -1306,7 +1306,7 @@ VkvgText vkvg_text_create_with_length(VkvgContext ctx, const char* text, uint32_
LOGE("vkvg_text_create error, no memory\n");
return NULL;
}
- text_run_init(tr, ctx->currentFont, ctx->textDirection, text, length);
+ text_run_init(tr, ctx, text, length);
return tr;
}
uint32_t vkvg_text_get_glyph_count(VkvgText textRun) {
diff --git a/src/vkvg_device.c b/src/vkvg_device.c
index 2a1535a..60b7e7d 100644
--- a/src/vkvg_device.c
+++ b/src/vkvg_device.c
@@ -299,6 +299,7 @@ VkvgDevice vkvg_device_create(vkvg_device_create_info_t* info) {
enabledExtsCount = 0;
if (vkvg_get_required_device_extensions(pi->phy, enabledExts, &enabledExtsCount) != VKVG_STATUS_SUCCESS) {
+ LOGE("CREATE Device failed, vkvg_get_required_device_extensions failure.\n");
dev->status = VKVG_STATUS_DEVICE_ERROR;
vkh_app_free_phyinfos(phyCount, phys);
vkh_app_destroy(app);
diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c
index 0697f95..6c6d160 100644
--- a/src/vkvg_device_internal.c
+++ b/src/vkvg_device_internal.c
@@ -243,7 +243,7 @@ void _device_check_best_image_tiling(VkvgDevice dev, VkFormat format) {
}
if (dev->pngStagFormat == VK_FORMAT_UNDEFINED)
- LOG(VKVG_LOG_DEBUG, "vkvg create device warning: no suitable image format for png write\n");
+ LOGW("vkvg create device warning: no suitable image format for png write\n");
dev->stencilFormat = VK_FORMAT_UNDEFINED;
dev->stencilAspectFlag = VK_IMAGE_ASPECT_STENCIL_BIT;
diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c
index 2e3dfa3..e8eb465 100644
--- a/src/vkvg_fonts.c
+++ b/src/vkvg_fonts.c
@@ -51,15 +51,26 @@ do { \
}
#define FT_CHECK_RES(f) \
{ \
- FT_Error res = (f); \
- if (res) { \
- char tmp[1024]; \
- ft_face_flags_to_string (face->face->face_flags, tmp, 1024); \
- LOGE("FreeType error is 0x%x in %s at line %d, flags: %s\n", res, __FILE__, __LINE__, tmp);\
- free(font); \
- return (VkvgFont)&_vkvg_status_null_pointer; \
+ FT_Error res = (f); \
+ if (res) { \
+ char tmp[1024]; \
+ ft_face_flags_to_string (face->face->face_flags, tmp, 1024); \
+ LOGE("FreeType error is 0x%x in %s at line %d, flags: %s\n", res, __FILE__, __LINE__, tmp);\
+ free(font); \
+ return (VkvgFont)&_vkvg_status_null_pointer; \
} \
}
+#define FT_CHECK_SIZE(f) \
+{ \
+ FT_Error res = (f); \
+ if (res) { \
+ char tmp[1024]; \
+ ft_face_flags_to_string (face->face->face_flags, tmp, 1024); \
+ LOGE("FreeType error is 0x%x in %s at line %d, flags: %s\n", res, __FILE__, __LINE__, tmp);\
+ free(fntsize); \
+ return false; \
+ } \
+}
#else
#define STBTT_assert(x) ((void)0)
#define STB_TRUETYPE_IMPLEMENTATION
@@ -95,6 +106,7 @@ void _fonts_cache_update_font_descriptor_set (VkvgDevice dev) {
vkUpdateDescriptorSets(dev->vkDev, 1, &writeDescriptorSet, 0, NULL);
}
void _fonts_cache_create(VkvgDevice dev, const char* fontDirs) {
+ LOG(VKVG_LOG_FONT, "Font cache create\n");
font_cache_t* cache = (font_cache_t*)calloc(1, sizeof(font_cache_t));
dev->fontCache = cache;
@@ -233,7 +245,8 @@ void _fonts_cache_create(VkvgDevice dev, const char* fontDirs) {
#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
vkh_device_set_object_name(dev->vkhDev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)cache->descriptorPool,
"Font cache Descriptor Pool");
- vkh_device_set_object_name(dev->vkhDev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)cache->dsFont, "Cache DescSet FONT");
+ vkh_device_set_object_name(dev->vkhDev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)cache->dsFont, "Font Cache DescSet");
+ vkh_device_set_object_name(dev->vkhDev, VK_OBJECT_TYPE_BUFFER, (uint64_t)cache->buff.buffer, "Font Cache Staging buff");
#endif
}
void _font_buffer_destroy (font_cache_t* cache, FontBuffer fontBuffer) {
@@ -243,10 +256,10 @@ void _font_buffer_destroy (font_cache_t* cache, FontBuffer fontBuffer) {
array_del_FontBuffer(&cache->fontBuffers, fontBuffer);
free(fontBuffer);
}
-void _font_face_destroy (VkvgFont font) {
+void _font_face_destroy (FontSize font) {
FontFace face = font->face;
LOG(VKVG_LOG_FONT, "FontFace destroy: %s\n", get_face_family_name(face));
- array_destroy_VkvgFont(&face->sizes);
+ array_destroy_FontSize(&face->sizes);
array_destroy_uint64_t(&face->queryHashes);
array_del_FontFace(&face->fontBuffer->faces, face);
@@ -264,7 +277,31 @@ void _font_face_destroy (VkvgFont font) {
}
free(face);
}
+void _font_size_destroy (FontSize font) {
+#ifdef VKVG_USE_FREETYPE
+ FT_Done_Size(font->ftSize);
+ if (font->coords)
+ free(font->coords);
+#endif
+
+ for (int i = 0; i < font->texLines.count; ++i) {
+ LOG(VKVG_LOG_FONT, "\treleased line %d of page %d\n", i, font->texLines.elements[i]->pageIdx);
+ font->texLines.elements[i]->released = true;
+ }
+ array_destroy_TexRef(&font->texLines);
+
+ array_del_FontSize(&font->face->sizes , font);
+
+ if (font->face->sizes.count == 0)
+ _font_face_destroy(font);
+ free(font->charLookup);
+
+ vkvg_device_destroy(font->dev);
+ free(font);
+ font = NULL;
+}
void _font_cache_destroy(VkvgDevice dev) {
+ LOG(VKVG_LOG_FONT, "Font cache destroy\n");
font_cache_t* cache = (font_cache_t*)dev->fontCache;
free(cache->hostBuff);
@@ -273,10 +310,10 @@ void _font_cache_destroy(VkvgDevice dev) {
for (int i = 0; i < cache->fontBuffers.count; ++i) {
FontFace* faces = buffs[i]->faces.elements;
for (int j = 0; j < buffs[i]->faces.count; ++j) {
- VkvgFont *fonts = faces[j]->sizes.elements;
+ FontSize *fonts = faces[j]->sizes.elements;
for (int k = 0; k < faces[j]->sizes.count; ++k) {
//while (vkvg_font_get_reference_count(fonts[k]) > 0)
- vkvg_font_destroy(fonts[k]);
+ _font_size_destroy (fonts[k]);
}
}
}
@@ -383,7 +420,7 @@ void _increase_font_tex_array(VkvgDevice dev) {
}
// flush font stagging buffer to cache texture array
// Trigger stagging buffer to be uploaded in font cache. Groupping upload improve performances.
-void _flush_chars_to_tex(VkvgFont f) {
+void _flush_chars_to_tex(FontSize f) {
font_cache_t* cache = f->dev->fontCache;
if (cache->stagingX == 0) // no char in stagging buff to flush
return;
@@ -428,7 +465,7 @@ void _flush_chars_to_tex(VkvgFont f) {
}
/// Start a new line in font cache, increase texture layer count if needed.
-void _init_next_line_in_tex_cache(VkvgFont f) {
+void _init_next_line_in_tex_cache(FontSize f) {
font_cache_t* cache = f->dev->fontCache;
for (int i = 0; i < cache->texPages.count; ++i) {
@@ -478,7 +515,7 @@ void _init_next_line_in_tex_cache(VkvgFont f) {
UNLOCK_FONTCACHE(ctx->dev)
}*/
// create a new char entry and put glyph in stagging buffer, ready for upload.
-glyph_ref _put_glyph_in_cache(VkvgDevice dev, VkvgFont font, uint32_t gindex) {
+glyph_ref _put_glyph_in_cache(VkvgDevice dev, FontSize font, uint32_t gindex) {
#ifdef VKVG_USE_FREETYPE
#if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING)
FT_CHECK_RESULT(FT_Load_Glyph(f->face, gindex, FT_LOAD_TARGET_NORMAL));
@@ -493,7 +530,7 @@ glyph_ref _put_glyph_in_cache(VkvgDevice dev, VkvgFont font, uint32_t gindex) {
res = FT_Load_Glyph(font->face->face, 0, FT_LOAD_RENDER);
if (res) {
LOGE("Fatal: FT_Load_Glyph error 0x%x for default glyph 0\n", res);
- font->status = VKVG_STATUS_INVALID_FONT;
+ //font->status = VKVG_STATUS_INVALID_FONT;
return (glyph_ref) {0};
}
}
@@ -563,7 +600,7 @@ glyph_ref _put_glyph_in_cache(VkvgDevice dev, VkvgFont font, uint32_t gindex) {
dev->fontCache->stagingX += bmpPixelWidth;
return cr;
}
-vkvg_inline glyph_ref get_cached_glyph (VkvgDevice dev, VkvgFont font, uint32_t gIndex) {
+vkvg_inline glyph_ref get_cached_glyph (VkvgDevice dev, FontSize font, uint32_t gIndex) {
glyph_ref gr;
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));
@@ -768,31 +805,112 @@ exit_failed:
#endif
return false;
}
-bool try_get_font_size (FontFace face, uint32_t pt26_6, signed long* coords, VkvgFont *font) {
- *font = NULL;
+
+bool try_get_or_create_font_size (VkvgSurface surf, VkvgFont font) {
+ if (font->curSize != NULL)
+ return true;
+ FontFace face = font->face;
+ uint32_t pxSize = (font->ptSize * surf->vdpi + 2304) / 4608;
+
for (int i = 0; i < face->sizes.count; ++i) {
- VkvgFont f = face->sizes.elements[i];
- if (f->charSize == pt26_6) {
+ FontSize f = face->sizes.elements[i];
+ if (f->pxSize == pxSize) {
#ifdef VKVG_USE_FREETYPE
- if (coords) {
+ /*if (coords) {
for (int axe = 0; axe < face->numAxis; ++axe) {
if (f->coords[axe] != coords[axe])
return false;
}
free(coords);//coords matche, free new coords
- }
+ }*/
#endif
- *font = f;
+ font->curSize = f;
return true;
}
}
- return false;
+
+ FontSize fntsize = (FontSize)calloc(1, sizeof(vkvg_font_size_t));
+ if (!fntsize) {
+ LOGE("Create font size failed, no memory\n");
+ return false;
+ }
+ fntsize->face = face;
+ VkvgDevice dev = surf->dev;
+
+#ifdef VKVG_USE_FREETYPE
+ if (dev->threadAware)
+ mtx_lock(&face->mutex);
+ /* if (face->numAxis && coords)
+ font->coords = coords;*/
+
+ 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);
+ LOGW("Unsuported font flags: %s\n", tmp);
+ if (dev->threadAware)
+ mtx_lock(&face->mutex);
+ free(fntsize);
+ return false;
+ } 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_FontSize(5);//new face,
+
+ FT_CHECK_SIZE(FT_New_Size (face->face, &fntsize->ftSize));
+ FT_CHECK_SIZE(FT_Activate_Size(fntsize->ftSize));
+ //TODO:handle fixed sizes
+ FT_CHECK_SIZE(FT_Set_Pixel_Sizes(face->face, 0, pxSize));
+
+ /*if (font->coords) {
+ FT_Set_Var_Design_Coordinates(face->face, font->face->numAxis, font->coords);
+ font->face->coords = font->coords;
+ }*/
+#ifdef VKVG_USE_HARFBUZZ
+ hb_font_t* hbf = face->hb_font;
+ hb_ft_font_changed(hbf);
+ hb_font_set_ppem(hbf, fntsize->ftSize->metrics.x_ppem, fntsize->ftSize->metrics.y_ppem);
+#endif
+
+ fntsize->charLookup = (glyph_ref*)calloc(face->face->num_glyphs, sizeof(glyph_ref));
+
+ if (FT_IS_SCALABLE(face->face))
+ fntsize->height = face->face->size->metrics.height >> 6;
+ else
+ fntsize->height = face->face->height >> 6;
+
+ fntsize->texLines = array_create_TexRef(2);
+
+ if (dev->threadAware)
+ mtx_lock(&face->mutex);
+#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 * surf->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);
+ font->lineGap = roundf(font->scale * font->lineGap);
+#endif
+ array_add_FontSize(&face->sizes, fntsize);
+
+ fntsize->dev = dev;
+ vkvg_device_reference(fntsize->dev);
+
+ _init_next_line_in_tex_cache(fntsize);
+
+ font->curSize = fntsize;
+ return true;
}
+
#ifdef VKVG_USE_HARFBUZZ
// Get harfBuzz buffer for provided text.
hb_buffer_t* _get_hb_buffer(VkvgText textRun, const char* text, int length) {
- VkvgFont font = textRun->font;
+ FontSize font = textRun->font;
hb_buffer_t* buf = hb_buffer_create();
hb_buffer_add_utf8 (buf, text, length, 0, length);
hb_buffer_guess_segment_properties (buf);
@@ -808,7 +926,7 @@ hb_buffer_t* _get_hb_buffer(VkvgText textRun, const char* text, int length) {
return buf;
}
#endif
-void _font_lock_size (VkvgFont font) {
+void _font_lock_size (FontSize font) {
#ifdef VKVG_USE_FREETYPE
FT_Face face = font->face->face;
if (face->size != font->ftSize || font->face->coords != font->coords) {
@@ -829,7 +947,10 @@ void _font_lock_size (VkvgFont font) {
}
// retrieve global font extends of context's current font as defined by FreeType
-void _font_cache_font_extents(VkvgFont font, vkvg_font_extents_t* extents) {
+void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) {
+ VkvgFont font = ctx->currentFont;
+ if (!try_get_or_create_font_size(ctx->pSurf, font))
+ return;
#ifdef VKVG_USE_FREETYPE
FT_Face face = font->face->face;
/*_font_lock_size(ctx, font);
@@ -839,7 +960,7 @@ void _font_cache_font_extents(VkvgFont font, vkvg_font_extents_t* extents) {
}*/
//FT_BBox* bbox = &face->bbox;
//FT_Size_Metrics* metrics = &face->size->metrics;
- FT_Size_Metrics* metrics = &font->ftSize->metrics;
+ FT_Size_Metrics* metrics = &font->curSize->ftSize->metrics;
extents->ascent = (float)(FT_MulFix(face->ascender, metrics->y_scale) >> 6); // metrics->ascender >> 6;
extents->descent = -(float)(FT_MulFix(face->descender, metrics->y_scale) >> 6); // metrics->descender >> 6;
@@ -867,7 +988,7 @@ void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkv
}
vkvg_text_run_t tr = {0};
- text_run_init(&tr, ctx->currentFont, ctx->textDirection, text, length);
+ text_run_init(&tr, ctx, text, length);
if (ctx->status)
return;
@@ -879,7 +1000,7 @@ void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkv
// text is expected as utf8 encoded
void _font_cache_show_text(VkvgContext ctx, const char* text) {
vkvg_text_run_t tr = {0};
- text_run_init(&tr, ctx->currentFont, ctx->textDirection, text, -1);
+ text_run_init(&tr, ctx, text, -1);
if (ctx->status)
return;
@@ -890,10 +1011,13 @@ void _font_cache_show_text(VkvgContext ctx, const char* text) {
}
// if length is < 0, text must be null terminated, else it contains glyph count
-void text_run_init(VkvgText textRun, VkvgFont font, vkvg_direction_t textDirection, const char* text, int length) {
- textRun->font = font;
- textRun->textDirection = textDirection;
- vkvg_font_reference (textRun->font);
+void text_run_init(VkvgText textRun, VkvgContext ctx, const char* text, int length) {
+ VkvgFont font = ctx->currentFont;
+
+ try_get_or_create_font_size(ctx->pSurf, font);
+
+ textRun->font = font->curSize;
+ textRun->textDirection = ctx->textDirection;
_font_lock_size(textRun->font);
@@ -959,7 +1083,7 @@ void text_run_term(VkvgText textRun) {
if (textRun->glyph_count > 0)
free(textRun->glyphs);
#endif
- vkvg_font_destroy(textRun->font);
+ //vkvg_font_destroy(textRun->font);
}
void text_run_render(VkvgText tr, VkvgContext ctx) {
@@ -970,7 +1094,7 @@ void text_run_render(VkvgText tr, VkvgContext ctx) {
vkvg_glyph_info_t* glyph_info = tr->glyphs;
glyph_count = tr->glyph_count;
#endif
- VkvgFont f = tr->font;
+ FontSize f = tr->font;
Vertex v = {{0}, ctx->curColor, {0, 0, -1}};
vec2 pen = {0, 0};
@@ -983,8 +1107,8 @@ void text_run_render(VkvgText tr, VkvgContext ctx) {
for (uint32_t i = 0; i < glyph_count; ++i) {
glyph_ref cr = get_cached_glyph(dev, f, glyph_info[i].codepoint);
- if (vkvg_unlikely (f->status))
- break;
+ /*if (vkvg_unlikely (f->status))
+ break;*/
vec2 p0 = {pen.x + cr.bmpDiff.x + (tr->glyphs[i].x_offset >> 6),
pen.y - cr.bmpDiff.y + (tr->glyphs[i].y_offset >> 6)};
@@ -1056,7 +1180,9 @@ void* vkvg_font_get_face(VkvgFont font) {
#endif
}
-VkvgFont _create_font_from_face (VkvgSurface surf, FontFace face, float pointSize, signed long* coords) {
+
+
+VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize, signed long* coords) {
VkvgFont font = (VkvgFont)calloc(1, sizeof(vkvg_font_t));
if (!font) {
LOGE("Create font failed, no memory\n");
@@ -1064,99 +1190,38 @@ VkvgFont _create_font_from_face (VkvgSurface surf, FontFace face, float pointSiz
}
font->face = face;
- VkvgDevice dev = surf->dev;
-
-#ifdef VKVG_USE_FREETYPE
- if (dev->threadAware)
- mtx_lock(&font->face->mutex);
- if (face->numAxis && coords)
- font->coords = coords;
- 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);
- LOGW("Unsuported font flags: %s\n", tmp);
- if (dev->threadAware)
- mtx_lock(&font->face->mutex);
- 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));
- //TODO:handle fixed sizes
- FT_CHECK_RES(FT_Set_Char_Size(face->face, 0, font->charSize, surf->hdpi, surf->vdpi));
- if (font->coords) {
- FT_Set_Var_Design_Coordinates(face->face, font->face->numAxis, font->coords);
- font->face->coords = font->coords;
- }
-#ifdef VKVG_USE_HARFBUZZ
- hb_font_t* hbf = font->face->hb_font;
- hb_ft_font_changed(hbf);
- hb_font_set_ppem(hbf, font->ftSize->metrics.x_ppem, font->ftSize->metrics.y_ppem);
-#endif
-
- font->charLookup = (glyph_ref*)calloc(face->face->num_glyphs, sizeof(glyph_ref));
-
- if (FT_IS_SCALABLE(face->face))
- font->height = face->face->size->metrics.height >> 6;
- else
- font->height = face->face->height >> 6;
-
- font->texLines = array_create_TexRef(2);
-
- if (dev->threadAware)
- mtx_lock(&font->face->mutex);
-#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 * surf->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);
- font->lineGap = roundf(font->scale * font->lineGap);
-#endif
- array_add_VkvgFont(&face->sizes, font);
-
font->dev = dev;
+ font->ptSize = (uint32_t)(pointSize * 64.f);
+
vkvg_device_reference(font->dev);
- _init_next_line_in_tex_cache(font);
atomic_init(&font->references, 1);
-
return font;
}
-VkvgFont vkvg_font_create_from_file (VkvgSurface surf, const char* fontFilePath, int faceIndex, float pointSize) {
+VkvgFont vkvg_font_create_from_file (VkvgDevice dev, const char* fontFilePath, int faceIndex, float pointSize) {
FontFace face = NULL;
- if (!try_create_font_face_from_path(surf->dev, fontFilePath, faceIndex, &face) || !face) {
+ if (!try_create_font_face_from_path(dev, fontFilePath, faceIndex, &face) || !face) {
return NULL;
}
- return _create_font_from_face(surf, face, pointSize, NULL);
+ return _create_font_from_face(dev, face, pointSize, NULL);
}
-VkvgFont vkvg_font_create (VkvgSurface surf, const char* query, float pointSize) {
- uint32_t pt26_6 = (uint32_t)(pointSize * 64.f);
+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;
signed long* coords = NULL;
unsigned int numAxis = 0;
- if (try_get_or_create_font_face_from_query(surf->dev, query, &face, &coords)) {
- if (try_get_font_size(face, pt26_6, coords, &font)) {
+ if (try_get_or_create_font_face_from_query(dev, query, &face, &coords)) {
+ /*if (try_get_font_size(face, pt26_6, coords, &font)) {
vkvg_font_reference(font);
return font;
- }
+ }*/
}
if (!face)
return NULL;
- return _create_font_from_face(surf, face, pointSize, coords);
+ return _create_font_from_face(dev, face, pointSize, coords);
}
VkvgFont vkvg_font_reference(VkvgFont font) {
if (!vkvg_font_status(font))
@@ -1175,23 +1240,6 @@ void vkvg_font_destroy(VkvgFont font) {
if (atomic_fetch_sub_explicit(&font->references, 1, memory_order_acq_rel) != 1)
return;
LOG(VKVG_LOG_FONT, "Font destroy: %s\n", get_face_family_name(font->face));
-#ifdef VKVG_USE_FREETYPE
- FT_Done_Size(font->ftSize);
- if (font->coords)
- free(font->coords);
-#endif
-
- for (int i = 0; i < font->texLines.count; ++i) {
- LOG(VKVG_LOG_FONT, "\treleased line %d of page %d\n", i, font->texLines.elements[i]->pageIdx);
- font->texLines.elements[i]->released = true;
- }
- array_destroy_TexRef(&font->texLines);
-
- array_del_VkvgFont(&font->face->sizes , font);
-
- if (font->face->sizes.count == 0)
- _font_face_destroy(font);
- free(font->charLookup);
vkvg_device_destroy(font->dev);
free(font);
diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h
index 9ef3da0..5395761 100644
--- a/src/vkvg_fonts.h
+++ b/src/vkvg_fonts.h
@@ -152,8 +152,12 @@ static inline int get_utf8_char_length(uint8_t first_byte) {
return utf8_len_table[first_byte];
}
-typedef struct _tex_ref_t tex_ref_t;
-typedef struct _tex_ref_t* TexRef;
+typedef struct _tex_ref_t tex_ref_t;//?
+typedef struct _tex_ref_t *TexRef;
+typedef struct _vkvg_font_buffer_t *FontBuffer;
+typedef struct _vkvg_font_face_t *FontFace;
+typedef struct _vkvg_font_size_t *FontSize;
+
// texture coordinates of one character in font cache array texture.
typedef struct _char_ref {
TexRef texRef; /* glyph bitmap ref */
@@ -182,6 +186,9 @@ CTOR_ARRAY(uint64_t)
CTOR_ARRAY(VkvgFont)
ARRAY_DEL_ELT(VkvgFont)
+CTOR_ARRAY(FontSize)
+ARRAY_DEL_ELT(FontSize)
+
typedef struct _tex_page_t {
array_TexRef lines;
float penY;
@@ -189,9 +196,6 @@ typedef struct _tex_page_t {
CTOR_ARRAY(tex_page_t)
-typedef struct _vkvg_font_buffer_t *FontBuffer;
-typedef struct _vkvg_font_face_t *FontFace;
-
/* Font identification structure */
typedef struct _vkvg_font_face_t{
FontBuffer fontBuffer;
@@ -211,7 +215,7 @@ typedef struct _vkvg_font_face_t{
#ifdef VKVG_USE_HARFBUZZ
hb_font_t* hb_font; /* HarfBuzz font instance*/
#endif
- array_VkvgFont sizes; /* loaded font size array */
+ array_FontSize sizes; /* loaded font size array */
} vkvg_font_face_t;
CTOR_ARRAY(FontFace)
@@ -229,14 +233,11 @@ ARRAY_DEL_ELT(FontBuffer)
DIAGNOSTIC_RESTORE_UNUSED
-typedef struct _vkvg_font_t {
- vkvg_status_t status;
- atomic_int references; // reference count
-
+typedef struct _vkvg_font_size_t {
FontFace face;
VkvgDevice dev; // to access font cache when required
+ float pxSize; // self computed pix size from pt with surface dpy used for size matching.
#ifdef VKVG_USE_FREETYPE
- FT_F26Dot6 charSize; /* Font size in Point as fixed float 26.6 */
FT_Size ftSize; /* FT size rec */
signed long* coords; /* Variable fonts axes coordinates */
#else
@@ -246,14 +247,32 @@ typedef struct _vkvg_font_t {
int descent;
int lineGap;
#endif
-
glyph_ref* charLookup;/* Lookup table of characteres in cache, if not found, upload is queued*/
array_TexRef texLines; /* texture reference where to add new glyph bmp's in cache */
int penX; /* Current X in cache for next char addition */
float height; /* Height in pixel */
+} vkvg_font_size_t;
+
+typedef struct _vkvg_font_t {
+ vkvg_status_t status;
+ atomic_int references; // reference count
+
+ FontFace face;
+ VkvgDevice dev; // to access font cache when required
+#ifdef VKVG_USE_FREETYPE
+ FT_F26Dot6 ptSize; /* Font size in Point as fixed float 26.6 */
+#else
+ float charSize; /* Font size in pixel */
+ float scale; /* scale factor for the given size */
+ int ascent; /* unscalled stb font metrics */
+ int descent;
+ int lineGap;
+#endif
+ vkvg_font_size_t* curSize;
} vkvg_font_t;
+
// Font cache global structure, entry point for all font related operations.
typedef struct _font_cache_t {
#ifdef VKVG_USE_FREETYPE
@@ -261,20 +280,20 @@ typedef struct _font_cache_t {
#else
#endif
#ifdef VKVG_USE_FONTCONFIG
- FcConfig* config; /* Font config, used to find font files by font names*/
+ FcConfig* config; /* Font config, used to find font files by font names*/
//FcPattern* fcPattern; /* patter used for all Font config queries */
- FcObjectSet* fcReqElts; /* Font config requested metadata elements */
+ FcObjectSet* fcReqElts; /* Font config requested metadata elements */
#endif
- int stagingX; /* x pen in host buffer */
- uint8_t* hostBuff; /* host memory where bitmaps are first loaded */
+ int stagingX; /* x pen in host buffer */
+ uint8_t* hostBuff; /* host memory where bitmaps are first loaded */
VkCommandBuffer cmd; /* vulkan command buffer for font textures upload */
vkh_buffer_t buff; /* stagin buffer */
VkhImage texture; /* 2d array texture used by contexts to draw characteres */
VkDescriptorPool descriptorPool;
- VkDescriptorSet dsFont; /* fonts glyphs texture atlas descriptor set */
+ VkDescriptorSet dsFont; /* fonts glyphs texture atlas descriptor set */
VkFormat texFormat; /* Format of the fonts texture array */
uint8_t texPixelSize; /* Size in byte of a single pixel in a font texture */
@@ -294,7 +313,7 @@ typedef struct _font_cache_t {
// Precompute everything necessary to measure and draw one line of text, usefull to draw the same text multiple times.
typedef struct _vkvg_text_run_t {
- VkvgFont font; /* vkvg font structure pointer */
+ FontSize font; /* vkvg font structure pointer */
vkvg_direction_t textDirection; /* horizontal or vertical */
vkvg_text_extents_t extents; /* store computed text extends */
const char* text; /* utf8 char array of text*/
@@ -313,10 +332,12 @@ void _font_cache_destroy(VkvgDevice dev);
bool _font_cache_load_font_file_in_memory(vkvg_font_face_t* fontId);
void _font_cache_show_text(VkvgContext ctx, const char* text);
void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkvg_text_extents_t* extents);
-void _font_cache_font_extents(VkvgFont font, vkvg_font_extents_t* extents);
+void _font_cache_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents);
void _font_cache_update_context_descset(VkvgContext ctx);
-void text_run_init(VkvgText textRun, VkvgFont font, vkvg_direction_t textDirection, const char* text, int length);
+void _font_size_destroy (FontSize font);
+
+void text_run_init(VkvgText textRun, VkvgContext ctx, const char* text, int length);
void text_run_term(VkvgText textRun);
void text_run_render(VkvgText tr, VkvgContext ctx); // Draw text run
#endif