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