1 /**
2  * @file lv_font_manager_recycle.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lv_font_manager_recycle.h"
11 
12 #if LV_USE_FONT_MANAGER
13 
14 #include "../../lvgl.h"
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 
20 /**********************
21  *      TYPEDEFS
22  **********************/
23 
24 struct _lv_font_manager_recycle_t {
25     lv_ll_t recycle_ll;
26     uint32_t max_size;
27 };
28 
29 typedef struct {
30     lv_freetype_info_t ft_info;
31     char name[LV_FONT_MANAGER_NAME_MAX_LEN];
32     lv_font_t * font;
33 } lv_font_recycle_t;
34 
35 /**********************
36  *  STATIC PROTOTYPES
37  **********************/
38 
39 static void lv_font_recycle_close(lv_font_manager_recycle_t * manager, lv_font_recycle_t * recycle);
40 static void lv_font_manager_recycle_remove_tail(lv_font_manager_recycle_t * manager);
41 
42 /**********************
43  *  STATIC VARIABLES
44  **********************/
45 
46 /**********************
47  *      MACROS
48  **********************/
49 
50 /**********************
51  *   GLOBAL FUNCTIONS
52  **********************/
53 
lv_font_manager_recycle_create(uint32_t max_size)54 lv_font_manager_recycle_t * lv_font_manager_recycle_create(uint32_t max_size)
55 {
56     lv_font_manager_recycle_t * manager = lv_malloc_zeroed(sizeof(lv_font_manager_recycle_t));
57     LV_ASSERT_MALLOC(manager);
58     if(!manager) {
59         LV_LOG_ERROR("malloc failed for lv_font_manager_recycle_t");
60         return NULL;
61     }
62 
63     lv_ll_init(&manager->recycle_ll, sizeof(lv_font_recycle_t));
64     manager->max_size = max_size;
65 
66     LV_LOG_INFO("success");
67     return manager;
68 }
69 
lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager)70 void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager)
71 {
72     LV_ASSERT_NULL(manager);
73 
74     lv_ll_t * recycle_ll = &manager->recycle_ll;
75 
76     lv_font_recycle_t * recycle = lv_ll_get_head(recycle_ll);
77 
78     /* clear all recycle */
79     while(recycle != NULL) {
80         lv_font_recycle_t * recycle_next = lv_ll_get_next(recycle_ll, recycle);
81         lv_font_recycle_close(manager, recycle);
82         recycle = recycle_next;
83     }
84 
85     lv_free(manager);
86 
87     LV_LOG_INFO("success");
88 }
89 
lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager,const lv_freetype_info_t * ft_info)90 lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_freetype_info_t * ft_info)
91 {
92     LV_ASSERT_NULL(manager);
93     LV_ASSERT_NULL(ft_info);
94 
95     lv_ll_t * recycle_ll = &manager->recycle_ll;
96 
97     LV_LOG_INFO("font: %s(%d) searching...", ft_info->name, ft_info->size);
98 
99     lv_font_recycle_t * recycle;
100     LV_LL_READ(recycle_ll, recycle) {
101         /* match font */
102         if(lv_freetype_info_is_equal(ft_info, &recycle->ft_info)) {
103             lv_font_t * font = recycle->font;
104             LV_LOG_INFO("found font: %p", (void *)font);
105 
106             /* remove reused font */
107             lv_ll_remove(recycle_ll, recycle);
108             lv_free(recycle);
109             return font;
110         }
111     }
112 
113     LV_LOG_INFO("NOT found");
114 
115     return false;
116 }
117 
lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager,lv_font_t * font,const lv_freetype_info_t * ft_info)118 void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font,
119                                        const lv_freetype_info_t * ft_info)
120 {
121     LV_ASSERT_NULL(manager);
122     LV_ASSERT_NULL(ft_info);
123 
124     lv_ll_t * recycle_ll = &manager->recycle_ll;
125 
126     /* check recycled size */
127     if(_lv_ll_get_len(recycle_ll) >= manager->max_size) {
128         LV_LOG_INFO("recycle full, remove tail font...");
129         lv_font_manager_recycle_remove_tail(manager);
130     }
131 
132     /* record reuse font */
133     lv_font_recycle_t * recycle = lv_ll_ins_head(recycle_ll);
134     LV_ASSERT_MALLOC(recycle);
135     lv_memzero(recycle, sizeof(lv_font_recycle_t));
136 
137     lv_strncpy(recycle->name, ft_info->name, sizeof(recycle->name));
138     recycle->name[sizeof(recycle->name) - 1] = '\0';
139 
140     recycle->font = font;
141     recycle->ft_info = *ft_info;
142     recycle->ft_info.name = recycle->name;
143 
144     LV_LOG_INFO("insert font: %s(%d) to reuse list", ft_info->name, ft_info->size);
145 }
146 
147 /**********************
148  *   STATIC FUNCTIONS
149  **********************/
150 
lv_font_recycle_close(lv_font_manager_recycle_t * manager,lv_font_recycle_t * recycle)151 static void lv_font_recycle_close(lv_font_manager_recycle_t * manager, lv_font_recycle_t * recycle)
152 {
153     LV_ASSERT_NULL(manager);
154     LV_ASSERT_NULL(recycle);
155 
156     LV_LOG_INFO("font: %s(%d) close", recycle->ft_info.name, recycle->ft_info.size);
157     lv_freetype_font_delete(recycle->font);
158 
159     lv_ll_remove(&manager->recycle_ll, recycle);
160     lv_free(recycle);
161 }
162 
lv_font_manager_recycle_remove_tail(lv_font_manager_recycle_t * manager)163 static void lv_font_manager_recycle_remove_tail(lv_font_manager_recycle_t * manager)
164 {
165     lv_font_recycle_t * tail = lv_ll_get_tail(&manager->recycle_ll);
166     LV_ASSERT_NULL(tail);
167     lv_font_recycle_close(manager, tail);
168 }
169 
170 #endif /* LV_USE_FONT_MANAGER */
171