diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-06 09:43:45 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-06 09:43:45 +0200 |
| commit | 79498029de5618cc2597b6cc3341f0e35725fb68 (patch) | |
| tree | 31ff357cd4e3b48d7128468763be47cd6c0c9d28 | |
| parent | b5d0777c0f456ec7c830a3129d4618f947115c05 (diff) | |
char_ref_t texRef index for dynamic y offset and page in texture array
| -rw-r--r-- | src/vkvg_fonts.c | 40 | ||||
| -rw-r--r-- | src/vkvg_fonts.h | 14 |
2 files changed, 31 insertions, 23 deletions
diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 05eff90..b003615 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -205,7 +205,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", l.penX, l.penY); + LOG(VKVG_LOG_INFO, "_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); @@ -224,7 +224,7 @@ void _flush_chars_to_tex(VkvgDevice dev, vkvg_font_t* f) { VkBufferImageCopy bufferCopyRegion = {.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, l.pageIdx, 1}, .bufferRowLength = FONT_PAGE_SIZE, .bufferImageHeight = l.height, - .imageOffset = {l.penX, l.penY, 0}, + .imageOffset = {f->penX, l.penY, 0}, .imageExtent = {cache->stagingX, l.height, 1}}; vkCmdCopyBufferToImage(cache->cmd, cache->buff.buffer, vkh_image_get_vkimage(cache->texture), @@ -238,7 +238,7 @@ void _flush_chars_to_tex(VkvgDevice dev, vkvg_font_t* f) { _device_submit_cmd(dev, &cache->cmd, cache->uploadFence); - l.penX += cache->stagingX; + f->penX += cache->stagingX; f->texLines.elements[f->texLines.count - 1] = l; cache->stagingX = 0; @@ -253,7 +253,7 @@ void _init_next_line_in_tex_cache(VkvgDevice dev, vkvg_font_t* f) { if (cache->pensY[i] + l->height >= FONT_PAGE_SIZE) continue; l->pageIdx = (unsigned char)i; - l->penX = 0; + f->penX = 0; l->penY = cache->pensY[i]; cache->pensY[i] += l->height; return; @@ -363,7 +363,7 @@ void _font_cache_update_context_descset(VkvgContext ctx) { UNLOCK_FONTCACHE(ctx->dev) } // create a new char entry and put glyph in stagging buffer, ready for upload. -_char_ref _prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) { +char_ref _prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) { VkvgFont f = tr->font; #ifdef VKVG_USE_FREETYPE #if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING) @@ -393,13 +393,13 @@ _char_ref _prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) { #endif uint8_t* data = dev->fontCache->hostBuff; tex_ref_t l = f->texLines.elements[f->texLines.count - 1]; - if (dev->fontCache->stagingX + l.penX + bmpPixelWidth > FONT_PAGE_SIZE) { + if (dev->fontCache->stagingX + f->penX + bmpPixelWidth > FONT_PAGE_SIZE) { _flush_chars_to_tex(dev, f); _init_next_line_in_tex_cache(dev, f); } - _char_ref cr = {slot->glyph_index}; - int penX = dev->fontCache->stagingX; + char_ref cr = {slot->glyph_index}; + int penX = dev->fontCache->stagingX; #ifdef VKVG_USE_FREETYPE for (uint32_t y = 0; y < bmpRows; y++) { @@ -430,12 +430,12 @@ _char_ref _prepare_char(VkvgDevice dev, VkvgText tr, uint32_t gindex) { cr.bmpDiff.y = (int16_t)-c_y1; cr.advance = (vec2){(uint32_t)roundf(f->scale * advance) << 6, 0}; #endif - vec4 uvBounds = {{(float)(penX + l.penX) / (float)FONT_PAGE_SIZE}, - {(float)l.penY / (float)FONT_PAGE_SIZE}, + vec4 uvBounds = {{(float)(penX + f->penX) / (float)FONT_PAGE_SIZE}, + {0.f}, {(float)bmpPixelWidth}, {(float)bmpRows}}; cr.bounds = uvBounds; - cr.pageIdx = l.pageIdx; + cr.texRefIdx = f->texLines.count - 1; f->charLookup[gindex] = cr; dev->fontCache->stagingX += bmpPixelWidth; @@ -517,6 +517,7 @@ bool tryGetFontBufferFromPathHash(_font_cache_t* cache, uint64_t pathHash, vkvg_ } return false; } + #ifdef VKVG_USE_FONTCONFIG bool _tryResolveFontNameWithFontConfig(VkvgDevice dev, const char* fontString, vkvg_font_face_t **const face) { _font_cache_t* cache = dev->fontCache; @@ -770,6 +771,8 @@ void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr) { glyph_count = tr->glyph_count; #endif + VkvgFont f = tr->font; + Vertex v = {{0}, ctx->curColor, {0, 0, -1}}; vec2 pen = {0, 0}; @@ -779,7 +782,7 @@ void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr) { LOCK_FONTCACHE(ctx->dev) for (uint32_t i = 0; i < glyph_count; ++i) { - _char_ref cr = tr->font->charLookup[glyph_info[i].codepoint]; + char_ref cr = tr->font->charLookup[glyph_info[i].codepoint]; #ifdef VKVG_USE_HARFBUZZ if (!cr.index) @@ -794,9 +797,12 @@ void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr) { VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + tex_ref_t texRef = f->texLines.elements[cr.texRefIdx]; + float yOffset = (float)texRef.penY / (float)FONT_PAGE_SIZE; + v.uv.x = cr.bounds.x; - v.uv.y = cr.bounds.y; - v.uv.z = cr.pageIdx; + v.uv.y = yOffset; // + cr.bounds.y + v.uv.z = texRef.pageIdx; _add_vertex(ctx, v); v.pos.y += cr.bounds.height; @@ -806,7 +812,7 @@ void _font_cache_show_text_run(VkvgContext ctx, VkvgText tr) { v.pos.x += cr.bounds.width; v.pos.y = p0.y; v.uv.x += uvWidth; - v.uv.y = cr.bounds.y; + v.uv.y = yOffset; // + cr.bounds.y; _add_vertex(ctx, v); v.pos.y += cr.bounds.height; @@ -930,9 +936,9 @@ VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { FT_CHECK_RESULT(FT_Set_Char_Size(face->face, 0, font->charSize, dev->hdpi, dev->vdpi)); font->ftSize = face->face->size; - font->charLookup = (_char_ref*)calloc(face->face->num_glyphs, sizeof(_char_ref)); + font->charLookup = (char_ref*)calloc(face->face->num_glyphs, sizeof(char_ref)); - tex_ref_t l = {0};//pageIdx?? + tex_ref_t l = {0}; if (FT_IS_SCALABLE(face->face)) l.height = face->face->size->metrics.height >> 6; diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index 4328648..5ab82e6 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -161,8 +161,10 @@ static inline uint32_t decode_unicode_codepoint(const uint8_t* text) { inline int get_utf8_char_length(uint8_t first_byte) { return utf8_len_table[first_byte]; } + +typedef struct _tex_ref_t tex_ref_t; // texture coordinates of one character in font cache array texture. -typedef struct { +typedef struct _char_ref { uint32_t index; /* stored here only to detect empty char_ref */ vec4 bounds; /* normalized float bounds of character bitmap in font cache texture. */ vec2i16 bmpDiff; /* Difference in pixel between char bitmap top left corner and char glyph*/ @@ -171,14 +173,13 @@ typedef struct { #else vec2 advance; #endif - uint8_t pageIdx; /* Page index in font cache texture array */ -} _char_ref; + uint32_t texRefIdx; /* glyph bitmap ref in texture array */ +} char_ref; // Current location in font cache texture array for new character addition. Each font holds such structure to locate // where to upload new chars. typedef struct _tex_ref_t{ uint8_t pageIdx; /* Current page number in font cache */ - int penX; /* Current X in cache for next char addition */ int penY; /* Current Y in cache for next char addition */ int height; /* Height of current line pointed by this structure */ } tex_ref_t; @@ -243,8 +244,9 @@ typedef struct _vkvg_font_t { #ifdef VKVG_USE_HARFBUZZ hb_font_t* hb_font; /* HarfBuzz font instance*/ #endif - _char_ref* charLookup; /* Lookup table of characteres in cache, if not found, upload is queued*/ - array_tex_ref_t texLines; /* texture reference where to add new glyph bmp's in cache */ + char_ref* charLookup;/* Lookup table of characteres in cache, if not found, upload is queued*/ + array_tex_ref_t texLines; /* texture reference where to add new glyph bmp's in cache */ + int penX; /* Current X in cache for next char addition */ } vkvg_font_t; |