Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/libs/lvgl/lv_objx/lv_img.c
1476 views
1
/**
2
* @file lv_img.c
3
*
4
*/
5
6
/*********************
7
* INCLUDES
8
*********************/
9
#include "lv_img.h"
10
#if USE_LV_IMG != 0
11
12
/*Testing of dependencies*/
13
#if USE_LV_LABEL == 0
14
#error "lv_img: lv_label is required. Enable it in lv_conf.h (USE_LV_LABEL 1) "
15
#endif
16
17
#include "../lv_core/lv_lang.h"
18
#include "../lv_themes/lv_theme.h"
19
#include "../lv_misc/lv_fs.h"
20
#include "../lv_misc/lv_ufs.h"
21
#include "../lv_misc/lv_txt.h"
22
#include "../lv_misc/lv_log.h"
23
24
/*********************
25
* DEFINES
26
*********************/
27
28
/**********************
29
* TYPEDEFS
30
**********************/
31
32
/**********************
33
* STATIC PROTOTYPES
34
**********************/
35
static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode_t mode);
36
static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param);
37
38
/**********************
39
* STATIC VARIABLES
40
**********************/
41
static lv_signal_func_t ancestor_signal;
42
43
/**********************
44
* MACROS
45
**********************/
46
47
/**********************
48
* GLOBAL FUNCTIONS
49
**********************/
50
51
/**
52
* Create an image objects
53
* @param par pointer to an object, it will be the parent of the new button
54
* @param copy pointer to a image object, if not NULL then the new object will be copied from it
55
* @return pointer to the created image
56
*/
57
lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy)
58
{
59
LV_LOG_TRACE("image create started");
60
61
lv_obj_t * new_img = NULL;
62
63
/*Create a basic object*/
64
new_img = lv_obj_create(par, copy);
65
lv_mem_assert(new_img);
66
if(new_img == NULL) return NULL;
67
68
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_img);
69
70
/*Extend the basic object to image object*/
71
lv_img_ext_t * ext = lv_obj_allocate_ext_attr(new_img, sizeof(lv_img_ext_t));
72
lv_mem_assert(ext);
73
if(ext == NULL) return NULL;
74
75
ext->src = NULL;
76
ext->src_type = LV_IMG_SRC_UNKNOWN;
77
ext->cf = LV_IMG_CF_UNKOWN;
78
ext->w = lv_obj_get_width(new_img);
79
ext->h = lv_obj_get_height(new_img);
80
ext->auto_size = 1;
81
#if USE_LV_MULTI_LANG
82
ext->lang_txt_id = LV_LANG_TXT_ID_NONE;
83
#endif
84
85
/*Init the new object*/
86
lv_obj_set_signal_func(new_img, lv_img_signal);
87
lv_obj_set_design_func(new_img, lv_img_design);
88
89
if(copy == NULL) {
90
lv_obj_set_click(new_img, false);
91
/* Enable auto size for non screens
92
* because image screens are wallpapers
93
* and must be screen sized*/
94
if(par != NULL) {
95
ext->auto_size = 1;
96
lv_obj_set_style(new_img, NULL); /*Inherit the style by default*/
97
} else {
98
ext->auto_size = 0;
99
lv_obj_set_style(new_img, &lv_style_plain); /*Set a style for screens*/
100
}
101
} else {
102
lv_img_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
103
ext->auto_size = copy_ext->auto_size;
104
lv_img_set_src(new_img, copy_ext->src);
105
106
/*Refresh the style with new signal function*/
107
lv_obj_refresh_style(new_img);
108
}
109
110
111
LV_LOG_INFO("image created");
112
113
return new_img;
114
}
115
116
117
/*=====================
118
* Setter functions
119
*====================*/
120
121
122
/**
123
* Set the pixel map to display by the image
124
* @param img pointer to an image object
125
* @param data the image data
126
*/
127
void lv_img_set_src(lv_obj_t * img, const void * src_img)
128
{
129
lv_img_src_t src_type = lv_img_src_get_type(src_img);
130
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
131
132
#if LV_LOG_LEVEL >= LV_LOG_LEVEL_INFO
133
switch(src_type) {
134
case LV_IMG_SRC_FILE:
135
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_FILE` type found");
136
break;
137
case LV_IMG_SRC_VARIABLE:
138
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found");
139
break;
140
case LV_IMG_SRC_SYMBOL:
141
LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_SYMBOL` type found");
142
break;
143
default:
144
LV_LOG_WARN("lv_img_set_src: unknown type");
145
}
146
#endif
147
148
/*If the new source type is unknown free the memories of the old source*/
149
if(src_type == LV_IMG_SRC_UNKNOWN) {
150
LV_LOG_WARN("lv_img_set_src: unknown image type");
151
if(ext->src_type == LV_IMG_SRC_SYMBOL || ext->src_type == LV_IMG_SRC_FILE) {
152
lv_mem_free(ext->src);
153
}
154
ext->src = NULL;
155
ext->src_type = LV_IMG_SRC_UNKNOWN;
156
return;
157
}
158
159
lv_img_header_t header;
160
lv_img_dsc_get_info(src_img, &header);
161
162
163
164
/*Save the source*/
165
if(src_type == LV_IMG_SRC_VARIABLE) {
166
LV_LOG_INFO("lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found");
167
168
/*If memory was allocated because of the previous `src_type` then free it*/
169
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
170
lv_mem_free(ext->src);
171
}
172
ext->src = src_img;
173
} else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) {
174
/* If the new and the old src are the same then it was only a refresh.*/
175
if(ext->src != src_img) {
176
/*If memory was allocated because of the previous `src_type` then free it*/
177
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
178
lv_mem_free(ext->src);
179
}
180
char * new_str = lv_mem_alloc(strlen(src_img) + 1);
181
lv_mem_assert(new_str);
182
if(new_str == NULL) return;
183
strcpy(new_str, src_img);
184
ext->src = new_str;
185
}
186
}
187
188
if(src_type == LV_IMG_SRC_SYMBOL) {
189
/*`lv_img_dsc_get_info` couldn't set the with and height of a font so set it here*/
190
lv_style_t * style = lv_img_get_style(img);
191
lv_point_t size;
192
lv_txt_get_size(&size, src_img, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, LV_TXT_FLAG_NONE);
193
header.w = size.x;
194
header.h = size.y;
195
}
196
197
ext->src_type = src_type;
198
ext->w = header.w;
199
ext->h = header.h;
200
ext->cf = header.cf;
201
202
if(lv_img_get_auto_size(img) != false) {
203
lv_obj_set_size(img, ext->w, ext->h);
204
}
205
206
lv_obj_invalidate(img);
207
}
208
209
#if USE_LV_MULTI_LANG
210
/**
211
* Set an ID which means a the same source but in different languages
212
* @param img pointer to an image object
213
* @param src_id ID of the source
214
*/
215
void lv_img_set_src_id(lv_obj_t * img, uint32_t src_id)
216
{
217
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
218
ext->lang_txt_id = src_id;
219
220
/*Apply the new language*/
221
img->signal_func(img, LV_SIGNAL_LANG_CHG, NULL);
222
}
223
#endif
224
225
/**
226
* Enable the auto size feature.
227
* If enabled the object size will be same as the picture size.
228
* @param img pointer to an image
229
* @param en true: auto size enable, false: auto size disable
230
*/
231
void lv_img_set_auto_size(lv_obj_t * img, bool en)
232
{
233
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
234
235
ext->auto_size = (en == false ? 0 : 1);
236
}
237
238
239
/*=====================
240
* Getter functions
241
*====================*/
242
243
244
/**
245
* Get the source of the image
246
* @param img pointer to an image object
247
* @return the image source (symbol, file name or C array)
248
*/
249
const void * lv_img_get_src(lv_obj_t * img)
250
{
251
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
252
253
return ext->src;
254
}
255
256
/**
257
* Get the name of the file set for an image
258
* @param img pointer to an image
259
* @return file name
260
*/
261
const char * lv_img_get_file_name(const lv_obj_t * img)
262
{
263
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
264
265
if(ext->src_type == LV_IMG_SRC_FILE) return ext->src;
266
else return "";
267
}
268
269
#if USE_LV_MULTI_LANG
270
/**
271
* Get the source ID of the image. (Used by the multi-language feature)
272
* @param img pointer to an image
273
* @return ID of the source
274
*/
275
uint16_t lv_img_get_src_id(lv_obj_t * img)
276
{
277
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
278
return ext->lang_txt_id;
279
}
280
#endif
281
282
/**
283
* Get the auto size enable attribute
284
* @param img pointer to an image
285
* @return true: auto size is enabled, false: auto size is disabled
286
*/
287
bool lv_img_get_auto_size(const lv_obj_t * img)
288
{
289
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
290
291
return ext->auto_size == 0 ? false : true;
292
}
293
294
/**********************
295
* STATIC FUNCTIONS
296
**********************/
297
298
/**
299
* Handle the drawing related tasks of the images
300
* @param img pointer to an object
301
* @param mask the object will be drawn only in this area
302
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
303
* (return 'true' if yes)
304
* LV_DESIGN_DRAW: draw the object (always return 'true')
305
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
306
* @param return true/false, depends on 'mode'
307
*/
308
static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode_t mode)
309
{
310
lv_style_t * style = lv_obj_get_style(img);
311
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
312
313
if(mode == LV_DESIGN_COVER_CHK) {
314
bool cover = false;
315
if(ext->src_type == LV_IMG_SRC_UNKNOWN || ext->src_type == LV_IMG_SRC_SYMBOL) return false;
316
317
if(ext->cf == LV_IMG_CF_TRUE_COLOR || ext->cf == LV_IMG_CF_RAW) cover = lv_area_is_in(mask, &img->coords);
318
319
return cover;
320
} else if(mode == LV_DESIGN_DRAW_MAIN) {
321
if(ext->h == 0 || ext->w == 0) return true;
322
lv_area_t coords;
323
lv_opa_t opa_scale = lv_obj_get_opa_scale(img);
324
325
lv_obj_get_coords(img, &coords);
326
327
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) {
328
LV_LOG_TRACE("lv_img_design: start to draw image");
329
lv_area_t cords_tmp;
330
cords_tmp.y1 = coords.y1;
331
cords_tmp.y2 = coords.y1 + ext->h - 1;
332
333
for(; cords_tmp.y1 < coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) {
334
cords_tmp.x1 = coords.x1;
335
cords_tmp.x2 = coords.x1 + ext->w - 1;
336
for(; cords_tmp.x1 < coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) {
337
lv_draw_img(&cords_tmp, mask, ext->src, style, opa_scale);
338
}
339
}
340
} else if(ext->src_type == LV_IMG_SRC_SYMBOL) {
341
LV_LOG_TRACE("lv_img_design: start to draw symbol");
342
lv_style_t style_mod;
343
lv_style_copy(&style_mod, style);
344
style_mod.text.color = style->image.color;
345
lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL);
346
} else {
347
/*Trigger the error handler of image drawer*/
348
LV_LOG_WARN("lv_img_design: image source type is unknown");
349
lv_draw_img(&img->coords, mask, NULL, style, opa_scale);
350
}
351
}
352
353
return true;
354
}
355
356
357
/**
358
* Signal function of the image
359
* @param img pointer to an image object
360
* @param sign a signal type from lv_signal_t enum
361
* @param param pointer to a signal specific variable
362
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
363
*/
364
static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
365
{
366
lv_res_t res;
367
368
/* Include the ancient signal function */
369
res = ancestor_signal(img, sign, param);
370
if(res != LV_RES_OK) return res;
371
372
lv_img_ext_t * ext = lv_obj_get_ext_attr(img);
373
if(sign == LV_SIGNAL_CLEANUP) {
374
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
375
lv_mem_free(ext->src);
376
ext->src = NULL;
377
ext->src_type = LV_IMG_SRC_UNKNOWN;
378
}
379
} else if(sign == LV_SIGNAL_STYLE_CHG) {
380
/*Refresh the file name to refresh the symbol text size*/
381
if(ext->src_type == LV_IMG_SRC_SYMBOL) {
382
lv_img_set_src(img, ext->src);
383
384
}
385
} else if(sign == LV_SIGNAL_LANG_CHG) {
386
#if USE_LV_MULTI_LANG
387
if(ext->lang_txt_id != LV_LANG_TXT_ID_NONE) {
388
const char * lang_src = lv_lang_get_text(ext->lang_txt_id);
389
if(lang_src) {
390
lv_img_set_src(img, lang_src);
391
} else {
392
LV_LOG_WARN("lv_lang_get_text return NULL for an image's source");
393
}
394
}
395
#endif
396
} else if(sign == LV_SIGNAL_GET_TYPE) {
397
lv_obj_type_t * buf = param;
398
uint8_t i;
399
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
400
if(buf->type[i] == NULL) break;
401
}
402
buf->type[i] = "lv_img";
403
}
404
405
return res;
406
}
407
408
#endif
409
410