mirror of
https://github.com/lvgl/lvgl.git
synced 2025-02-04 07:13: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"
|
bool "Enable loading Tiny TTF data from files"
|
||||||
default n
|
default n
|
||||||
depends on LV_USE_TINY_TTF
|
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
|
config LV_USE_RLOTTIE
|
||||||
bool "Lottie library"
|
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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_BENCHMARK
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_WIDGETS
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_WIDGETS
|
#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)
|
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#elif defined(LV_BUILD_TEST)
|
|
||||||
#include "../../../lvgl.h"
|
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_DEMO_WIDGETS
|
#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
|
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)`.
|
: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
|
By default, a font will cache data for upto 256 glyphs elements to speed up rendering.
|
||||||
glyphs. 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, 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, 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 bytes.
|
available). The cache size is indicated in number of entries. Kerning is whether to allow
|
||||||
|
if supported, or disable.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _tiny_ttf_example:
|
.. _tiny_ttf_example:
|
||||||
|
|
||||||
|
@ -780,6 +780,7 @@
|
|||||||
#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
|
||||||
|
#define LV_TINY_TTF_CACHE_GLYPH_CNT 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*Rlottie library*/
|
/*Rlottie library*/
|
||||||
|
@ -174,10 +174,6 @@ typedef struct _lv_global_t {
|
|||||||
struct _lv_freetype_context_t * ft_context;
|
struct _lv_freetype_context_t * ft_context;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_TINY_TTF
|
|
||||||
lv_cache_t * tiny_ttf_cache;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_FONT_COMPRESSED
|
#if LV_USE_FONT_COMPRESSED
|
||||||
lv_font_fmt_rle_t font_fmt_rle;
|
lv_font_fmt_rle_t font_fmt_rle;
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
*********************/
|
*********************/
|
||||||
#include "../../lvgl.h"
|
#include "../../lvgl.h"
|
||||||
|
|
||||||
#if LV_USE_TINY_TTF
|
#if LV_USE_TINY_TTF != 0
|
||||||
|
|
||||||
#include "../../core/lv_global.h"
|
|
||||||
|
|
||||||
#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers)
|
#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers)
|
||||||
|
|
||||||
@ -18,8 +16,6 @@
|
|||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
#define CACHE_NAME "TINY_TTF"
|
|
||||||
|
|
||||||
#define STB_RECT_PACK_IMPLEMENTATION
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
#define STBRP_STATIC
|
#define STBRP_STATIC
|
||||||
#define STBTT_STATIC
|
#define STBTT_STATIC
|
||||||
@ -55,6 +51,7 @@ static void ttf_cb_stream_seek(ttf_cb_stream_t * stream, size_t position);
|
|||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
typedef struct ttf_font_desc {
|
typedef struct ttf_font_desc {
|
||||||
lv_fs_file_t file;
|
lv_fs_file_t file;
|
||||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
||||||
@ -66,10 +63,21 @@ typedef struct ttf_font_desc {
|
|||||||
float scale;
|
float scale;
|
||||||
int ascent;
|
int ascent;
|
||||||
int descent;
|
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;
|
} ttf_font_desc_t;
|
||||||
|
|
||||||
typedef struct _tiny_ttf_cache_data_t {
|
typedef struct _tiny_ttf_glyph_cache_data_t {
|
||||||
lv_font_t * font;
|
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 glyph_index;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
lv_draw_buf_t * draw_buf;
|
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 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 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,
|
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);
|
size_t cache_size);
|
||||||
|
|
||||||
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);
|
||||||
static void tiny_ttf_cache_free_cb(tiny_ttf_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_cache_compare_cb(const tiny_ttf_cache_data_t * lhs,
|
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);
|
const tiny_ttf_cache_data_t * rhs);
|
||||||
|
|
||||||
|
static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc);
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL VARIABLES
|
* 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);
|
stbtt_GetFontVMetrics(&dsc->info, &dsc->ascent, &dsc->descent, &line_gap);
|
||||||
font->line_height = (int32_t)(dsc->scale * (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));
|
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)
|
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);
|
lv_fs_close(&ttf->file);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
lv_free(ttf);
|
||||||
font->dsc = NULL;
|
font->dsc = NULL;
|
||||||
}
|
}
|
||||||
@ -138,23 +168,6 @@ void lv_tiny_ttf_destroy(lv_font_t * font)
|
|||||||
lv_free(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
|
* 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;
|
dsc_out->is_placeholder = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
|
ttf_font_desc_t * dsc = (ttf_font_desc_t *)font->dsc;
|
||||||
int g1 = stbtt_FindGlyphIndex(&dsc->info, (int)unicode_letter);
|
|
||||||
if(g1 == 0) {
|
tiny_ttf_glyph_cache_data_t search_key = {
|
||||||
/* Glyph not found */
|
.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;
|
return false;
|
||||||
}
|
}
|
||||||
int x1, y1, x2, y2;
|
|
||||||
|
|
||||||
stbtt_GetGlyphBitmapBox(&dsc->info, g1, dsc->scale, dsc->scale, &x1, &y1, &x2, &y2);
|
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;
|
int g2 = 0;
|
||||||
if(unicode_letter_next != 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);
|
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);
|
||||||
}
|
}
|
||||||
int advw, lsb;
|
|
||||||
stbtt_GetGlyphHMetrics(&dsc->info, g1, &advw, &lsb);
|
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)advw + (float)k) * dsc->scale) +
|
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]*/
|
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->entry = NULL;
|
||||||
dsc_out->format = LV_FONT_GLYPH_FORMAT_A8;
|
|
||||||
dsc_out->is_placeholder = false;
|
lv_cache_release(dsc->glyph_cache, entry, NULL);
|
||||||
dsc_out->gid.index = (uint32_t)g1;
|
|
||||||
return true; /*true: glyph found; false: glyph was not found*/
|
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);
|
LV_UNUSED(draw_buf);
|
||||||
uint32_t glyph_index = g_dsc->gid.index;
|
uint32_t glyph_index = g_dsc->gid.index;
|
||||||
const lv_font_t * font = g_dsc->resolved_font;
|
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 = {
|
tiny_ttf_cache_data_t search_key = {
|
||||||
.font = (lv_font_t *)font,
|
|
||||||
.glyph_index = glyph_index,
|
.glyph_index = glyph_index,
|
||||||
.size = font->line_height,
|
.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) {
|
if(entry == NULL) {
|
||||||
LV_LOG_ERROR("cache not allocated");
|
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) {
|
if(g_dsc->entry == NULL) {
|
||||||
return;
|
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;
|
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,
|
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(data_size);
|
||||||
LV_UNUSED(cache_size);
|
|
||||||
if((path == NULL && data == NULL) || 0 >= font_size) {
|
if((path == NULL && data == NULL) || 0 >= font_size) {
|
||||||
LV_LOG_ERROR("tiny_ttf: invalid argument");
|
LV_LOG_ERROR("tiny_ttf: invalid argument");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -308,12 +361,23 @@ static lv_font_t * lv_tiny_ttf_create(const char * path, const void * data, size
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
dsc->cache_size = cache_size;
|
||||||
|
|
||||||
lv_font_t * out_font = lv_malloc_zeroed(sizeof(lv_font_t));
|
lv_font_t * out_font = lv_malloc_zeroed(sizeof(lv_font_t));
|
||||||
if(out_font == NULL) {
|
if(out_font == NULL) {
|
||||||
lv_free(dsc);
|
lv_free(dsc);
|
||||||
LV_LOG_ERROR("tiny_ttf: out of memory");
|
LV_LOG_ERROR("tiny_ttf: out of memory");
|
||||||
return NULL;
|
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_dsc = ttf_get_glyph_dsc_cb;
|
||||||
out_font->get_glyph_bitmap = ttf_get_glyph_bitmap_cb;
|
out_font->get_glyph_bitmap = ttf_get_glyph_bitmap_cb;
|
||||||
out_font->release_glyph = ttf_release_glyph_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;
|
return out_font;
|
||||||
}
|
}
|
||||||
#if LV_TINY_TTF_FILE_SUPPORT != 0
|
#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)
|
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
|
#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)
|
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
|
* 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;
|
ttf_font_desc_t * dsc = (ttf_font_desc_t *)user_data;
|
||||||
|
|
||||||
const stbtt_fontinfo * info = (const stbtt_fontinfo *)&dsc->info;
|
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;
|
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_UNUSED(user_data);
|
||||||
|
|
||||||
lv_draw_buf_destroy_user(font_draw_buf_handlers, node->draw_buf);
|
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,
|
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)
|
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) {
|
if(lhs->glyph_index != rhs->glyph_index) {
|
||||||
return lhs->glyph_index > rhs->glyph_index ? 1 : -1;
|
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);
|
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.*/
|
/* 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
|
#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.*/
|
/* 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);
|
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.*/
|
/* 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*/
|
/* 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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2597,6 +2597,13 @@
|
|||||||
#define LV_TINY_TTF_FILE_SUPPORT 0
|
#define LV_TINY_TTF_FILE_SUPPORT 0
|
||||||
#endif
|
#endif
|
||||||
#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
|
#endif
|
||||||
|
|
||||||
/*Rlottie library*/
|
/*Rlottie library*/
|
||||||
|
@ -316,10 +316,6 @@ void lv_init(void)
|
|||||||
lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT);
|
lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_TINY_TTF
|
|
||||||
lv_tiny_ttf_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_initialized = true;
|
lv_initialized = true;
|
||||||
|
|
||||||
LV_LOG_TRACE("finished");
|
LV_LOG_TRACE("finished");
|
||||||
@ -357,10 +353,6 @@ void lv_deinit(void)
|
|||||||
lv_freetype_uninit();
|
lv_freetype_uninit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_TINY_TTF
|
|
||||||
lv_tiny_ttf_deinit();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LV_USE_THEME_DEFAULT
|
#if LV_USE_THEME_DEFAULT
|
||||||
lv_theme_default_deinit();
|
lv_theme_default_deinit();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user