/** * @file lv_obj_draw.c * */ /********************* * INCLUDES *********************/ #include "lv_obj_draw.h" #include "lv_obj.h" #include "lv_disp.h" #include "lv_indev.h" /********************* * DEFINES *********************/ #define MY_CLASS &lv_obj_class /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t * draw_dsc) { lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); if(part != LV_PART_MAIN) { if(opa <= LV_OPA_MIN) { draw_dsc->bg_opa = LV_OPA_TRANSP; draw_dsc->bg_img_opa = LV_OPA_TRANSP; draw_dsc->border_opa = LV_OPA_TRANSP; draw_dsc->outline_opa = LV_OPA_TRANSP; draw_dsc->shadow_opa = LV_OPA_TRANSP; return; } } #if LV_DRAW_COMPLEX if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); draw_dsc->radius = lv_obj_get_style_radius(obj, part); if(draw_dsc->bg_opa != LV_OPA_TRANSP) { draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part); if(draw_dsc->bg_opa > LV_OPA_MIN) { draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part); const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part); if(grad && grad->dir != LV_GRAD_DIR_NONE) { lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad)); } else { draw_dsc->bg_grad.dir = lv_obj_get_style_bg_grad_dir(obj, part); if(draw_dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { draw_dsc->bg_grad.stops[0].color = lv_obj_get_style_bg_color_filtered(obj, part); draw_dsc->bg_grad.stops[1].color = lv_obj_get_style_bg_grad_color_filtered(obj, part); draw_dsc->bg_grad.stops[0].frac = lv_obj_get_style_bg_main_stop(obj, part); draw_dsc->bg_grad.stops[1].frac = lv_obj_get_style_bg_grad_stop(obj, part); } draw_dsc->bg_grad.dither = lv_obj_get_style_bg_dither_mode(obj, part); } } } draw_dsc->border_width = lv_obj_get_style_border_width(obj, part); if(draw_dsc->border_width) { if(draw_dsc->border_opa != LV_OPA_TRANSP) { draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part); if(draw_dsc->border_opa > LV_OPA_MIN) { draw_dsc->border_side = lv_obj_get_style_border_side(obj, part); draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part); } } } draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part); if(draw_dsc->outline_width) { if(draw_dsc->outline_opa != LV_OPA_TRANSP) { draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part); if(draw_dsc->outline_opa > LV_OPA_MIN) { draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part); draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part); } } } if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) { draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part); if(draw_dsc->bg_img_src) { draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part); if(draw_dsc->bg_img_opa > LV_OPA_MIN) { if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) { draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part); draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part); } else { draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part); draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part); draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part); } } } } if(draw_dsc->shadow_opa) { draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part); if(draw_dsc->shadow_width) { if(draw_dsc->shadow_opa > LV_OPA_MIN) { draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part); if(draw_dsc->shadow_opa > LV_OPA_MIN) { draw_dsc->shadow_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part); draw_dsc->shadow_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part); draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part); draw_dsc->shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part); } } } } #else /*LV_DRAW_COMPLEX*/ if(draw_dsc->bg_opa != LV_OPA_TRANSP) { draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part); if(draw_dsc->bg_opa > LV_OPA_MIN) { draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part); } } draw_dsc->border_width = lv_obj_get_style_border_width(obj, part); if(draw_dsc->border_width) { if(draw_dsc->border_opa != LV_OPA_TRANSP) { draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part); if(draw_dsc->border_opa > LV_OPA_MIN) { draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part); draw_dsc->border_side = lv_obj_get_style_border_side(obj, part); } } } draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part); if(draw_dsc->outline_width) { if(draw_dsc->outline_opa != LV_OPA_TRANSP) { draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part); if(draw_dsc->outline_opa > LV_OPA_MIN) { draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part); draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part); } } } if(draw_dsc->bg_img_opa != LV_OPA_TRANSP) { draw_dsc->bg_img_src = lv_obj_get_style_bg_img_src(obj, part); if(draw_dsc->bg_img_src) { draw_dsc->bg_img_opa = lv_obj_get_style_bg_img_opa(obj, part); if(draw_dsc->bg_img_opa > LV_OPA_MIN) { if(lv_img_src_get_type(draw_dsc->bg_img_src) == LV_IMG_SRC_SYMBOL) { draw_dsc->bg_img_symbol_font = lv_obj_get_style_text_font(obj, part); draw_dsc->bg_img_recolor = lv_obj_get_style_text_color_filtered(obj, part); } else { draw_dsc->bg_img_recolor = lv_obj_get_style_bg_img_recolor_filtered(obj, part); draw_dsc->bg_img_recolor_opa = lv_obj_get_style_bg_img_recolor_opa(obj, part); draw_dsc->bg_img_tiled = lv_obj_get_style_bg_img_tiled(obj, part); } } } } #endif if(opa < LV_OPA_MAX) { draw_dsc->bg_opa = (opa * draw_dsc->bg_opa) >> 8; draw_dsc->bg_img_opa = (opa * draw_dsc->bg_img_opa) >> 8; draw_dsc->border_opa = (opa * draw_dsc->border_opa) >> 8; draw_dsc->outline_opa = (opa * draw_dsc->outline_opa) >> 8; draw_dsc->shadow_opa = (opa * draw_dsc->shadow_opa) >> 8; } } void lv_obj_init_draw_label_dsc(lv_obj_t * obj, uint32_t part, lv_draw_label_dsc_t * draw_dsc) { draw_dsc->opa = lv_obj_get_style_text_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); if(opa <= LV_OPA_MIN) { draw_dsc->opa = LV_OPA_TRANSP; return; } if(opa < LV_OPA_MAX) { draw_dsc->opa = (opa * draw_dsc->opa) >> 8; } if(draw_dsc->opa <= LV_OPA_MIN) return; draw_dsc->color = lv_obj_get_style_text_color_filtered(obj, part); draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part); draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part); draw_dsc->decor = lv_obj_get_style_text_decor(obj, part); #if LV_DRAW_COMPLEX if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif draw_dsc->font = lv_obj_get_style_text_font(obj, part); #if LV_USE_BIDI draw_dsc->bidi_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); #endif draw_dsc->align = lv_obj_get_style_text_align(obj, part); } void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint32_t part, lv_draw_img_dsc_t * draw_dsc) { draw_dsc->opa = lv_obj_get_style_img_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); if(opa <= LV_OPA_MIN) { draw_dsc->opa = LV_OPA_TRANSP; return; } if(opa < LV_OPA_MAX) { draw_dsc->opa = (opa * draw_dsc->opa) >> 8; } if(draw_dsc->opa <= LV_OPA_MIN) return; draw_dsc->angle = 0; draw_dsc->zoom = LV_IMG_ZOOM_NONE; draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2; draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2; draw_dsc->recolor_opa = lv_obj_get_style_img_recolor_opa(obj, part); if(draw_dsc->recolor_opa > 0) { draw_dsc->recolor = lv_obj_get_style_img_recolor_filtered(obj, part); } #if LV_DRAW_COMPLEX if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint32_t part, lv_draw_line_dsc_t * draw_dsc) { draw_dsc->opa = lv_obj_get_style_line_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); if(opa <= LV_OPA_MIN) { draw_dsc->opa = LV_OPA_TRANSP; return; } if(opa < LV_OPA_MAX) { draw_dsc->opa = (opa * draw_dsc->opa) >> 8; } if(draw_dsc->opa <= LV_OPA_MIN) return; draw_dsc->width = lv_obj_get_style_line_width(obj, part); if(draw_dsc->width == 0) return; draw_dsc->color = lv_obj_get_style_line_color_filtered(obj, part); draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part); if(draw_dsc->dash_width) { draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part); } draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part); draw_dsc->round_end = draw_dsc->round_start; #if LV_DRAW_COMPLEX if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, uint32_t part, lv_draw_arc_dsc_t * draw_dsc) { draw_dsc->width = lv_obj_get_style_arc_width(obj, part); if(draw_dsc->width == 0) return; draw_dsc->opa = lv_obj_get_style_arc_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); if(opa <= LV_OPA_MIN) { draw_dsc->opa = LV_OPA_TRANSP; return; } if(opa < LV_OPA_MAX) { draw_dsc->opa = (opa * draw_dsc->opa) >> 8; } if(draw_dsc->opa <= LV_OPA_MIN) return; draw_dsc->color = lv_obj_get_style_arc_color_filtered(obj, part); draw_dsc->img_src = lv_obj_get_style_arc_img_src(obj, part); draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part); #if LV_DRAW_COMPLEX if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); #endif } lv_coord_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, uint32_t part) { lv_coord_t s = 0; lv_coord_t sh_width = lv_obj_get_style_shadow_width(obj, part); if(sh_width) { lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part); if(sh_opa > LV_OPA_MIN) { sh_width = sh_width / 2 + 1; /*The blur adds only half width*/ sh_width += lv_obj_get_style_shadow_spread(obj, part); lv_coord_t sh_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part); lv_coord_t sh_ofs_y = lv_obj_get_style_shadow_ofs_y(obj, part); sh_width += LV_MAX(LV_ABS(sh_ofs_x), LV_ABS(sh_ofs_y)); s = LV_MAX(s, sh_width); } } lv_coord_t outline_width = lv_obj_get_style_outline_width(obj, part); if(outline_width) { lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part); if(outline_opa > LV_OPA_MIN) { lv_coord_t outline_pad = lv_obj_get_style_outline_pad(obj, part); s = LV_MAX(s, outline_pad + outline_width); } } lv_coord_t w = lv_obj_get_style_transform_width(obj, part); lv_coord_t h = lv_obj_get_style_transform_height(obj, part); lv_coord_t wh = LV_MAX(w, h); if(wh > 0) s += wh; return s; } void lv_obj_draw_dsc_init(lv_obj_draw_part_dsc_t * dsc, lv_draw_ctx_t * draw_ctx) { lv_memset_00(dsc, sizeof(lv_obj_draw_part_dsc_t)); dsc->draw_ctx = draw_ctx; } bool lv_obj_draw_part_check_type(lv_obj_draw_part_dsc_t * dsc, const lv_obj_class_t * class_p, uint32_t type) { if(dsc->class_p == class_p && dsc->type == type) return true; else return false; } void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_coord_t s_old = _lv_obj_get_ext_draw_size(obj); lv_coord_t s_new = 0; lv_event_send(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new); if(s_new != s_old) lv_obj_invalidate(obj); /*Store the result if the special attrs already allocated*/ if(obj->spec_attr) { obj->spec_attr->ext_draw_size = s_new; } /*Allocate spec. attrs. only if the result is not zero. *Zero is the default value if the spec. attr. are not defined.*/ else if(s_new != 0) { lv_obj_allocate_spec_attr(obj); obj->spec_attr->ext_draw_size = s_new; } if(s_new != s_old) lv_obj_invalidate(obj); } lv_coord_t _lv_obj_get_ext_draw_size(const lv_obj_t * obj) { if(obj->spec_attr) return obj->spec_attr->ext_draw_size; else return 0; } lv_layer_type_t _lv_obj_get_layer_type(const lv_obj_t * obj) { if(obj->spec_attr) return obj->spec_attr->layer_type; else return LV_LAYER_TYPE_NONE; } /********************** * STATIC FUNCTIONS **********************/