fix(tiny_ttf): fix no cache and formatting cleanup (#6568)

This commit is contained in:
Visa Harvey
2024-08-01 12:09:55 +03:00
committed by GitHub
parent 7791740de6
commit a623a5ca3d
3 changed files with 62 additions and 21 deletions

View File

@@ -687,6 +687,11 @@
#if LV_USE_TINY_TTF #if LV_USE_TINY_TTF
/* Enable loading TTF data from files */ /* Enable loading TTF data from files */
#define LV_TINY_TTF_FILE_SUPPORT 0 #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 #endif
/*Rlottie library*/ /*Rlottie library*/

View File

@@ -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. By default, a font will cache data for upto 256 glyphs elements to speed up rendering.
This maximum can be changed by using 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 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 available). The cache size is indicated in number of entries. Kerning is whether to allow
if supported, or disable. if supported, or disable.

View File

@@ -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_rect_pack.h"
#include "stb_truetype_htcw.h" #include "stb_truetype_htcw.h"
#define tiny_ttf_cache LV_GLOBAL_DEFAULT()->tiny_ttf_cache
/********************** /**********************
* TYPEDEFS * 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, .unicode = unicode_letter,
}; };
int adv_w;
lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc); lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc);
if(entry == NULL) { 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"); LV_LOG_ERROR("cache not allocated");
return false; return false;
} }
tiny_ttf_glyph_cache_data_t * data = lv_cache_entry_get_data(entry); tiny_ttf_glyph_cache_data_t * data = lv_cache_entry_get_data(entry);
*dsc_out = data->glyph_dsc; *dsc_out = data->glyph_dsc;
adv_w = data->adv_w;
lv_cache_release(dsc->glyph_cache, entry, NULL);
/*Kerning correction*/ /*Kerning correction*/
if(font->kerning == LV_FONT_KERNING_NORMAL && if(font->kerning == LV_FONT_KERNING_NORMAL &&
unicode_letter_next != 0) { // check if we need to do any kerning calculations unicode_letter_next != 0) { /* check if we need to do any kerning calculations */
uint32_t g1 = data->glyph_dsc.gid.index; uint32_t g1 = dsc_out->gid.index;
int g2 = 0; 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); lv_cache_entry_t * entry_next = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc);
if(entry_next == NULL) 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) { if(g2) {
int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, 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]*/ 0.5f); /*Horizontal space required by the glyph in [px]*/
} }
} }
dsc_out->entry = NULL; dsc_out->entry = NULL;
lv_cache_release(dsc->glyph_cache, entry, NULL);
return true; /*true: glyph found; false: glyph was not found*/ 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); lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->draw_data_cache, &search_key, (void *)font->dsc);
if(entry == NULL) { 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"); LV_LOG_ERROR("cache not allocated");
return NULL; 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) static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc)
{ {
LV_ASSERT_NULL(font); LV_ASSERT_NULL(font);
if(g_dsc->entry == NULL) {
return;
}
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc; 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; 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; 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) { 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; 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; int advw, lsb;
stbtt_GetGlyphHMetrics(&dsc->info, g1, &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); int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, 0);
dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) + dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) +
0.5f); /*Horizontal space required by the glyph in [px]*/ 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) + dsc_out->adv_w = (uint16_t)floor(((float)advw * dsc->scale) +
0.5f); /*Horizontal space required by the glyph in [px]*/; 0.5f); /*Horizontal space required by the glyph in [px]*/;
} }
// precalculate no kerning value /* precalculate no kerning value */
node->adv_w = advw; node->adv_w = advw;
dsc_out->box_w = (x2 - x1 + 1); /*width of the bitmap in [px]*/ 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]*/ 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) 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; int g1 = (int)node->glyph_index;
if(g1 == 0) { if(g1 == 0) {
/* Glyph not found */ /* Glyph not found */
return false; 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; int x1, y1, x2, y2;
stbtt_GetGlyphBitmapBox(info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2); stbtt_GetGlyphBitmapBox(info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2);
int w, h; int w, h;
w = x2 - x1 + 1; w = x2 - x1 + 1;
h = y2 - y1 + 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); 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) { if(NULL == draw_buf) {
LV_LOG_ERROR("tiny_ttf: out of memory"); LV_LOG_ERROR("tiny_ttf: out of memory");