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