arch(font_manager): add multiple font backend support (#8038)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX
2025-04-15 11:35:50 +08:00
committed by GitHub
parent db7cad1e32
commit 19cb83732b
44 changed files with 995 additions and 286 deletions
+1 -2
View File
@@ -1656,8 +1656,7 @@ menu "LVGL configuration"
This can save some memory, but not much. After the quick access bar is created, it can be hidden by clicking the button at the top left corner of the browsing area, which is very useful for small screen devices.
config LV_USE_FONT_MANAGER
bool "Enable freetype font manager"
depends on LV_USE_FREETYPE
bool "Enable Font manager"
default n
config LV_FONT_MANAGER_NAME_MAX_LEN
int "Font manager name max length"
@@ -4,9 +4,9 @@
Font Manager
============
Font Manager is a secondary encapsulation of :ref:`freetype`, which provides
facilities for high-level applications to manage and use vector fonts. Currently
provided font-management functions includes:
The font manager is a secondary encapsulation of the LVGL font engine,
which facilitates the use and management of fonts for applications.
The font management functions currently provided include:
- Font resource reference counting (reduces repeated creation of font resources).
- Font resource concatenation (font fallback).
@@ -21,7 +21,7 @@ Usage
*****
Enable FreeType and Font Manager in ``lv_conf.h`` by setting the
:c:macro:`LV_USE_FREETYPE` and :c:macro:`LV_USE_FONT_MANAGER` macros to non-zero
:c:macro:`LV_USE_FONT_MANAGER` macros to non-zero
values, and configure :c:macro:`LV_FONT_MANAGER_NAME_MAX_LEN` to set the maximum
length of the font name.
@@ -32,13 +32,17 @@ Use :cpp:func:`lv_font_manager_create` to create a font manager, where the
:cpp:func:`recycle_cache_size` parameter is used to set the number of font recycling
caches, which can improve font creation efficiency.
Use :cpp:func:`lv_font_manager_add_path_static` to add a mapping between the font
file path and the custom font name, so that the application can access the font
resources more conveniently. It should be noted that if the file path is not static
(assigned from a local variable), use :cpp:func:`lv_font_manager_add_path` to
add the path. This function will make its own copy of the string.
Use :cpp:func:`lv_font_manager_add_src_static` to add a mapping between font names
and font resources to tell the font manager how to access the font resources.
Note that if the font resource description structure is not statically allocated
(for example, allocated from a local variable), use :cpp:func:`lv_font_manager_add_src` to add the resource.
This function will copy the contents of the structure itself.
Use :cpp:func:`lv_font_manager_remove_path` to remove the font path mapping.
Use :cpp:func:`lv_font_manager_remove_src` to remove the font resource mapping.
It should be noted that the ``src`` parameter must strictly correspond to ``class_p``.
``class_p`` will affect the way the font manager interprets src. If an incompatible parameter is passed, the program may fail.
For currently supported font classes, please refer to the example code.
.. code-block:: c
@@ -50,15 +54,18 @@ Use :cpp:func:`lv_font_manager_remove_path` to remove the font path mapping.
g_font_manager = lv_font_manager_create(8);
/* Add font path mapping to font manager */
lv_font_manager_add_path_static(g_font_manager, "Lato-Regular", "./lvgl/examples/libs/freetype/Lato-Regular.ttf");
lv_font_manager_add_path_static(g_font_manager, "MyFont", "./path/to/myfont.ttf");
lv_font_manager_add_src_static(g_font_manager, "Lato-Regular", "./lvgl/examples/libs/freetype/Lato-Regular.ttf", &lv_freetype_font_class);
char path[] = "/path/to/myfont.ttf";
lv_font_manager_add_src(g_font_manager, "MyFont", path, &lv_freetype_font_class);
}
Create Font from Font Manager
-----------------------------
Use :cpp:func:`lv_font_manager_create_font` to create a font. The parameters are
basically the same as :cpp:func:`lv_freetype_font_create`.
The parameters will be passed to the font creation function of the font backend,
such as :cpp:func:`lv_freetype_font_create` and :cpp:func:`lv_tiny_ttf_create_file`.
The font backend will select the supported parameters by itself and ignore the unsupported parameters.
The ``font_family`` parameter can be filled with the names of multiple fonts
(separated by ``,``) to achieve font concatenation (when the corresponding glyph is
@@ -74,7 +81,13 @@ font).
"Lato-Regular,MyFont",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
24,
LV_FREETYPE_FONT_STYLE_NORMAL);
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
/* Handle error case */
if(g_font == NULL) {
g_font = (lv_font_t *)LV_FONT_DEFAULT;
}
/* Create label with the font */
lv_obj_t * label = lv_label_create(lv_screen_active());
+1 -1
View File
@@ -1766,7 +1766,7 @@
<RTE_Components_h>
/*! \brief Enable freetype font manager */
/*! \brief Enable Font manager */
#define LV_USE_FONT_MANAGER 1
</RTE_Components_h>
+1 -1
View File
@@ -1004,7 +1004,7 @@
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
#endif
/** 1: Enable freetype font manager
/** 1: Enable Font manager
* - Requires: LV_USE_FREETYPE */
#if LV_USE_FONT_MANAGER
+13 -1
View File
@@ -1,6 +1,18 @@
Font manager example
Create FreeType Font
--------------------
.. lv_example:: others/font_manager/lv_example_font_manager_1
:language: c
Create Font Family
------------------
.. lv_example:: others/font_manager/lv_example_font_manager_2
:language: c
Create Custom Image Font
------------------------
.. lv_example:: others/font_manager/lv_example_font_manager_3
:language: c
@@ -26,6 +26,8 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
void lv_example_font_manager_1(void);
void lv_example_font_manager_2(void);
void lv_example_font_manager_3(void);
/**********************
* MACROS
@@ -1,5 +1,5 @@
#include "../../lv_examples.h"
#if LV_USE_FREETYPE && LV_USE_FONT_MANAGER && LV_BUILD_EXAMPLES
#if LV_USE_FONT_MANAGER && LV_USE_FREETYPE && LV_BUILD_EXAMPLES
#if LV_FREETYPE_USE_LVGL_PORT
#define PATH_PREFIX "A:"
@@ -15,16 +15,18 @@ void lv_example_font_manager_1(void)
g_font_manager = lv_font_manager_create(8);
/* Add font path mapping to font manager */
lv_font_manager_add_path_static(g_font_manager,
"Lato-Regular",
PATH_PREFIX "lvgl/examples/libs/freetype/Lato-Regular.ttf");
lv_font_manager_add_src_static(g_font_manager,
"Lato-Regular",
PATH_PREFIX "lvgl/examples/libs/freetype/Lato-Regular.ttf",
&lv_freetype_font_class);
/* Create font from font manager */
lv_font_t * font = lv_font_manager_create_font(g_font_manager,
"Lato-Regular",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
24,
LV_FREETYPE_FONT_STYLE_NORMAL);
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
if(!font) {
LV_LOG_ERROR("Could not create font");
@@ -43,7 +45,7 @@ void lv_example_font_manager_1(void)
void lv_example_font_manager_1(void)
{
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "FreeType or font_manager is not enabled");
lv_label_set_text(label, "Font Manager or FreeType is not enabled");
lv_obj_center(label);
}
@@ -0,0 +1,88 @@
#include "../../lv_examples.h"
#if LV_USE_FONT_MANAGER && LV_BUILD_EXAMPLES
#if defined(LV_FREETYPE_USE_LVGL_PORT) && LV_FREETYPE_USE_LVGL_PORT
#define PATH_PREFIX "A:"
#else
#define PATH_PREFIX "./"
#endif
static lv_font_manager_t * g_font_manager = NULL;
void lv_example_font_manager_2(void)
{
/* Create font manager, with 8 fonts recycling buffers */
g_font_manager = lv_font_manager_create(8);
#if LV_FONT_MONTSERRAT_14 && LV_FONT_MONTSERRAT_32
/* Register built-in font sources */
static lv_builtin_font_src_t builtin_font_src[3] = { 0 };
builtin_font_src[0].font_p = &lv_font_montserrat_14;
builtin_font_src[0].size = 14;
builtin_font_src[1].font_p = &lv_font_montserrat_32;
builtin_font_src[1].size = 32;
/* IMPORTANT! Marking the end of the array */
builtin_font_src[2].font_p = NULL;
builtin_font_src[2].size = 0;
lv_font_manager_add_src_static(g_font_manager,
"Montserrat",
builtin_font_src,
&lv_builtin_font_class);
#endif
#if LV_USE_FREETYPE
/* Register FreeType font source */
lv_font_manager_add_src_static(g_font_manager,
"NotoColorEmoji",
PATH_PREFIX "lvgl/examples/libs/freetype/NotoColorEmoji-32.subset.ttf",
&lv_freetype_font_class);
#endif
#if LV_USE_TINY_TTF && LV_TINY_TTF_FILE_SUPPORT
/* Register TinyTTF font source */
static const lv_tiny_ttf_font_src_t tiny_ttf_font_src = {
.path = "A:lvgl/examples/libs/tiny_ttf/Ubuntu-Medium.ttf",
.data = NULL,
.data_size = 0,
.cache_size = 0,
};
lv_font_manager_add_src_static(g_font_manager,
"Ubuntu-Medium",
&tiny_ttf_font_src,
&lv_tiny_ttf_font_class);
#endif
/* Create font from font manager */
lv_font_t * font = lv_font_manager_create_font(g_font_manager,
"Ubuntu-Medium,NotoColorEmoji,Montserrat",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
32,
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
if(!font) {
LV_LOG_ERROR("Could not create font");
return;
}
/* Create label with the font */
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_obj_set_style_text_font(label, font, 0);
lv_label_set_text(label, "Hello Font Manager! 😀 " LV_SYMBOL_OK);
lv_obj_center(label);
}
#else
void lv_example_font_manager_2(void)
{
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "Font Manager is not enabled");
lv_obj_center(label);
}
#endif
@@ -0,0 +1,123 @@
#include "../../lv_examples.h"
#if LV_USE_FONT_MANAGER && LV_USE_FREETYPE && LV_USE_IMGFONT && LV_BUILD_EXAMPLES
#if LV_FREETYPE_USE_LVGL_PORT
#define PATH_PREFIX "A:"
#else
#define PATH_PREFIX "./"
#endif
typedef struct {
uint16_t match_size_min;
uint16_t match_size_max;
lv_imgfont_get_path_cb_t get_path_cb;
} imgfont_src_t;
static lv_font_manager_t * g_font_manager = NULL;
static const void * get_imgfont_path(const lv_font_t * font, uint32_t unicode, uint32_t unicode_next,
int32_t * offset_y, void * user_data)
{
LV_UNUSED(font);
LV_UNUSED(unicode_next);
LV_UNUSED(offset_y);
LV_UNUSED(user_data);
LV_IMAGE_DECLARE(emoji_F617);
if(unicode == 0xF617) {
return &emoji_F617;
}
return NULL;
}
static lv_font_t * imgfont_create_cb(const lv_font_info_t * info, const void * src)
{
const imgfont_src_t * imgfont_src = src;
if(info->size < imgfont_src->match_size_min
|| info->size > imgfont_src->match_size_max) {
return NULL;
}
return lv_imgfont_create(info->size, imgfont_src->get_path_cb, NULL);
}
static void imgfont_delete_cb(lv_font_t * font)
{
lv_imgfont_destroy(font);
}
static void * imgfont_dup_src_cb(const void * src)
{
imgfont_src_t * imgfont_src = lv_malloc(sizeof(imgfont_src_t));
LV_ASSERT_MALLOC(imgfont_src);
lv_memcpy(imgfont_src, src, sizeof(imgfont_src_t));
return imgfont_src;
}
static void imgfont_free_src_cb(void * src)
{
lv_free(src);
}
static const lv_font_class_t imgfont_class = {
.create_cb = imgfont_create_cb,
.delete_cb = imgfont_delete_cb,
.dup_src_cb = imgfont_dup_src_cb,
.free_src_cb = imgfont_free_src_cb,
};
void lv_example_font_manager_3(void)
{
/* Create font manager, with 8 fonts recycling buffers */
g_font_manager = lv_font_manager_create(8);
/* Add font path mapping to font manager */
lv_font_manager_add_src_static(g_font_manager,
"Lato-Regular",
PATH_PREFIX "lvgl/examples/libs/freetype/Lato-Regular.ttf",
&lv_freetype_font_class);
/* Add custom imgfont source to font manager */
static const imgfont_src_t imgfont_src = {
.match_size_min = 70,
.match_size_max = 80,
.get_path_cb = get_imgfont_path,
};
lv_font_manager_add_src_static(g_font_manager,
"Emoji",
&imgfont_src,
&imgfont_class);
/* Create font from font manager */
lv_font_t * font = lv_font_manager_create_font(g_font_manager,
"Lato-Regular,Emoji",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
75,
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
if(!font) {
LV_LOG_ERROR("Could not create font");
return;
}
/* Create label with the font */
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_obj_set_style_text_font(label, font, 0);
lv_label_set_text(label, "Quiet\uF617~");
lv_obj_center(label);
}
#else
void lv_example_font_manager_3(void)
{
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "Font Manager or Freetype or Imgfont is not enabled");
lv_obj_center(label);
}
#endif
+1 -2
View File
@@ -1117,8 +1117,7 @@
#define LV_FILE_EXPLORER_QUICK_ACCESS 1
#endif
/** 1: Enable freetype font manager
* - Requires: LV_USE_FREETYPE */
/** 1: Enable Font manager */
#define LV_USE_FONT_MANAGER 0
#if LV_USE_FONT_MANAGER
+66
View File
@@ -69,10 +69,26 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f
static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
static unsigned int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res);
static lv_font_t * binfont_font_create_cb(const lv_font_info_t * info, const void * src);
static void binfont_font_delete_cb(lv_font_t * font);
static void * binfont_font_dup_src_cb(const void * src);
static void binfont_font_free_src_cb(void * src);
/**********************
* MACROS
**********************/
/**********************
* GLOBAL VARIABLES
**********************/
const lv_font_class_t lv_binfont_font_class = {
.create_cb = binfont_font_create_cb,
.delete_cb = binfont_font_delete_cb,
.dup_src_cb = binfont_font_dup_src_cb,
.free_src_cb = binfont_font_free_src_cb,
};
/**********************
* GLOBAL FUNCTIONS
**********************/
@@ -656,3 +672,53 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f
return kern_length;
}
static lv_font_t * binfont_font_create_cb(const lv_font_info_t * info, const void * src)
{
const lv_binfont_font_src_t * font_src = src;
if(info->size == font_src->font_size) {
if(font_src->path) {
return lv_binfont_create(font_src->path);
}
#if LV_USE_FS_MEMFS
return lv_binfont_create_from_buffer((void *)font_src->buffer, font_src->buffer_size);
#else
LV_LOG_WARN("LV_USE_FS_MEMFS not enabled");
return NULL;
#endif
}
return NULL;
}
static void binfont_font_delete_cb(lv_font_t * font)
{
lv_binfont_destroy(font);
}
static void * binfont_font_dup_src_cb(const void * src)
{
const lv_binfont_font_src_t * font_src = src;
lv_binfont_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_binfont_font_src_t));
LV_ASSERT_MALLOC(new_src);
*new_src = *font_src;
if(font_src->path) {
new_src->path = lv_strdup(font_src->path);
}
return new_src;
}
static void binfont_font_free_src_cb(void * src)
{
lv_binfont_font_src_t * font_src = src;
if(font_src->path) {
lv_free((char *)font_src->path);
font_src->path = NULL;
}
lv_free(font_src);
}
+10
View File
@@ -22,6 +22,16 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct {
uint32_t font_size; /**< Size of the font in pixels*/
const char * path; /**< Path to font file*/
const void * buffer; /**< Address of the font file in the memory*/
uint32_t buffer_size; /**< Size of the font file buffer*/
} lv_binfont_font_src_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_binfont_font_class;
/**********************
* GLOBAL PROTOTYPES
**********************/
+14
View File
@@ -154,6 +154,20 @@ const lv_font_t * lv_font_get_default(void)
return LV_FONT_DEFAULT;
}
bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_t * ft_info_2)
{
LV_ASSERT_NULL(ft_info_1);
LV_ASSERT_NULL(ft_info_2);
bool is_equal = (ft_info_1->size == ft_info_2->size
&& ft_info_1->style == ft_info_2->style
&& ft_info_1->render_mode == ft_info_2->render_mode
&& ft_info_1->kerning == ft_info_2->kerning
&& lv_strcmp(ft_info_1->name, ft_info_2->name) == 0);
return is_equal;
}
/**********************
* STATIC FUNCTIONS
**********************/
+24
View File
@@ -120,6 +120,22 @@ struct _lv_font_t {
void * user_data; /**< Custom user data for font.*/
};
struct _lv_font_class_t {
lv_font_t * (*create_cb)(const lv_font_info_t * info, const void * src); /**< Font creation callback function*/
void (*delete_cb)(lv_font_t * font); /**< Font deletion callback function*/
void * (*dup_src_cb)(const void * src); /**< Font source duplication callback function*/
void (*free_src_cb)(void * src); /**< Font source free callback function*/
};
struct _lv_font_info_t {
const char * name; /**< Font name, used to distinguish different font resources*/
const lv_font_class_t * class_p; /**< Font backend implementation*/
uint32_t size; /**< Font size in pixel*/
uint32_t render_mode; /**< Font rendering mode, see `lv_freetype_font_render_mode_t`*/
uint32_t style; /**< Font style, see `lv_freetype_font_style_t`*/
lv_font_kerning_t kerning; /**< Font kerning, see `lv_font_kerning_t`*/
};
/**********************
* GLOBAL PROTOTYPES
**********************/
@@ -181,6 +197,14 @@ void lv_font_set_kerning(lv_font_t * font, lv_font_kerning_t kerning);
*/
const lv_font_t * lv_font_get_default(void);
/**
* Compare font information.
* @param ft_info_1 font information 1.
* @param ft_info_2 font information 2.
* @return return true if the fonts are equal.
*/
bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_t * ft_info_2);
/**********************
* MACROS
**********************/
+70
View File
@@ -47,6 +47,11 @@ static int kern_pair_16_compare(const void * ref, const void * element);
static inline uint8_t rle_next(void);
#endif /*LV_USE_FONT_COMPRESSED*/
static lv_font_t * builtin_font_create_cb(const lv_font_info_t * info, const void * src);
static void builtin_font_delete_cb(lv_font_t * font);
static void * builtin_font_dup_src_cb(const void * src);
static void builtin_font_free_src_cb(void * src);
/**********************
* STATIC VARIABLES
**********************/
@@ -63,6 +68,13 @@ static const uint8_t opa3_table[8] = {0, 36, 73, 109, 146, 182, 218, 255};
static const uint8_t opa2_table[4] = {0, 85, 170, 255};
const lv_font_class_t lv_builtin_font_class = {
.create_cb = builtin_font_create_cb,
.delete_cb = builtin_font_delete_cb,
.dup_src_cb = builtin_font_dup_src_cb,
.free_src_cb = builtin_font_free_src_cb,
};
/**********************
* GLOBAL PROTOTYPES
**********************/
@@ -598,3 +610,61 @@ static int unicode_list_compare(const void * ref, const void * element)
{
return (*(uint16_t *)ref) - (*(uint16_t *)element);
}
static lv_font_t * builtin_font_create_cb(const lv_font_info_t * info, const void * src)
{
const lv_builtin_font_src_t * font_src = src;
/**
* If a crash occurs here, please check whether the last font in
* the lv_builtin_font_src array is set to NULL as required to mark the end of the array.
*/
while(font_src->font_p) {
if(info->size == font_src->size) {
return (lv_font_t *)font_src->font_p;
}
font_src++;
}
LV_LOG_WARN("No built-in font found with size: %" LV_PRIu32, info->size);
return NULL;
}
static void builtin_font_delete_cb(lv_font_t * font)
{
/*Nothing to delete*/
LV_UNUSED(font);
}
static void * builtin_font_dup_src_cb(const void * src)
{
const lv_builtin_font_src_t * font_src = src;
uint32_t len = 0;
/*Measure the size of the source data*/
/**
* If a crash occurs here, please check whether the last font in
* the lv_builtin_font_src array is set to NULL as required to mark the end of the array.
*/
while(font_src->font_p) {
len++;
font_src++;
}
if(len == 0) {
LV_LOG_WARN("No source data found");
return NULL;
}
lv_builtin_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_builtin_font_src_t) * (len + 1));
LV_ASSERT_MALLOC(new_src);
lv_memcpy(new_src, src, sizeof(lv_builtin_font_src_t) * len);
return new_src;
}
static void builtin_font_free_src_cb(void * src)
{
lv_free(src);
}
+7
View File
@@ -186,6 +186,13 @@ typedef struct {
uint16_t bitmap_format : 2;
} lv_font_fmt_txt_dsc_t;
typedef struct {
const lv_font_t * font_p; /**< Pointer to built-in font*/
uint32_t size; /** < Size of the built-in font*/
} lv_builtin_font_src_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_builtin_font_class;
/**********************
* GLOBAL PROTOTYPES
**********************/
+33
View File
@@ -50,10 +50,23 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u
static void cache_node_cache_free_cb(lv_freetype_cache_node_t * node, void * user_data);
static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cache_node_t * lhs,
const lv_freetype_cache_node_t * rhs);
static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src);
static void freetype_font_delete_cb(lv_font_t * font);
static void * freetype_font_dup_src_cb(const void * src);
static void freetype_font_free_src_cb(void * src);
/**********************
* STATIC VARIABLES
**********************/
const lv_font_class_t lv_freetype_font_class = {
.create_cb = freetype_font_create_cb,
.delete_cb = freetype_font_delete_cb,
.dup_src_cb = freetype_font_dup_src_cb,
.free_src_cb = freetype_font_free_src_cb,
};
/**********************
* MACROS
**********************/
@@ -415,4 +428,24 @@ static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cach
return 0;
}
static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src)
{
return lv_freetype_font_create(src, info->render_mode, info->size, info->style);
}
static void freetype_font_delete_cb(lv_font_t * font)
{
lv_freetype_font_delete(font);
}
static void * freetype_font_dup_src_cb(const void * src)
{
return lv_strdup(src);
}
static void freetype_font_free_src_cb(void * src)
{
lv_free(src);
}
#endif /*LV_USE_FREETYPE*/
+5
View File
@@ -61,6 +61,11 @@ typedef enum {
LV_FREETYPE_OUTLINE_BORDER_START, /* When line width > 0 the border glyph is drawn after the regular glyph */
} lv_freetype_outline_type_t;
/* Only path string is required */
typedef const char lv_freetype_font_src_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_freetype_font_class;
/**********************
* GLOBAL PROTOTYPES
**********************/
+68
View File
@@ -104,10 +104,23 @@ static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf
const tiny_ttf_cache_data_t * rhs);
static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc);
static lv_font_t * tiny_ttf_font_create_cb(const lv_font_info_t * info, const void * src);
static void tiny_ttf_font_delete_cb(lv_font_t * font);
static void * tiny_ttf_font_dup_src_cb(const void * src);
static void tiny_ttf_font_free_src_cb(void * src);
/**********************
* GLOBAL VARIABLES
**********************/
const lv_font_class_t lv_tiny_ttf_font_class = {
.create_cb = tiny_ttf_font_create_cb,
.delete_cb = tiny_ttf_font_delete_cb,
.dup_src_cb = tiny_ttf_font_dup_src_cb,
.free_src_cb = tiny_ttf_font_free_src_cb,
};
/**********************
* STATIC VARIABLES
**********************/
@@ -556,4 +569,59 @@ static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf
return 0;
}
static lv_font_t * tiny_ttf_font_create_cb(const lv_font_info_t * info, const void * src)
{
const lv_tiny_ttf_font_src_t * font_src = src;
if(font_src->path) {
#if LV_TINY_TTF_FILE_SUPPORT
if(font_src->cache_size) {
return lv_tiny_ttf_create_file_ex(font_src->path, info->size, info->kerning, font_src->cache_size);
}
return lv_tiny_ttf_create_file(font_src->path, info->size);
#else
LV_LOG_WARN("LV_TINY_TTF_FILE_SUPPORT not enabled");
return NULL;
#endif
}
if(font_src->cache_size) {
return lv_tiny_ttf_create_data_ex(font_src->data, font_src->data_size, info->size, info->kerning, font_src->cache_size);
}
return lv_tiny_ttf_create_data(font_src->data, font_src->data_size, info->size);
}
static void tiny_ttf_font_delete_cb(lv_font_t * font)
{
lv_tiny_ttf_destroy(font);
}
static void * tiny_ttf_font_dup_src_cb(const void * src)
{
const lv_tiny_ttf_font_src_t * font_src = src;
lv_tiny_ttf_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_tiny_ttf_font_src_t));
LV_ASSERT_MALLOC(new_src);
*new_src = *font_src;
if(font_src->path) {
new_src->path = lv_strdup(font_src->path);
}
return new_src;
}
static void tiny_ttf_font_free_src_cb(void * src)
{
lv_tiny_ttf_font_src_t * font_src = src;
if(font_src->path) {
lv_free((char *)font_src->path);
font_src->path = NULL;
}
lv_free(font_src);
}
#endif
+9
View File
@@ -25,6 +25,15 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct {
const char * path; /**< Path to the font file*/
const void * data; /**< Pointer to the font data*/
size_t data_size; /**< Size of the font data*/
size_t cache_size; /**< Size of the font cache*/
} lv_tiny_ttf_font_src_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_tiny_ttf_font_class;
/**********************
* GLOBAL PROTOTYPES
**********************/
+1 -2
View File
@@ -3550,8 +3550,7 @@
#endif
#endif
/** 1: Enable freetype font manager
* - Requires: LV_USE_FREETYPE */
/** 1: Enable Font manager */
#ifndef LV_USE_FONT_MANAGER
#ifdef CONFIG_LV_USE_FONT_MANAGER
#define LV_USE_FONT_MANAGER CONFIG_LV_USE_FONT_MANAGER
+4
View File
@@ -116,6 +116,10 @@ typedef struct _lv_theme_t lv_theme_t;
typedef struct _lv_anim_t lv_anim_t;
typedef struct _lv_font_t lv_font_t;
typedef struct _lv_font_class_t lv_font_class_t;
typedef struct _lv_font_info_t lv_font_info_t;
typedef struct _lv_font_manager_t lv_font_manager_t;
typedef struct _lv_image_decoder_t lv_image_decoder_t;
+117 -100
View File
@@ -12,8 +12,8 @@
#if LV_USE_FONT_MANAGER
#include "lv_font_manager_recycle.h"
#include "lv_font_manager_utils.h"
#include "../../lvgl.h"
#include "../../misc/lv_ll.h"
#include "../../stdlib/lv_sprintf.h"
/*********************
* DEFINES
@@ -28,16 +28,16 @@
/* font manager object */
struct _lv_font_manager_t {
lv_ll_t refer_ll; /* freetype font record list */
lv_ll_t refer_ll; /* font reference list */
lv_ll_t rec_ll; /* lvgl font record list */
lv_ll_t path_ll; /* font path record list */
lv_ll_t src_ll; /* font src record list */
lv_font_manager_recycle_t * recycle_manager;
};
/* freetype font reference node */
/* font reference node */
typedef struct _lv_font_refer_node_t {
lv_font_t * font_p; /* lv_freetype gen font */
lv_freetype_info_t ft_info; /* freetype font info */
lv_font_t * font_p;
lv_font_info_t ft_info;
char name[LV_FONT_MANAGER_NAME_MAX_LEN]; /* name buffer */
int ref_cnt; /* reference count */
} lv_font_refer_node_t;
@@ -45,36 +45,37 @@ typedef struct _lv_font_refer_node_t {
/* lvgl font record node */
typedef struct _lv_font_rec_node_t {
lv_font_t font; /* lvgl font info */
const lv_font_refer_node_t * refer_node_p; /* referenced freetype resource */
const lv_font_refer_node_t * refer_node_p; /* referenced font resource */
} lv_font_rec_node_t;
typedef struct _lv_font_path_t {
typedef struct _lv_font_src_t {
char * name;
char * path;
void * src;
bool is_static;
} lv_font_path_t;
const lv_font_class_t * class_p;
} lv_font_src_t;
/**********************
* STATIC PROTOTYPES
**********************/
static const char * lv_font_manager_get_path(lv_font_manager_t * manager, const char * name);
static lv_font_src_t * lv_font_manager_get_src(lv_font_manager_t * manager, const char * name);
static bool lv_font_manager_check_resource(lv_font_manager_t * manager);
static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t * manager, lv_font_t * font);
static const lv_font_refer_node_t * lv_font_manager_get_freetype_font(lv_font_manager_t * manager,
const lv_freetype_info_t * ft_info);
static bool lv_font_manager_reset_freetype_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node);
static const lv_font_refer_node_t * lv_font_manager_get_font(lv_font_manager_t * manager,
const lv_font_info_t * ft_info);
static bool lv_font_manager_drop_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node);
static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_freetype_info_t * ft_info);
static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_font_info_t * ft_info);
static bool lv_font_manager_delete_font_single(lv_font_manager_t * manager, lv_font_t * font);
static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_freetype_info_t * ft_info);
static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_font_info_t * ft_info);
static void lv_font_manager_delete_font_family(lv_font_manager_t * manager, lv_font_t * font);
static void lv_font_manager_add_path_core(lv_font_manager_t * manager, const char * name, const char * path,
bool is_static);
static bool lv_font_manager_add_src_core(lv_font_manager_t * manager, const char * name, const char * path,
const lv_font_class_t * class_p, bool is_static);
/**********************
* STATIC VARIABLES
@@ -96,7 +97,7 @@ lv_font_manager_t * lv_font_manager_create(uint32_t recycle_cache_size)
lv_ll_init(&manager->refer_ll, sizeof(lv_font_refer_node_t));
lv_ll_init(&manager->rec_ll, sizeof(lv_font_rec_node_t));
lv_ll_init(&manager->path_ll, sizeof(lv_font_path_t));
lv_ll_init(&manager->src_ll, sizeof(lv_font_src_t));
manager->recycle_manager = lv_font_manager_recycle_create(recycle_cache_size);
@@ -118,17 +119,18 @@ bool lv_font_manager_delete(lv_font_manager_t * manager)
lv_font_manager_recycle_delete(manager->recycle_manager);
/* clean path map */
lv_font_path_t * font_path;
LV_LL_READ(&manager->path_ll, font_path) {
if(!font_path->is_static) {
lv_free(font_path->name);
lv_free(font_path->path);
lv_font_src_t * font_src;
LV_LL_READ(&manager->src_ll, font_src) {
LV_LOG_INFO("remove src: %s", font_src->name);
if(!font_src->is_static) {
lv_free(font_src->name);
font_src->class_p->free_src_cb(font_src->src);
}
font_path->name = NULL;
font_path->path = NULL;
font_src->name = NULL;
font_src->src = NULL;
}
lv_ll_clear(&manager->path_ll);
lv_ll_clear(&manager->src_ll);
lv_free(manager);
@@ -136,59 +138,67 @@ bool lv_font_manager_delete(lv_font_manager_t * manager)
return true;
}
void lv_font_manager_add_path(lv_font_manager_t * manager, const char * name, const char * path)
bool lv_font_manager_add_src(lv_font_manager_t * manager,
const char * name,
const void * src,
const lv_font_class_t * class_p)
{
lv_font_manager_add_path_core(manager, name, path, false);
return lv_font_manager_add_src_core(manager, name, src, class_p, false);
}
void lv_font_manager_add_path_static(lv_font_manager_t * manager, const char * name, const char * path)
bool lv_font_manager_add_src_static(lv_font_manager_t * manager,
const char * name,
const void * src,
const lv_font_class_t * class_p)
{
lv_font_manager_add_path_core(manager, name, path, true);
return lv_font_manager_add_src_core(manager, name, src, class_p, true);
}
bool lv_font_manager_remove_path(lv_font_manager_t * manager, const char * name)
bool lv_font_manager_remove_src(lv_font_manager_t * manager, const char * name)
{
lv_font_path_t * font_path;
LV_LL_READ(&manager->path_ll, font_path) {
if(lv_strcmp(name, font_path->name) == 0) {
break;
}
}
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(name);
if(!font_path) {
LV_LOG_WARN("name: %s not found", name);
lv_font_src_t * font_src = lv_font_manager_get_src(manager, name);
if(!font_src) {
LV_LOG_WARN("src: %s not found", name);
return false;
}
lv_ll_remove(&manager->path_ll, font_path);
lv_ll_remove(&manager->src_ll, font_src);
if(!font_path->is_static) {
lv_free(font_path->name);
lv_free(font_path->path);
if(!font_src->is_static) {
lv_free(font_src->name);
font_src->class_p->free_src_cb(font_src->src);
}
font_path->name = NULL;
font_path->path = NULL;
font_src->name = NULL;
font_src->src = NULL;
lv_free(font_path);
lv_free(font_src);
LV_LOG_WARN("name: %s remove success", name);
LV_LOG_WARN("src: %s remove success", name);
return true;
}
lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager, const char * font_family, uint16_t render_mode,
uint32_t size, uint16_t style)
lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager,
const char * font_family,
uint32_t render_mode,
uint32_t size,
uint32_t style,
lv_font_kerning_t kerning)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(font_family);
lv_freetype_info_t ft_info;
lv_font_info_t ft_info;
lv_memzero(&ft_info, sizeof(ft_info));
ft_info.name = font_family;
ft_info.render_mode = render_mode;
ft_info.size = size;
ft_info.style = style;
ft_info.kerning = kerning;
lv_font_t * ret_font;
@@ -229,13 +239,12 @@ void lv_font_manager_delete_font(lv_font_manager_t * manager, lv_font_t * font)
* STATIC FUNCTIONS
**********************/
static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_freetype_info_t * ft_info)
static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
/* get freetype font */
const lv_font_refer_node_t * refer_node = lv_font_manager_get_freetype_font(manager, ft_info);
const lv_font_refer_node_t * refer_node = lv_font_manager_get_font(manager, ft_info);
if(!refer_node) {
return NULL;
}
@@ -245,10 +254,10 @@ static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manage
LV_ASSERT_MALLOC(rec_node);
lv_memzero(rec_node, sizeof(lv_font_rec_node_t));
/* copy freetype_font data */
/* copy font data */
rec_node->font = *refer_node->font_p;
/* record reference freetype_font */
/* record reference font */
rec_node->refer_node_p = refer_node;
LV_LOG_INFO("success");
@@ -274,8 +283,7 @@ static bool lv_font_manager_delete_font_single(lv_font_manager_t * manager, lv_f
return false;
}
/* reset freetype font resource */
bool retval = lv_font_manager_reset_freetype_font(manager, rec_node->refer_node_p);
bool retval = lv_font_manager_drop_font(manager, rec_node->refer_node_p);
LV_ASSERT(retval);
/* free rec_node */
@@ -304,7 +312,7 @@ static const char * strncpy_until(char * dest, const char * src, size_t n, char
return src;
}
static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_freetype_info_t * ft_info)
static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
@@ -316,7 +324,7 @@ static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manage
LV_LOG_INFO("font-family: %s", family_str);
char tmp_name[LV_FONT_MANAGER_NAME_MAX_LEN] = { 0 };
lv_freetype_info_t tmp_ft_info = *ft_info;
lv_font_info_t tmp_ft_info = *ft_info;
tmp_ft_info.name = tmp_name;
while(1) {
@@ -344,7 +352,7 @@ static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manage
}
if(*family_str != ',') {
LV_LOG_ERROR("font name buffer is too small, please increase FONT_NAME_MAX");
LV_LOG_ERROR("font name buffer is too small, please increase LV_FONT_MANAGER_NAME_MAX_LEN");
break;
}
@@ -368,44 +376,50 @@ static void lv_font_manager_delete_font_family(lv_font_manager_t * manager, lv_f
}
}
static void lv_font_manager_add_path_core(lv_font_manager_t * manager, const char * name, const char * path,
bool is_static)
static bool lv_font_manager_add_src_core(lv_font_manager_t * manager,
const char * name,
const char * src,
const lv_font_class_t * class_p,
bool is_static)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(name);
LV_ASSERT_NULL(path);
LV_ASSERT_NULL(src);
LV_ASSERT_NULL(class_p);
const char * old_path = lv_font_manager_get_path(manager, name);
if(old_path) {
LV_LOG_WARN("name: %s, path: %s already exists", name, old_path);
return;
if(lv_font_manager_get_src(manager, name)) {
LV_LOG_WARN("name: %s already exists", name);
return false;
}
lv_font_path_t * font_path = lv_ll_ins_tail(&manager->path_ll);
LV_ASSERT_MALLOC(font_path);
font_path->is_static = is_static;
lv_font_src_t * font_src = lv_ll_ins_tail(&manager->src_ll);
LV_ASSERT_MALLOC(font_src);
lv_memzero(font_src, sizeof(lv_font_src_t));
font_src->is_static = is_static;
font_src->class_p = class_p;
if(is_static) {
font_path->name = (char *)name;
font_path->path = (char *)path;
font_src->name = (char *)name;
font_src->src = (void *)src;
}
else {
font_path->name = lv_strdup(name);
LV_ASSERT_MALLOC(font_path->name);
font_src->name = lv_strdup(name);
LV_ASSERT_MALLOC(font_src->name);
font_path->path = lv_strdup(path);
LV_ASSERT_MALLOC(font_path->path);
font_src->src = font_src->class_p->dup_src_cb(src);
LV_ASSERT_NULL(font_src->src);
}
LV_LOG_INFO("name: %s, path: %s add success", name, path);
LV_LOG_INFO("name: %s, src: %p add success", name, src);
return true;
}
static const char * lv_font_manager_get_path(lv_font_manager_t * manager, const char * name)
static lv_font_src_t * lv_font_manager_get_src(lv_font_manager_t * manager, const char * name)
{
lv_font_path_t * font_path;
LV_LL_READ(&manager->path_ll, font_path) {
if(lv_strcmp(name, font_path->name) == 0) {
return font_path->path;
lv_font_src_t * font_src;
LV_LL_READ(&manager->src_ll, font_src) {
if(lv_strcmp(name, font_src->name) == 0) {
return font_src;
}
}
@@ -432,11 +446,11 @@ static bool lv_font_manager_check_resource(lv_font_manager_t * manager)
}
}
/* Check the recorded font resources created by freetype */
/* Check the recorded font resources created by font creater */
lv_ll_t * refer_ll = &manager->refer_ll;
uint32_t refer_ll_len = lv_ll_get_len(refer_ll);
if(refer_ll_len) {
LV_LOG_WARN("freetype font resource[%" LV_PRIu32 "]:", refer_ll_len);
LV_LOG_WARN("font resource[%" LV_PRIu32 "]:", refer_ll_len);
lv_font_refer_node_t * node;
LV_LL_READ(refer_ll, node) {
@@ -470,14 +484,14 @@ static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t *
}
static lv_font_refer_node_t * lv_font_manager_search_refer_node(lv_font_manager_t * manager,
const lv_freetype_info_t * ft_info)
const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
lv_font_refer_node_t * refer_node;
LV_LL_READ(&manager->refer_ll, refer_node) {
if(lv_freetype_info_is_equal(ft_info, &refer_node->ft_info)) {
if(lv_font_info_is_equal(ft_info, &refer_node->ft_info)) {
LV_LOG_INFO("font: %s(%d) matched", ft_info->name, ft_info->size);
return refer_node;
}
@@ -486,14 +500,14 @@ static lv_font_refer_node_t * lv_font_manager_search_refer_node(lv_font_manager_
return NULL;
}
static lv_font_t * lv_font_manager_create_font_warpper(lv_font_manager_t * manager, const lv_freetype_info_t * ft_info)
static lv_font_t * lv_font_manager_create_font_wrapper(lv_font_manager_t * manager, const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
lv_font_t * font;
/* create freetype font */
/* create font */
font = lv_font_manager_recycle_get_reuse(manager->recycle_manager, ft_info);
/* get reuse font from recycle */
@@ -503,16 +517,15 @@ static lv_font_t * lv_font_manager_create_font_warpper(lv_font_manager_t * manag
/* cache miss */
/* generate full file path */
const char * path = lv_font_manager_get_path(manager, ft_info->name);
if(!path) {
LV_LOG_ERROR("name: %s not found path", ft_info->name);
const lv_font_src_t * font_src = lv_font_manager_get_src(manager, ft_info->name);
if(!font_src) {
LV_LOG_ERROR("name: %s not found src", ft_info->name);
return NULL;
}
font = lv_freetype_font_create(path, ft_info->render_mode, ft_info->size, ft_info->style);
font = font_src->class_p->create_cb(ft_info, font_src->src);
if(!font) {
LV_LOG_ERROR("Freetype font init failed, name: %s, render_mode: %d, size: %d, style: %d",
LV_LOG_ERROR("font create failed, name: %s, render_mode: %d, size: %d, style: %d",
ft_info->name, ft_info->render_mode, ft_info->size, ft_info->style);
return NULL;
}
@@ -527,8 +540,8 @@ static void lv_font_manager_delete_font_warpper(lv_font_manager_t * manager, lv_
lv_font_manager_recycle_set_reuse(manager->recycle_manager, refer_node->font_p, &refer_node->ft_info);
}
static const lv_font_refer_node_t * lv_font_manager_get_freetype_font(lv_font_manager_t * manager,
const lv_freetype_info_t * ft_info)
static const lv_font_refer_node_t * lv_font_manager_get_font(lv_font_manager_t * manager,
const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
@@ -543,7 +556,7 @@ static const lv_font_refer_node_t * lv_font_manager_get_freetype_font(lv_font_ma
/* not found refer_node, start to create font */
lv_font_t * font = lv_font_manager_create_font_warpper(manager, ft_info);
lv_font_t * font = lv_font_manager_create_font_wrapper(manager, ft_info);
if(!font) {
return NULL;
@@ -556,17 +569,21 @@ static const lv_font_refer_node_t * lv_font_manager_get_freetype_font(lv_font_ma
lv_strncpy(refer_node->name, ft_info->name, sizeof(refer_node->name) - 1);
const lv_font_src_t * font_src = lv_font_manager_get_src(manager, ft_info->name);
LV_ASSERT_NULL(font_src);
/* copy font data */
refer_node->font_p = font;
refer_node->ft_info = *ft_info;
refer_node->ft_info.name = refer_node->name;
refer_node->ft_info.class_p = font_src->class_p;
refer_node->ref_cnt = 1;
LV_LOG_INFO("success");
return refer_node;
}
static bool lv_font_manager_reset_freetype_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node)
static bool lv_font_manager_drop_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(node);
+32 -23
View File
@@ -13,14 +13,10 @@ extern "C" {
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#include "../../font/lv_font.h"
#if LV_USE_FONT_MANAGER
#if !LV_USE_FREETYPE
#error "LV_USE_FONT_MANAGER requires LV_USE_FREETYPE"
#endif
/*********************
* DEFINES
*********************/
@@ -29,8 +25,6 @@ extern "C" {
* TYPEDEFS
**********************/
typedef struct _lv_font_manager_t lv_font_manager_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
@@ -50,40 +44,55 @@ lv_font_manager_t * lv_font_manager_create(uint32_t recycle_cache_size);
bool lv_font_manager_delete(lv_font_manager_t * manager);
/**
* Add the font file path.
* Add font resource.
* @param manager pointer to main font manager.
* @param name font name.
* @param path font file path.
* @param src font source. Need to strictly correspond to the font class.
* @param class_p font class. eg. lv_freetype_font_class, lv_builtin_font_class.
* @return return true if the add was successful.
*/
void lv_font_manager_add_path(lv_font_manager_t * manager, const char * name, const char * path);
bool lv_font_manager_add_src(lv_font_manager_t * manager,
const char * name,
const void * src,
const lv_font_class_t * class_p);
/**
* Add the font file path with static memory.
* Add font resource with static memory.
* @param manager pointer to main font manager.
* @param name font name.
* @param path font file path.
* @param name font name. It cannot be a local variable.
* @param src font source. Need to strictly correspond to the font class. And it cannot be a local variable.
* @param class_p font class. E.g. lv_freetype_font_class, lv_builtin_font_class.
* @return return true if the add was successful.
*/
void lv_font_manager_add_path_static(lv_font_manager_t * manager, const char * name, const char * path);
bool lv_font_manager_add_src_static(lv_font_manager_t * manager,
const char * name,
const void * src,
const lv_font_class_t * class_p);
/**
* Remove the font file path.
* Remove font resource.
* @param manager pointer to main font manager.
* @param name font name.
* @return return true if the remove was successful.
*/
bool lv_font_manager_remove_path(lv_font_manager_t * manager, const char * name);
bool lv_font_manager_remove_src(lv_font_manager_t * manager, const char * name);
/**
* Create font.
* @param manager pointer to main font manager.
* @param font_family font family name.
* @param render_mode font render mode, see lv_freetype_font_render_mode_t.
* @param size font size.
* @param style font style, see lv_freetype_font_style_t.
* @return point to the created font
* @param font_family font family name. Matches the font resource name, using commas to separate different names. E.g. "my_font_1,my_font_2".
* @param render_mode font render mode. see `lv_freetype_font_render_mode_t`.
* @param size font size in pixel.
* @param style font style. see `lv_freetype_font_style_t`.
* @param kerning kerning mode. see `lv_font_kerning_t`.
* @return point to the created font.
*/
lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager, const char * font_family, uint16_t render_mode,
uint32_t size, uint16_t style);
lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager,
const char * font_family,
uint32_t render_mode,
uint32_t size,
uint32_t style,
lv_font_kerning_t kerning);
/**
* Delete font.
@@ -11,7 +11,8 @@
#if LV_USE_FONT_MANAGER
#include "../../lvgl.h"
#include "../../font/lv_font.h"
#include "../../misc/lv_ll.h"
/*********************
* DEFINES
@@ -27,7 +28,7 @@ struct _lv_font_manager_recycle_t {
};
typedef struct {
lv_freetype_info_t ft_info;
lv_font_info_t ft_info;
char name[LV_FONT_MANAGER_NAME_MAX_LEN];
lv_font_t * font;
} lv_font_recycle_t;
@@ -87,7 +88,7 @@ void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager)
LV_LOG_INFO("success");
}
lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_freetype_info_t * ft_info)
lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
@@ -99,7 +100,7 @@ lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manage
lv_font_recycle_t * recycle;
LV_LL_READ(recycle_ll, recycle) {
/* match font */
if(lv_freetype_info_is_equal(ft_info, &recycle->ft_info)) {
if(lv_font_info_is_equal(ft_info, &recycle->ft_info)) {
lv_font_t * font = recycle->font;
LV_LOG_INFO("found font: %p", (void *)font);
@@ -116,7 +117,7 @@ lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manage
}
void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font,
const lv_freetype_info_t * ft_info)
const lv_font_info_t * ft_info)
{
LV_ASSERT_NULL(manager);
LV_ASSERT_NULL(ft_info);
@@ -124,7 +125,7 @@ void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_f
lv_ll_t * recycle_ll = &manager->recycle_ll;
/* check recycled size */
if(_lv_ll_get_len(recycle_ll) >= manager->max_size) {
if(lv_ll_get_len(recycle_ll) >= manager->max_size) {
LV_LOG_INFO("recycle full, remove tail font...");
lv_font_manager_recycle_remove_tail(manager);
}
@@ -154,7 +155,8 @@ static void lv_font_recycle_close(lv_font_manager_recycle_t * manager, lv_font_r
LV_ASSERT_NULL(recycle);
LV_LOG_INFO("font: %s(%d) close", recycle->ft_info.name, recycle->ft_info.size);
lv_freetype_font_delete(recycle->font);
recycle->ft_info.class_p->delete_cb(recycle->font);
recycle->font = NULL;
lv_ll_remove(&manager->recycle_ll, recycle);
lv_free(recycle);
@@ -14,7 +14,7 @@ extern "C" {
* INCLUDES
*********************/
#include "lv_font_manager_utils.h"
#include "../../misc/lv_types.h"
#if LV_USE_FONT_MANAGER
@@ -55,7 +55,7 @@ void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager);
* @param ft_info font info.
* @return returns true on success.
*/
lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_freetype_info_t * ft_info);
lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_font_info_t * ft_info);
/**
* Set fonts to be reused.
@@ -63,7 +63,7 @@ lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manage
* @param ft_info font info.
*/
void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font,
const lv_freetype_info_t * ft_info);
const lv_font_info_t * ft_info);
/**********************
* MACROS
@@ -1,56 +0,0 @@
/**
* @file lv_font_manager_utils.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_font_manager_utils.h"
#if LV_USE_FONT_MANAGER
#include "../../misc/lv_assert.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
bool lv_freetype_info_is_equal(const lv_freetype_info_t * ft_info_1, const lv_freetype_info_t * ft_info_2)
{
LV_ASSERT_NULL(ft_info_1);
LV_ASSERT_NULL(ft_info_2);
bool is_equal = (ft_info_1->size == ft_info_2->size
&& ft_info_1->style == ft_info_2->style
&& ft_info_1->render_mode == ft_info_2->render_mode
&& lv_strcmp(ft_info_1->name, ft_info_2->name) == 0);
return is_equal;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* LV_USE_FONT_MANAGER */
@@ -1,59 +0,0 @@
/**
* @file lv_font_manager_utils.h
*
*/
#ifndef LV_FONT_MANAGER_UTILS_H
#define LV_FONT_MANAGER_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_types.h"
#if LV_USE_FONT_MANAGER
#include "../../libs/freetype/lv_freetype.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
const char * name;
lv_freetype_font_render_mode_t render_mode;
lv_freetype_font_style_t style;
uint32_t size;
} lv_freetype_info_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Compare font information.
* @param ft_info_1 font information 1.
* @param ft_info_2 font information 2.
* @return return true if the fonts are equal.
*/
bool lv_freetype_info_is_equal(const lv_freetype_info_t * ft_info_1, const lv_freetype_info_t * ft_info_2);
/**********************
* MACROS
**********************/
#endif /*LV_USE_FONT_MANAGER*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* LV_FONT_MANAGER_UTILS_H */
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

+10 -8
View File
@@ -183,7 +183,7 @@ static lv_font_t * font_manager_font_create_cb(font_stress_ctx_t * ctx,
lv_freetype_font_style_t style)
{
TEST_ASSERT_NOT_NULL(ctx->font_manager);
return lv_font_manager_create_font(ctx->font_manager, name, render_mode, size, style);
return lv_font_manager_create_font(ctx->font_manager, name, render_mode, size, style, LV_FONT_KERNING_NONE);
}
static void font_manager_font_delete_cb(font_stress_ctx_t * ctx, lv_font_t * font)
@@ -248,11 +248,13 @@ void test_font_manager_stress(void)
g_ctx.font_manager = lv_font_manager_create(2);
TEST_ASSERT_NOT_NULL(g_ctx.font_manager);
lv_font_manager_add_path_static(g_ctx.font_manager, "NotoSansSC-Regular",
"./src/test_files/fonts/noto/NotoSansSC-Regular.ttf");
lv_font_manager_add_path_static(g_ctx.font_manager, "Arial", "../src/libs/freetype/arial.ttf");
lv_font_manager_add_path(g_ctx.font_manager, "Montserrat-Bold", "./src/test_files/fonts/Montserrat-Bold.ttf");
lv_font_manager_add_path(g_ctx.font_manager, "UNKNOWN", "UNKNOWN_FONT_PATH");
lv_font_manager_add_src_static(g_ctx.font_manager, "NotoSansSC-Regular",
"./src/test_files/fonts/noto/NotoSansSC-Regular.ttf",
&lv_freetype_font_class);
lv_font_manager_add_src_static(g_ctx.font_manager, "Arial", "../src/libs/freetype/arial.ttf", &lv_freetype_font_class);
lv_font_manager_add_src(g_ctx.font_manager, "Montserrat-Bold", "./src/test_files/fonts/Montserrat-Bold.ttf",
&lv_freetype_font_class);
lv_font_manager_add_src(g_ctx.font_manager, "UNKNOWN", "UNKNOWN_FONT_PATH", &lv_freetype_font_class);
static const char * font_name_arr[] = {
"NotoSansSC-Regular,Arial",
@@ -280,10 +282,10 @@ void test_font_manager_stress(void)
font_stress_label_delete_all(&g_ctx);
bool remove_ok = lv_font_manager_remove_path(g_ctx.font_manager, "Arial");
bool remove_ok = lv_font_manager_remove_src(g_ctx.font_manager, "Arial");
TEST_ASSERT_TRUE(remove_ok);
remove_ok = lv_font_manager_remove_path(g_ctx.font_manager, "UNKNOWN");
remove_ok = lv_font_manager_remove_src(g_ctx.font_manager, "UNKNOWN");
TEST_ASSERT_TRUE(remove_ok);
bool success = lv_font_manager_delete(g_ctx.font_manager);
+247
View File
@@ -0,0 +1,247 @@
#if LV_BUILD_TEST
#include "../lvgl.h"
#include "unity/unity.h"
#if LV_USE_FONT_MANAGER \
&& LV_FONT_MONTSERRAT_14 && LV_FONT_MONTSERRAT_32 \
&& LV_USE_FREETYPE \
&& LV_USE_TINY_TTF && LV_TINY_TTF_FILE_SUPPORT
/**
* There are some differences between the rendering of FreeType in 64-bit and 32-bit,
* so we compare them separately here.
*/
#ifndef NON_AMD64_BUILD
#define EXT_NAME ".lp64.png"
#else
#define EXT_NAME ".lp32.png"
#endif
static lv_font_manager_t * g_font_manager = NULL;
typedef bool (*add_src_cb_t)(lv_font_manager_t * manager,
const char * name,
const void * src,
const lv_font_class_t * class_p);
void setUp(void)
{
}
void tearDown(void)
{
lv_obj_clean(lv_screen_active());
}
static void test_font_manager_src(add_src_cb_t add_src_cb)
{
g_font_manager = lv_font_manager_create(2);
TEST_ASSERT_NOT_NULL(g_font_manager);
/* Register built-in font sources */
static lv_builtin_font_src_t builtin_font_src[3] = { 0 };
builtin_font_src[0].font_p = &lv_font_montserrat_14;
builtin_font_src[0].size = 14;
builtin_font_src[1].font_p = &lv_font_montserrat_32;
builtin_font_src[1].size = 32;
/* IMPORTANT! Marking the end of the array */
builtin_font_src[2].font_p = NULL;
builtin_font_src[2].size = 0;
bool add_src_result = add_src_cb(g_font_manager,
"Montserrat",
builtin_font_src,
&lv_builtin_font_class);
TEST_ASSERT_TRUE(add_src_result);
/* Try to add the same source again, should fail */
add_src_result = add_src_cb(g_font_manager,
"Montserrat",
builtin_font_src,
&lv_builtin_font_class);
TEST_ASSERT_FALSE(add_src_result);
/* Register FreeType font source */
add_src_result = add_src_cb(g_font_manager,
"NotoSansSC-Regular",
"./src/test_files/fonts/noto/NotoSansSC-Regular.ttf",
&lv_freetype_font_class);
TEST_ASSERT_TRUE(add_src_result);
/* Register TinyTTF font source */
extern const uint8_t test_ubuntu_font[];
extern size_t test_ubuntu_font_size;
static lv_tiny_ttf_font_src_t tiny_ttf_font_data_src = { 0 };
tiny_ttf_font_data_src.data = test_ubuntu_font;
tiny_ttf_font_data_src.data_size = test_ubuntu_font_size;
add_src_result = add_src_cb(g_font_manager,
"Ubuntu-Medium",
&tiny_ttf_font_data_src,
&lv_tiny_ttf_font_class);
TEST_ASSERT_TRUE(add_src_result);
static lv_tiny_ttf_font_src_t tiny_ttf_font_file_src = { 0 };
tiny_ttf_font_file_src.path = "A:src/test_files/fonts/noto/NotoSansSC-Regular.ttf";
add_src_result = add_src_cb(g_font_manager,
"NotoSansSC-Regular-2",
&tiny_ttf_font_file_src,
&lv_tiny_ttf_font_class);
TEST_ASSERT_TRUE(add_src_result);
/* Register binary font source */
static const lv_binfont_font_src_t binfont_font_file_src = {
.font_size = 20,
.path = "A:src/test_assets/test_font_3.fnt",
.buffer = NULL,
.buffer_size = 0,
};
add_src_result = add_src_cb(g_font_manager,
"RobotoMono-Regular-file",
&binfont_font_file_src,
&lv_binfont_font_class);
TEST_ASSERT_TRUE(add_src_result);
extern uint8_t const test_font_3_buf[4892];
static lv_binfont_font_src_t binfont_font_buffer_src = { 0 };
binfont_font_buffer_src.font_size = 20;
binfont_font_buffer_src.buffer = test_font_3_buf;
binfont_font_buffer_src.buffer_size = sizeof(test_font_3_buf);
add_src_result = add_src_cb(g_font_manager,
"RobotoMono-Regular-buffer",
&binfont_font_buffer_src,
&lv_binfont_font_class);
TEST_ASSERT_TRUE(add_src_result);
/* Create font from font manager */
/* Try to create font with unknown name, should fail */
lv_font_t * font_unknown = lv_font_manager_create_font(g_font_manager,
"UNKNOWN_FONT_NAME",
0,
10,
0,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NULL(font_unknown);
lv_font_t * font_14 = lv_font_manager_create_font(g_font_manager,
"NotoSansSC-Regular,Ubuntu-Medium,Montserrat,UNKNOWN_FONT_NAME",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
14,
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NOT_NULL(font_14);
lv_font_t * font_32 = lv_font_manager_create_font(g_font_manager,
"Ubuntu-Medium,NotoSansSC-Regular,Montserrat",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
32,
LV_FREETYPE_FONT_STYLE_NORMAL,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NOT_NULL(font_32);
lv_font_t * font_40 = lv_font_manager_create_font(g_font_manager,
"Ubuntu-Medium,NotoSansSC-Regular-2,Montserrat",
0,
40,
0,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NOT_NULL(font_40);
lv_font_t * font_file_20 = lv_font_manager_create_font(g_font_manager,
"RobotoMono-Regular-file,NotoSansSC-Regular-2",
0,
20,
0,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NOT_NULL(font_file_20);
lv_font_t * font_buffer_20 = lv_font_manager_create_font(g_font_manager,
"RobotoMono-Regular-buffer,NotoSansSC-Regular-2",
0,
20,
0,
LV_FONT_KERNING_NONE);
TEST_ASSERT_NOT_NULL(font_file_20);
/* Create label with the font */
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_set_text(label,
"这是一段中文。\n"
"This is a English text.\n"
"Symbols: " LV_SYMBOL_OK LV_SYMBOL_CLOSE);
lv_obj_center(label);
lv_obj_set_style_text_font(label, font_14, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/font_manager_1" EXT_NAME);
lv_obj_set_style_text_font(label, font_32, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/font_manager_2" EXT_NAME);
lv_obj_set_style_text_font(label, font_40, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/font_manager_3" EXT_NAME);
/* Freetype fonts have not been tested, so there is no need to distinguish and process images */
lv_obj_set_style_text_font(label, font_file_20, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/font_manager_4.png");
/* Rendered images should be the same */
lv_obj_set_style_text_font(label, font_buffer_20, 0);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/font_manager_4.png");
/* Should not be deleted successfully, because it is used by the label */
bool delete_result = lv_font_manager_delete(g_font_manager);
TEST_ASSERT_FALSE(delete_result);
lv_obj_delete(label);
lv_font_manager_delete_font(g_font_manager, font_14);
lv_font_manager_delete_font(g_font_manager, font_32);
lv_font_manager_delete_font(g_font_manager, font_40);
lv_font_manager_delete_font(g_font_manager, font_file_20);
lv_font_manager_delete_font(g_font_manager, font_buffer_20);
/* Trying to delete a font that was not created by the font manager, it needs to handle this situation */
lv_font_manager_delete_font(g_font_manager, (lv_font_t *)LV_FONT_DEFAULT);
lv_font_manager_delete_font(g_font_manager, (lv_font_t *)&lv_font_montserrat_32);
delete_result = lv_font_manager_delete(g_font_manager);
TEST_ASSERT_TRUE(delete_result);
g_font_manager = NULL;
}
void test_font_manager_src_normal(void)
{
test_font_manager_src(lv_font_manager_add_src);
}
void test_font_manager_src_static(void)
{
test_font_manager_src(lv_font_manager_add_src_static);
}
#else
void setUp(void)
{
}
void tearDown(void)
{
}
void test_font_manager_src_normal(void)
{
}
void test_font_manager_src_static(void)
{
}
#endif
#endif /* LV_BUILD_TEST */