1 /**
2 * @file lv_obj_draw.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_obj_draw.h"
10 #include "lv_obj.h"
11 #include "lv_disp.h"
12 #include "lv_indev.h"
13
14 /*********************
15 * DEFINES
16 *********************/
17 #define MY_CLASS &lv_obj_class
18
19 /**********************
20 * TYPEDEFS
21 **********************/
22
23 /**********************
24 * STATIC PROTOTYPES
25 **********************/
26
27 /**********************
28 * STATIC VARIABLES
29 **********************/
30
31 /**********************
32 * MACROS
33 **********************/
34
35 /**********************
36 * GLOBAL FUNCTIONS
37 **********************/
38
lv_obj_init_draw_rect_dsc(lv_obj_t * obj,uint32_t part,lv_draw_rect_dsc_t * draw_dsc)39 void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc)
40 {
41 lv_opa_t opa = LV_OPA_COVER;
42 if(part != LV_PART_MAIN) {
43 opa = lv_obj_get_style_opa(obj, part);
44 if(opa <= LV_OPA_MIN) {
45 draw_dsc->bg_opa = LV_OPA_TRANSP;
46 draw_dsc->bg_img_opa = LV_OPA_TRANSP;
47 draw_dsc->border_opa = LV_OPA_TRANSP;
48 draw_dsc->outline_opa = LV_OPA_TRANSP;
49 draw_dsc->shadow_opa = LV_OPA_TRANSP;
50 return;
51 }
52 }
53
54 #if LV_DRAW_COMPLEX
55 if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
56
57 draw_dsc->radius = lv_obj_get_style_radius(obj, part);
58
59 if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
60 draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
61 if(draw_dsc->bg_opa > LV_OPA_MIN) {
62 draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
63 const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part);
64 if(grad && grad->dir != LV_GRAD_DIR_NONE) {
65 lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad));
66 }
67 else {
68 draw_dsc->bg_grad.dir = lv_obj_get_style_bg_grad_dir(obj, part);
69 if(draw_dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
70 draw_dsc->bg_grad.stops[0].color = lv_obj_get_style_bg_color_filtered(obj, part);
71 draw_dsc->bg_grad.stops[1].color = lv_obj_get_style_bg_grad_color_filtered(obj, part);
72 draw_dsc->bg_grad.stops[0].frac = lv_obj_get_style_bg_main_stop(obj, part);
73 draw_dsc->bg_grad.stops[1].frac = lv_obj_get_style_bg_grad_stop(obj, part);
74 }
75 draw_dsc->bg_grad.dither = lv_obj_get_style_bg_dither_mode(obj, part);
76 }
77 }
78 }
79
80 draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
81 if(draw_dsc->border_width) {
82 if(draw_dsc->border_opa != LV_OPA_TRANSP) {
83 draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
84 if(draw_dsc->border_opa > LV_OPA_MIN) {
85 draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
86 draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part);
87 }
88 }
89 }
90
91 draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
92 if(draw_dsc->outline_width) {
93 if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
94 draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
95 if(draw_dsc->outline_opa > LV_OPA_MIN) {
96 draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
97 draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part);
98 }
99 }
100 }
101
102 if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) {
103 draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part);
104 if(draw_dsc->bg_img_src) {
105 draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part);
106 if(draw_dsc->bg_img_opa > LV_OPA_MIN) {
107 if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) {
108 draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part);
109 draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part);
110 }
111 else {
112 draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part);
113 draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part);
114 draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part);
115 }
116 }
117 }
118 }
119
120 if(draw_dsc->shadow_opa) {
121 draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
122 if(draw_dsc->shadow_width) {
123 if(draw_dsc->shadow_opa > LV_OPA_MIN) {
124 draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part);
125 if(draw_dsc->shadow_opa > LV_OPA_MIN) {
126 draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
127 draw_dsc->shadow_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
128 draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part);
129 draw_dsc->shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part);
130 }
131 }
132 }
133 }
134
135 #else /*LV_DRAW_COMPLEX*/
136 if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
137 draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
138 if(draw_dsc->bg_opa > LV_OPA_MIN) {
139 draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
140 }
141 }
142
143 draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
144 if(draw_dsc->border_width) {
145 if(draw_dsc->border_opa != LV_OPA_TRANSP) {
146 draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
147 if(draw_dsc->border_opa > LV_OPA_MIN) {
148 draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part);
149 draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
150 }
151 }
152 }
153
154 draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
155 if(draw_dsc->outline_width) {
156 if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
157 draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
158 if(draw_dsc->outline_opa > LV_OPA_MIN) {
159 draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
160 draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part);
161 }
162 }
163 }
164
165 if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) {
166 draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part);
167 if(draw_dsc->bg_img_src) {
168 draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part);
169 if(draw_dsc->bg_img_opa > LV_OPA_MIN) {
170 if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) {
171 draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part);
172 draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part);
173 }
174 else {
175 draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part);
176 draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part);
177 draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part);
178 }
179 }
180 }
181 }
182 #endif
183
184 if(part != LV_PART_MAIN) {
185 if(opa < LV_OPA_MAX) {
186 draw_dsc->bg_opa = (opa * draw_dsc->shadow_opa) >> 8;
187 draw_dsc->bg_img_opa = (opa * draw_dsc->shadow_opa) >> 8;
188 draw_dsc->border_opa = (opa * draw_dsc->shadow_opa) >> 8;
189 draw_dsc->outline_opa = (opa * draw_dsc->shadow_opa) >> 8;
190 draw_dsc->shadow_opa = (opa * draw_dsc->shadow_opa) >> 8;
191 }
192 }
193 }
194
lv_obj_init_draw_label_dsc(lv_obj_t * obj,uint32_t part,lv_draw_label_dsc_t * draw_dsc)195 void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc)
196 {
197 draw_dsc->opa = lv_obj_get_style_text_opa(obj, part);
198 if(draw_dsc->opa <= LV_OPA_MIN) return;
199
200 if(part != LV_PART_MAIN) {
201 lv_opa_t opa = lv_obj_get_style_opa(obj, part);
202 if(opa <= LV_OPA_MIN) {
203 draw_dsc->opa = LV_OPA_TRANSP;
204 return;
205 }
206 if(opa < LV_OPA_MAX) {
207 draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
208 }
209 }
210
211 draw_dsc->color = lv_obj_get_style_text_color_filtered(obj, part);
212 draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part);
213 draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part);
214 draw_dsc->decor = lv_obj_get_style_text_decor(obj, part);
215 #if LV_DRAW_COMPLEX
216 if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
217 #endif
218
219 draw_dsc->font = lv_obj_get_style_text_font(obj, part);
220
221 #if LV_USE_BIDI
222 draw_dsc->bidi_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
223 #endif
224
225 draw_dsc->align = lv_obj_get_style_text_align(obj, part);
226 }
227
lv_obj_init_draw_img_dsc(lv_obj_t * obj,uint32_t part,lv_draw_img_dsc_t * draw_dsc)228 void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc)
229 {
230 draw_dsc->opa = lv_obj_get_style_img_opa(obj, part);
231 if(draw_dsc->opa <= LV_OPA_MIN) return;
232
233 if(part != LV_PART_MAIN) {
234 lv_opa_t opa = lv_obj_get_style_opa(obj, part);
235 if(opa <= LV_OPA_MIN) {
236 draw_dsc->opa = LV_OPA_TRANSP;
237 return;
238 }
239 if(opa < LV_OPA_MAX) {
240 draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
241 }
242 }
243
244 draw_dsc->angle = 0;
245 draw_dsc->zoom = LV_IMG_ZOOM_NONE;
246 draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
247 draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
248
249 draw_dsc->recolor_opa = lv_obj_get_style_img_recolor_opa(obj, part);
250 if(draw_dsc->recolor_opa > 0) {
251 draw_dsc->recolor = lv_obj_get_style_img_recolor_filtered(obj, part);
252 }
253 #if LV_DRAW_COMPLEX
254 if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
255 #endif
256 }
257
lv_obj_init_draw_line_dsc(lv_obj_t * obj,uint32_t part,lv_draw_line_dsc_t * draw_dsc)258 void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc)
259 {
260 draw_dsc->opa = lv_obj_get_style_line_opa(obj, part);
261 if(draw_dsc->opa <= LV_OPA_MIN) return;
262
263 if(part != LV_PART_MAIN) {
264 lv_opa_t opa = lv_obj_get_style_opa(obj, part);
265 if(opa <= LV_OPA_MIN) {
266 draw_dsc->opa = LV_OPA_TRANSP;
267 return;
268 }
269 if(opa < LV_OPA_MAX) {
270 draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
271 }
272 }
273
274 draw_dsc->width = lv_obj_get_style_line_width(obj, part);
275 if(draw_dsc->width == 0) return;
276
277 draw_dsc->color = lv_obj_get_style_line_color_filtered(obj, part);
278
279 draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part);
280 if(draw_dsc->dash_width) {
281 draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part);
282 }
283
284 draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part);
285 draw_dsc->round_end = draw_dsc->round_start;
286
287 #if LV_DRAW_COMPLEX
288 if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
289 #endif
290 }
291
lv_obj_init_draw_arc_dsc(lv_obj_t * obj,uint32_t part,lv_draw_arc_dsc_t * draw_dsc)292 void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc)
293 {
294 draw_dsc->width = lv_obj_get_style_arc_width(obj, part);
295 if(draw_dsc->width == 0) return;
296
297 draw_dsc->opa = lv_obj_get_style_arc_opa(obj, part);
298 if(draw_dsc->opa <= LV_OPA_MIN) return;
299
300 if(part != LV_PART_MAIN) {
301 lv_opa_t opa = lv_obj_get_style_opa(obj, part);
302 if(opa <= LV_OPA_MIN) {
303 draw_dsc->opa = LV_OPA_TRANSP;
304 return;
305 }
306 if(opa < LV_OPA_MAX) {
307 draw_dsc->opa = (opa * draw_dsc->opa) >> 8;
308 }
309 }
310
311 draw_dsc->color = lv_obj_get_style_arc_color_filtered(obj, part);
312 draw_dsc->img_src = lv_obj_get_style_arc_img_src(obj, part);
313
314 draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part);
315
316 #if LV_DRAW_COMPLEX
317 if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
318 #endif
319 }
320
lv_obj_calculate_ext_draw_size(lv_obj_t * obj,uint32_t part)321 lv_coord_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part)
322 {
323 lv_coord_t s = 0;
324
325 lv_coord_t sh_width = lv_obj_get_style_shadow_width(obj, part);
326 if(sh_width) {
327 lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part);
328 if(sh_opa > LV_OPA_MIN) {
329 sh_width = sh_width / 2 + 1; /*The blur adds only half width*/
330 sh_width += lv_obj_get_style_shadow_spread(obj, part);
331 lv_coord_t sh_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part);
332 lv_coord_t sh_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part);
333 sh_width += LV_MAX(LV_ABS(sh_ofs_x), LV_ABS(sh_ofs_y));
334 s = LV_MAX(s, sh_width);
335 }
336 }
337
338 lv_coord_t outline_width = lv_obj_get_style_outline_width(obj, part);
339 if(outline_width) {
340 lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part);
341 if(outline_opa > LV_OPA_MIN) {
342 lv_coord_t outline_pad = lv_obj_get_style_outline_pad(obj, part);
343 s = LV_MAX(s, outline_pad + outline_width);
344 }
345 }
346
347 lv_coord_t w = lv_obj_get_style_transform_width(obj, part);
348 lv_coord_t h = lv_obj_get_style_transform_height(obj, part);
349 lv_coord_t wh = LV_MAX(w, h);
350 if(wh > 0) s += wh;
351
352 return s;
353 }
354
lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc,lv_draw_ctx_t * draw_ctx)355 void lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc, lv_draw_ctx_t * draw_ctx)
356 {
357 lv_memset_00(dsc, sizeof(lv_obj_draw_part_dsc_t));
358 dsc->draw_ctx = draw_ctx;
359 }
360
lv_obj_draw_part_check_type(lv_obj_draw_part_dsc_t * dsc,const lv_obj_class_t * class_p,uint32_t type)361 bool lv_obj_draw_part_check_type(lv_obj_draw_part_dsc_t * dsc, const lv_obj_class_t * class_p, uint32_t type)
362 {
363 if(dsc->class_p == class_p && dsc->type == type) return true;
364 else return false;
365 }
366
lv_obj_refresh_ext_draw_size(lv_obj_t * obj)367 void lv_obj_refresh_ext_draw_size(lv_obj_t * obj)
368 {
369 LV_ASSERT_OBJ(obj, MY_CLASS);
370
371 lv_coord_t s_old = _lv_obj_get_ext_draw_size(obj);
372 lv_coord_t s_new = 0;
373 lv_event_send(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new);
374
375 if(s_new != s_old) lv_obj_invalidate(obj);
376
377 /*Store the result if the special attrs already allocated*/
378 if(obj->spec_attr) {
379 obj->spec_attr->ext_draw_size = s_new;
380 }
381 /*Allocate spec. attrs. only if the result is not zero.
382 *Zero is the default value if the spec. attr. are not defined.*/
383 else if(s_new != 0) {
384 lv_obj_allocate_spec_attr(obj);
385 obj->spec_attr->ext_draw_size = s_new;
386 }
387
388 if(s_new != s_old) lv_obj_invalidate(obj);
389 }
390
_lv_obj_get_ext_draw_size(const lv_obj_t * obj)391 lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj)
392 {
393 if(obj->spec_attr) return obj->spec_attr->ext_draw_size;
394 else return 0;
395 }
396
_lv_obj_get_layer_type(const lv_obj_t * obj)397 lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj)
398 {
399
400 if(obj->spec_attr) return obj->spec_attr->layer_type;
401 else return LV_LAYER_TYPE_NONE;
402 }
403
404 /**********************
405 * STATIC FUNCTIONS
406 **********************/
407