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
/* 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*/

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.
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.

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_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);
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
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;
}
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
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");