mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
refactor(tiny_fft): refactor tiny_ttf cache with updated improvements (#6441)
Co-authored-by: Benign X <1341398182@qq.com> Co-authored-by: Visa Harvey <visa.harvey@semel.fi>
This commit is contained in:
parent
3ac0a96cca
commit
730a3bd76f
4
Kconfig
4
Kconfig
@ -1241,6 +1241,10 @@ menu "LVGL configuration"
|
||||
bool "Enable loading Tiny TTF data from files"
|
||||
default n
|
||||
depends on LV_USE_TINY_TTF
|
||||
config LV_TINY_TTF_CACHE_GLYPH_CNT
|
||||
bool "Tiny ttf cache entries count"
|
||||
default 256
|
||||
depends on LV_USE_TINY_TTF
|
||||
|
||||
config LV_USE_RLOTTIE
|
||||
bool "Lottie library"
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_BENCHMARK
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_BENCHMARK
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_BENCHMARK
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_BENCHMARK
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
|
@ -1,9 +1,15 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../../../lvgl.h"
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_DEMO_WIDGETS
|
||||
|
@ -29,11 +29,14 @@ entire time the font is being used.
|
||||
After a font is created, you can change the font size in pixels by using
|
||||
:cpp:expr:`lv_tiny_ttf_set_size(font, font_size)`.
|
||||
|
||||
By default, a font will use up to 4KB of cache to speed up rendering
|
||||
glyphs. This maximum can be changed by using
|
||||
:cpp:expr:`lv_tiny_ttf_create_data_ex(data, data_size, font_size, cache_size)`
|
||||
or :cpp:expr:`lv_tiny_ttf_create_file_ex(path, font_size, cache_size)` (when
|
||||
available). The cache size is indicated in bytes.
|
||||
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, )`
|
||||
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.
|
||||
|
||||
|
||||
|
||||
.. _tiny_ttf_example:
|
||||
|
||||
|
@ -780,6 +780,7 @@
|
||||
#if LV_USE_TINY_TTF
|
||||
/* Enable loading TTF data from files */
|
||||
#define LV_TINY_TTF_FILE_SUPPORT 0
|
||||
#define LV_TINY_TTF_CACHE_GLYPH_CNT 256
|
||||
#endif
|
||||
|
||||
/*Rlottie library*/
|
||||
|
@ -174,10 +174,6 @@ typedef struct _lv_global_t {
|
||||
struct _lv_freetype_context_t * ft_context;
|
||||
#endif
|
||||
|
||||
#if LV_USE_TINY_TTF
|
||||
lv_cache_t * tiny_ttf_cache;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FONT_COMPRESSED
|
||||
lv_font_fmt_rle_t font_fmt_rle;
|
||||
#endif
|
||||
|
@ -8,9 +8,7 @@
|
||||
*********************/
|
||||
#include "../../lvgl.h"
|
||||
|
||||
#if LV_USE_TINY_TTF
|
||||
|
||||
#include "../../core/lv_global.h"
|
||||
#if LV_USE_TINY_TTF != 0
|
||||
|
||||
#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers)
|
||||
|
||||
@ -18,8 +16,6 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define CACHE_NAME "TINY_TTF"
|
||||
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#define STBRP_STATIC
|
||||
#define STBTT_STATIC
|
||||
@ -55,6 +51,7 @@ static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position);
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct ttf_font_desc {
|
||||
lv_fs_file_t file;
|
||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
||||
@ -66,10 +63,21 @@ typedef struct ttf_font_desc {
|
||||
float scale;
|
||||
int ascent;
|
||||
int descent;
|
||||
|
||||
lv_font_kerning_t kerning;
|
||||
|
||||
int cache_size;
|
||||
lv_cache_t * glyph_cache;
|
||||
lv_cache_t * draw_data_cache;
|
||||
} ttf_font_desc_t;
|
||||
|
||||
typedef struct _tiny_ttf_cache_data_t {
|
||||
lv_font_t * font;
|
||||
typedef struct _tiny_ttf_glyph_cache_data_t {
|
||||
uint32_t unicode;
|
||||
int adv_w;
|
||||
lv_font_glyph_dsc_t glyph_dsc;
|
||||
} tiny_ttf_glyph_cache_data_t;
|
||||
|
||||
typedef struct _lv_tiny_ttf_cache_data_t {
|
||||
uint32_t glyph_index;
|
||||
uint32_t size;
|
||||
lv_draw_buf_t * draw_buf;
|
||||
@ -82,13 +90,20 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d
|
||||
static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf);
|
||||
static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc);
|
||||
static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size,
|
||||
int32_t font_size,
|
||||
int32_t font_size, lv_font_kerning_t kerning,
|
||||
size_t cache_size);
|
||||
|
||||
static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data);
|
||||
static void tiny_ttf_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data);
|
||||
static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_data_t * lhs,
|
||||
const tiny_ttf_cache_data_t * rhs);
|
||||
static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data);
|
||||
static void tiny_ttf_glyph_cache_free_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data);
|
||||
static lv_cache_compare_res_t tiny_ttf_glyph_cache_compare_cb(const tiny_ttf_glyph_cache_data_t * lhs,
|
||||
const tiny_ttf_glyph_cache_data_t * rhs);
|
||||
|
||||
static bool tiny_ttf_draw_data_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data);
|
||||
static void tiny_ttf_draw_data_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data);
|
||||
static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf_cache_data_t * lhs,
|
||||
const tiny_ttf_cache_data_t * rhs);
|
||||
|
||||
static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc);
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
@ -117,6 +132,20 @@ void lv_tiny_ttf_set_size(lv_font_t * font, int32_t font_size)
|
||||
stbtt_GetFontVMetrics(&dsc->info, &dsc->ascent, &dsc->descent, &line_gap);
|
||||
font->line_height = (int32_t)(dsc->scale * (dsc->ascent - dsc->descent + line_gap));
|
||||
font->base_line = (int32_t)(dsc->scale * (line_gap - dsc->descent));
|
||||
|
||||
/* size change means cache needs to be invalidated. */
|
||||
|
||||
if(dsc->glyph_cache) {
|
||||
lv_cache_destroy(dsc->glyph_cache, NULL);
|
||||
dsc->glyph_cache = NULL;
|
||||
}
|
||||
|
||||
if(dsc->draw_data_cache) {
|
||||
lv_cache_destroy(dsc->draw_data_cache, NULL);
|
||||
dsc->draw_data_cache = NULL;
|
||||
}
|
||||
|
||||
lv_tiny_ttf_cache_create(dsc);
|
||||
}
|
||||
|
||||
void lv_tiny_ttf_destroy(lv_font_t * font)
|
||||
@ -130,7 +159,8 @@ void lv_tiny_ttf_destroy(lv_font_t * font)
|
||||
lv_fs_close(&ttf->file);
|
||||
}
|
||||
#endif
|
||||
lv_cache_drop_all(tiny_ttf_cache, (void *)font->dsc);
|
||||
lv_cache_destroy(ttf->glyph_cache, NULL);
|
||||
lv_cache_destroy(ttf->draw_data_cache, NULL);
|
||||
lv_free(ttf);
|
||||
font->dsc = NULL;
|
||||
}
|
||||
@ -138,23 +168,6 @@ void lv_tiny_ttf_destroy(lv_font_t * font)
|
||||
lv_free(font);
|
||||
}
|
||||
|
||||
void lv_tiny_ttf_init(void)
|
||||
{
|
||||
lv_cache_ops_t ops = {
|
||||
.compare_cb = (lv_cache_compare_cb_t)tiny_ttf_cache_compare_cb,
|
||||
.create_cb = (lv_cache_create_cb_t)tiny_ttf_cache_create_cb,
|
||||
.free_cb = (lv_cache_free_cb_t)tiny_ttf_cache_free_cb,
|
||||
};
|
||||
|
||||
tiny_ttf_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_cache_data_t), 128, ops);
|
||||
lv_cache_set_name(tiny_ttf_cache, CACHE_NAME);
|
||||
}
|
||||
|
||||
void lv_tiny_ttf_deinit(void)
|
||||
{
|
||||
lv_cache_destroy(tiny_ttf_cache, NULL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -205,31 +218,51 @@ static bool ttf_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * d
|
||||
dsc_out->is_placeholder = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
|
||||
int g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter);
|
||||
if(g1 == 0) {
|
||||
/* Glyph not found */
|
||||
|
||||
tiny_ttf_glyph_cache_data_t search_key = {
|
||||
.unicode = unicode_letter,
|
||||
};
|
||||
|
||||
lv_cache_entry_t * entry = lv_cache_acquire_or_create(dsc->glyph_cache, &search_key, (void *)dsc);
|
||||
|
||||
if(entry == NULL) {
|
||||
LV_LOG_ERROR("cache not allocated");
|
||||
return false;
|
||||
}
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
stbtt_GetGlyphBitmapBox(&dsc->info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2);
|
||||
int g2 = 0;
|
||||
if(unicode_letter_next != 0) {
|
||||
g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next);
|
||||
tiny_ttf_glyph_cache_data_t * data = lv_cache_entry_get_data(entry);
|
||||
*dsc_out = data->glyph_dsc;
|
||||
|
||||
/*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;
|
||||
|
||||
int g2 = 0;
|
||||
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)
|
||||
g2 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter_next);
|
||||
else {
|
||||
tiny_ttf_glyph_cache_data_t * data_next = lv_cache_entry_get_data(entry_next);
|
||||
g2 = data_next->glyph_dsc.gid.index;
|
||||
lv_cache_release(dsc->glyph_cache, entry_next, NULL);
|
||||
}
|
||||
|
||||
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) +
|
||||
0.5f); /*Horizontal space required by the glyph in [px]*/
|
||||
}
|
||||
}
|
||||
int advw, lsb;
|
||||
stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb);
|
||||
int k = stbtt_GetGlyphKernAdvance(&dsc->info, g1, g2);
|
||||
dsc_out->adv_w = (uint16_t)floor((((float)advw + (float)k) * dsc->scale) +
|
||||
0.5f); /*Horizontal space required by the glyph 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->ofs_x = x1; /*X offset of the bitmap in [pf]*/
|
||||
dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/
|
||||
dsc_out->format = LV_FONT_GLYPH_FORMAT_A8;
|
||||
dsc_out->is_placeholder = false;
|
||||
dsc_out->gid.index = (uint32_t)g1;
|
||||
|
||||
dsc_out->entry = NULL;
|
||||
|
||||
lv_cache_release(dsc->glyph_cache, entry, NULL);
|
||||
|
||||
return true; /*true: glyph found; false: glyph was not found*/
|
||||
}
|
||||
|
||||
@ -238,13 +271,13 @@ static const void * ttf_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw
|
||||
LV_UNUSED(draw_buf);
|
||||
uint32_t glyph_index = g_dsc->gid.index;
|
||||
const lv_font_t * font = g_dsc->resolved_font;
|
||||
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
|
||||
tiny_ttf_cache_data_t search_key = {
|
||||
.font = (lv_font_t *)font,
|
||||
.glyph_index = glyph_index,
|
||||
.size = font->line_height,
|
||||
};
|
||||
|
||||
lv_cache_entry_t * entry = lv_cache_acquire_or_create(tiny_ttf_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) {
|
||||
LV_LOG_ERROR("cache not allocated");
|
||||
@ -262,15 +295,35 @@ static void ttf_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g
|
||||
if(g_dsc->entry == NULL) {
|
||||
return;
|
||||
}
|
||||
lv_cache_release(tiny_ttf_cache, g_dsc->entry, NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc)
|
||||
{
|
||||
/*Init cache*/
|
||||
dsc->glyph_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_glyph_cache_data_t), dsc->cache_size,
|
||||
(lv_cache_ops_t) {
|
||||
.compare_cb = (lv_cache_compare_cb_t)tiny_ttf_glyph_cache_compare_cb,
|
||||
.create_cb = (lv_cache_create_cb_t)tiny_ttf_glyph_cache_create_cb,
|
||||
.free_cb = (lv_cache_free_cb_t)tiny_ttf_glyph_cache_free_cb
|
||||
});
|
||||
lv_cache_set_name(dsc->glyph_cache, "TINY_TTF_GLYPH");
|
||||
|
||||
dsc->draw_data_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(tiny_ttf_cache_data_t), dsc->cache_size,
|
||||
(lv_cache_ops_t) {
|
||||
.compare_cb = (lv_cache_compare_cb_t)tiny_ttf_draw_data_cache_compare_cb,
|
||||
.create_cb = (lv_cache_create_cb_t)tiny_ttf_draw_data_cache_create_cb,
|
||||
.free_cb = (lv_cache_free_cb_t)tiny_ttf_draw_data_cache_free_cb,
|
||||
});
|
||||
lv_cache_set_name(dsc->draw_data_cache, "TINY_TTF_DRAW_DATA");
|
||||
}
|
||||
|
||||
static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size_t data_size, int32_t font_size,
|
||||
size_t cache_size)
|
||||
lv_font_kerning_t kerning, size_t cache_size)
|
||||
{
|
||||
LV_UNUSED(data_size);
|
||||
LV_UNUSED(cache_size);
|
||||
if((path == NULL && data == NULL) || 0 >= font_size) {
|
||||
LV_LOG_ERROR("tiny_ttf: invalid argument");
|
||||
return NULL;
|
||||
@ -308,12 +361,23 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size
|
||||
}
|
||||
#endif
|
||||
|
||||
dsc->cache_size = cache_size;
|
||||
|
||||
lv_font_t * out_font = lv_malloc_zeroed(sizeof(lv_font_t));
|
||||
if(out_font == NULL) {
|
||||
lv_free(dsc);
|
||||
LV_LOG_ERROR("tiny_ttf: out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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.
|
||||
}
|
||||
|
||||
dsc->kerning = kerning;
|
||||
out_font->kerning = kerning;
|
||||
|
||||
out_font->get_glyph_dsc = ttf_get_glyph_dsc_cb;
|
||||
out_font->get_glyph_bitmap = ttf_get_glyph_bitmap_cb;
|
||||
out_font->release_glyph = ttf_release_glyph_cb;
|
||||
@ -322,31 +386,89 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size
|
||||
return out_font;
|
||||
}
|
||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
||||
lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, size_t cache_size)
|
||||
lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, lv_font_kerning_t kerning,
|
||||
size_t cache_size)
|
||||
{
|
||||
return lv_tiny_ttf_create(path, NULL, 0, font_size, cache_size);
|
||||
return lv_tiny_ttf_create(path, NULL, 0, font_size, kerning, cache_size);
|
||||
}
|
||||
lv_font_t * lv_tiny_ttf_create_file(const char * path, int32_t font_size)
|
||||
{
|
||||
return lv_tiny_ttf_create(path, NULL, 0, font_size, 0);
|
||||
return lv_tiny_ttf_create(path, NULL, 0, font_size, LV_FONT_KERNING_NORMAL, LV_TINY_TTF_CACHE_GLYPH_CNT);
|
||||
}
|
||||
#endif
|
||||
lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, size_t cache_size)
|
||||
|
||||
lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size,
|
||||
lv_font_kerning_t kerning, size_t cache_size)
|
||||
{
|
||||
return lv_tiny_ttf_create(NULL, data, data_size, font_size, cache_size);
|
||||
return lv_tiny_ttf_create(NULL, data, data_size, font_size, kerning, cache_size);
|
||||
}
|
||||
lv_font_t * lv_tiny_ttf_create_data(const void * data, size_t data_size, int32_t font_size)
|
||||
{
|
||||
return lv_tiny_ttf_create(NULL, data, data_size, font_size, 0);
|
||||
return lv_tiny_ttf_create(NULL, data, data_size, font_size, LV_FONT_KERNING_NORMAL, LV_TINY_TTF_CACHE_GLYPH_CNT);
|
||||
}
|
||||
|
||||
/*-----------------
|
||||
* Cache Callbacks
|
||||
*----------------*/
|
||||
|
||||
static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_data)
|
||||
static bool tiny_ttf_glyph_cache_create_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data)
|
||||
{
|
||||
ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data;
|
||||
lv_font_glyph_dsc_t * dsc_out = &node->glyph_dsc;
|
||||
|
||||
uint32_t unicode_letter = node->unicode;
|
||||
|
||||
int g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter);
|
||||
if(g1 == 0) {
|
||||
/* Glyph not found */
|
||||
return false;
|
||||
}
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
stbtt_GetGlyphBitmapBox(&dsc->info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2);
|
||||
|
||||
int advw, lsb;
|
||||
stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb);
|
||||
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]*/
|
||||
}
|
||||
else {
|
||||
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
|
||||
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]*/
|
||||
dsc_out->ofs_x = x1; /*X offset of the bitmap in [pf]*/
|
||||
dsc_out->ofs_y = -y2; /*Y offset of the bitmap measured from the as line*/
|
||||
dsc_out->format = LV_FONT_GLYPH_FORMAT_A8;
|
||||
dsc_out->is_placeholder = false;
|
||||
dsc_out->gid.index = (uint32_t)g1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tiny_ttf_glyph_cache_free_cb(tiny_ttf_glyph_cache_data_t * node, void * user_data)
|
||||
{
|
||||
LV_UNUSED(node);
|
||||
LV_UNUSED(user_data);
|
||||
}
|
||||
|
||||
static lv_cache_compare_res_t tiny_ttf_glyph_cache_compare_cb(const tiny_ttf_glyph_cache_data_t * lhs,
|
||||
const tiny_ttf_glyph_cache_data_t * rhs)
|
||||
{
|
||||
if(lhs->unicode != rhs->unicode) {
|
||||
return lhs->unicode > rhs->unicode ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -375,20 +497,16 @@ static bool tiny_ttf_cache_create_cb(tiny_ttf_cache_data_t * node, void * user_d
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tiny_ttf_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data)
|
||||
static void tiny_ttf_draw_data_cache_free_cb(tiny_ttf_cache_data_t * node, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
|
||||
lv_draw_buf_destroy_user(font_draw_buf_handlers, node->draw_buf);
|
||||
}
|
||||
|
||||
static lv_cache_compare_res_t tiny_ttf_cache_compare_cb(const tiny_ttf_cache_data_t * lhs,
|
||||
const tiny_ttf_cache_data_t * rhs)
|
||||
static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf_cache_data_t * lhs,
|
||||
const tiny_ttf_cache_data_t * rhs)
|
||||
{
|
||||
if(lhs->font != rhs->font) {
|
||||
return lhs->font > rhs->font ? 1 : -1;
|
||||
}
|
||||
|
||||
if(lhs->glyph_index != rhs->glyph_index) {
|
||||
return lhs->glyph_index > rhs->glyph_index ? 1 : -1;
|
||||
}
|
||||
|
@ -34,18 +34,16 @@ extern "C" {
|
||||
lv_font_t * lv_tiny_ttf_create_file(const char * path, int32_t font_size);
|
||||
|
||||
/* create a font from the specified file or path with the specified line height with the specified cache size.*/
|
||||
lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, size_t cache_size);
|
||||
lv_font_t * lv_tiny_ttf_create_file_ex(const char * path, int32_t font_size, lv_font_kerning_t kerning,
|
||||
size_t cache_size);
|
||||
#endif
|
||||
|
||||
void lv_tiny_ttf_init(void);
|
||||
|
||||
void lv_tiny_ttf_deinit(void);
|
||||
|
||||
/* create a font from the specified data pointer with the specified line height.*/
|
||||
lv_font_t * lv_tiny_ttf_create_data(const void * data, size_t data_size, int32_t font_size);
|
||||
|
||||
/* create a font from the specified data pointer with the specified line height and the specified cache size.*/
|
||||
lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size, size_t cache_size);
|
||||
lv_font_t * lv_tiny_ttf_create_data_ex(const void * data, size_t data_size, int32_t font_size,
|
||||
lv_font_kerning_t kerning, size_t cache_size);
|
||||
|
||||
/* set the size of the font to a new font_size*/
|
||||
void lv_tiny_ttf_set_size(lv_font_t * font, int32_t font_size);
|
||||
|
@ -2854,7 +2854,47 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo * info, i
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STBTT_DEF int stbtt_KernTableCheck(const stbtt_fontinfo * info)
|
||||
{
|
||||
if(info->gpos) {
|
||||
stbtt_uint16 lookupListOffset;
|
||||
stbtt_uint32 lookupList;
|
||||
stbtt_uint16 lookupCount;
|
||||
#ifdef STBTT_STREAM_TYPE
|
||||
STBTT_STREAM_TYPE data = info->data;
|
||||
#else
|
||||
const stbtt_uint8 * data = info->data;
|
||||
#endif
|
||||
stbtt_int32 i;
|
||||
|
||||
if(!info->gpos) return 0;
|
||||
|
||||
if(ttUSHORT(data, 0 + info->gpos) != 1) return 0; // Major version 1
|
||||
if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0
|
||||
|
||||
lookupListOffset = ttUSHORT(data, 8 + info->gpos);
|
||||
lookupList = lookupListOffset;
|
||||
lookupCount = ttUSHORT(data, lookupList);
|
||||
|
||||
for(i = 0; i < lookupCount; ++i) {
|
||||
stbtt_uint16 lookupOffset = ttUSHORT(data, lookupList + 2 + 2 * i);
|
||||
stbtt_uint32 lookupTable = lookupList + lookupOffset;
|
||||
|
||||
stbtt_uint16 lookupType = ttUSHORT(data, lookupTable);
|
||||
|
||||
if(lookupType != 2) // Pair Adjustment Positioning Subtable
|
||||
continue;
|
||||
|
||||
return 1; // we have a usable lookup table.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if(info->kern) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2597,6 +2597,13 @@
|
||||
#define LV_TINY_TTF_FILE_SUPPORT 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_TINY_TTF_CACHE_GLYPH_CNT
|
||||
#ifdef CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT
|
||||
#define LV_TINY_TTF_CACHE_GLYPH_CNT CONFIG_LV_TINY_TTF_CACHE_GLYPH_CNT
|
||||
#else
|
||||
#define LV_TINY_TTF_CACHE_GLYPH_CNT 256
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Rlottie library*/
|
||||
|
@ -316,10 +316,6 @@ void lv_init(void)
|
||||
lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT);
|
||||
#endif
|
||||
|
||||
#if LV_USE_TINY_TTF
|
||||
lv_tiny_ttf_init();
|
||||
#endif
|
||||
|
||||
lv_initialized = true;
|
||||
|
||||
LV_LOG_TRACE("finished");
|
||||
@ -357,10 +353,6 @@ void lv_deinit(void)
|
||||
lv_freetype_uninit();
|
||||
#endif
|
||||
|
||||
#if LV_USE_TINY_TTF
|
||||
lv_tiny_ttf_deinit();
|
||||
#endif
|
||||
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
lv_theme_default_deinit();
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user