From a623a5ca3d96f36b02bcde5b7da2c9a0151d1618 Mon Sep 17 00:00:00 2001 From: Visa Harvey Date: Thu, 1 Aug 2024 12:09:55 +0300 Subject: [PATCH] fix(tiny_ttf): fix no cache and formatting cleanup (#6568) --- .devcontainer/__lv_conf.h__ | 5 +++ docs/libs/tiny_ttf.rst | 2 +- src/libs/tiny_ttf/lv_tiny_ttf.c | 76 ++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/.devcontainer/__lv_conf.h__ b/.devcontainer/__lv_conf.h__ index b915ec761..a1424736d 100644 --- a/.devcontainer/__lv_conf.h__ +++ b/.devcontainer/__lv_conf.h__ @@ -687,6 +687,11 @@ #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ #define LV_TINY_TTF_FILE_SUPPORT 0 + /*Cache count of the glyphs in Tiny TTF. It means the number of glyphs that can be cached. + *The higher the value, the more memory will be used + *Minor performance benefit should be evident with cnt > 3 + *For best performance count should be greater than count of glyphs in use */ + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 #endif /*Rlottie library*/ diff --git a/docs/libs/tiny_ttf.rst b/docs/libs/tiny_ttf.rst index 69f801b4d..42ffeeaba 100644 --- a/docs/libs/tiny_ttf.rst +++ b/docs/libs/tiny_ttf.rst @@ -31,7 +31,7 @@ After a font is created, you can change the font size in pixels by using By default, a font will cache data for upto 256 glyphs elements to speed up rendering. This maximum can be changed by using -:cpp:expr:`lv_tiny_ttf_create_data_ex(data, data_size, font_size, kerning, cache_size, )` +:cpp:expr:`lv_tiny_ttf_create_data_ex(data, data_size, font_size, kerning, cache_size)` or :cpp:expr:`lv_tiny_ttf_create_file_ex(path, font_size, kerning, cache_size)` (when available). The cache size is indicated in number of entries. Kerning is whether to allow if supported, or disable. diff --git a/src/libs/tiny_ttf/lv_tiny_ttf.c b/src/libs/tiny_ttf/lv_tiny_ttf.c index 0170607cf..00927e104 100644 --- a/src/libs/tiny_ttf/lv_tiny_ttf.c +++ b/src/libs/tiny_ttf/lv_tiny_ttf.c @@ -47,7 +47,6 @@ static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position); #include "stb_rect_pack.h" #include "stb_truetype_htcw.h" -#define tiny_ttf_cache LV_GLOBAL_DEFAULT()->tiny_ttf_cache /********************** * TYPEDEFS **********************/ @@ -225,23 +224,46 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d .unicode = unicode_letter, }; + int adv_w; lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc); if(entry == NULL) { + if(!dsc->cache_size) { /* no cache, do everything directly */ + uint32_t g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter); + tiny_ttf_glyph_cache_create_cb(&search_key, dsc); + *dsc_out = search_key.glyph_dsc; + adv_w = search_key.adv_w; + + /*Kerning correction*/ + if(font->kerning == LV_FONT_KERNING_NORMAL && + unicode_letter_next != 0) { + int g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next); /* not using cache, only do glyph id lookup */ + if(g2) { + int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2); + dsc_out->adv_w = (uint16_t)floor((((float)adv_w + (float)k) * dsc->scale) + + 0.5f); /*Horizontal space required by the glyph in [px]*/ + } + } + + dsc_out->entry = NULL; + return true; + } LV_LOG_ERROR("cache not allocated"); return false; } tiny_ttf_glyph_cache_data_t * data = lv_cache_entry_get_data(entry); *dsc_out = data->glyph_dsc; + adv_w = data->adv_w; + lv_cache_release(dsc->glyph_cache, entry, NULL); /*Kerning correction*/ if(font->kerning == LV_FONT_KERNING_NORMAL && - unicode_letter_next != 0) { // check if we need to do any kerning calculations - uint32_t g1 = data->glyph_dsc.gid.index; + unicode_letter_next != 0) { /* check if we need to do any kerning calculations */ + uint32_t g1 = dsc_out->gid.index; int g2 = 0; - search_key.unicode = unicode_letter_next; // reuse search key + search_key.unicode = unicode_letter_next; /* reuse search key */ lv_cache_entry_t * entry_next = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc); if(entry_next == NULL) @@ -254,15 +276,12 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d if(g2) { int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2); - dsc_out->adv_w = (uint16_t)floor((((float)data->adv_w + (float)k) * dsc->scale) + + dsc_out->adv_w = (uint16_t)floor((((float)adv_w + (float)k) * dsc->scale) + 0.5f); /*Horizontal space required by the glyph in [px]*/ } } dsc_out->entry = NULL; - - lv_cache_release(dsc->glyph_cache, entry, NULL); - return true; /*true: glyph found; false: glyph was not found*/ } @@ -278,8 +297,17 @@ static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw }; lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->draw_data_cache, &search_key, (void *)font->dsc); - if(entry == NULL) { + if(!dsc->cache_size) { /* no cache, do everything directly */ + if(tiny_ttf_draw_data_cache_create_cb(&search_key, (void *)font->dsc)) { + /* use the cache entry to store the buffer if no cache specified */ + g_dsc->entry = (lv_cache_entry_t *)search_key.draw_buf; + return g_dsc->entry; + } + else { + return NULL; + } + } LV_LOG_ERROR("cache not allocated"); return NULL; } @@ -292,11 +320,17 @@ static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc) { LV_ASSERT_NULL(font); - if(g_dsc->entry == NULL) { - return; - } + ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; - lv_cache_release(dsc->draw_data_cache, g_dsc->entry, NULL); + if(!dsc->cache_size) { /* no cache, do everything directly */ + lv_draw_buf_destroy_user(font_draw_buf_handlers, (lv_draw_buf_t *)g_dsc->entry); + } + else { + if(g_dsc->entry == NULL) { + return; + } + lv_cache_release(dsc->draw_data_cache, g_dsc->entry, NULL); + } g_dsc->entry = NULL; } @@ -370,9 +404,9 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size return NULL; } - // check if font has kerning tables to use, else disable kerning automatically. + /* check if font has kerning tables to use, else disable kerning automatically. */ if(stbtt_KernTableCheck(&dsc->info) == 0) { - kerning = LV_FONT_KERNING_NONE; // disable kerning if font has no tables. + kerning = LV_FONT_KERNING_NONE; /* disable kerning if font has no tables. */ } dsc->kerning = kerning; @@ -429,7 +463,7 @@ static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, v int advw, lsb; stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb); - if(dsc->kerning != LV_FONT_KERNING_NORMAL) { // calculate default advance + if(dsc->kerning != LV_FONT_KERNING_NORMAL) { /* calculate default advance */ int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, 0); dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) + 0.5f); /*Horizontal space required by the glyph in [px]*/ @@ -438,7 +472,7 @@ static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, v dsc_out->adv_w = (uint16_t)floor(((float)advw * dsc->scale) + 0.5f); /*Horizontal space required by the glyph in [px]*/; } - // precalculate no kerning value + /* precalculate no kerning value */ node->adv_w = advw; dsc_out->box_w = (x2 - x1 + 1); /*width of the bitmap in [px]*/ dsc_out->box_h = (y2 - y1 + 1); /*height of the bitmap in [px]*/ @@ -469,19 +503,21 @@ static lv_cache_compare_res_t tiny_ttf_glyph_cache_compare_cb(const tiny_ttf_gly static bool tiny_ttf_draw_data_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data) { - ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data; - - const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info; int g1 = (int)node->glyph_index; if(g1 == 0) { /* Glyph not found */ return false; } + + ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data; + + const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info; int x1, y1, x2, y2; stbtt_GetGlyphBitmapBox(info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2); int w, h; w = x2 - x1 + 1; h = y2 - y1 + 1; + lv_draw_buf_t * draw_buf = lv_draw_buf_create_user(font_draw_buf_handlers, w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO); if(NULL == draw_buf) { LV_LOG_ERROR("tiny_ttf: out of memory");