1 /**
2  * @file lv_draw_vg_lite_box_shadow.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "../../misc/lv_area_private.h"
11 #include "lv_draw_vg_lite.h"
12 
13 #if LV_USE_DRAW_VG_LITE
14 
15 #include "lv_draw_vg_lite_type.h"
16 
17 /*********************
18  *      DEFINES
19  *********************/
20 
21 /**********************
22  *      TYPEDEFS
23  **********************/
24 
25 /**********************
26  *  STATIC PROTOTYPES
27  **********************/
28 
29 /**********************
30  *  STATIC VARIABLES
31  **********************/
32 
33 /**********************
34  *      MACROS
35  **********************/
36 
37 /**********************
38  *   GLOBAL FUNCTIONS
39  **********************/
40 
lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit,const lv_draw_box_shadow_dsc_t * dsc,const lv_area_t * coords)41 void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc,
42                                 const lv_area_t * coords)
43 {
44     /*Calculate the rectangle which is blurred to get the shadow in `shadow_area`*/
45     lv_area_t core_area;
46     core_area.x1 = coords->x1  + dsc->ofs_x - dsc->spread;
47     core_area.x2 = coords->x2  + dsc->ofs_x + dsc->spread;
48     core_area.y1 = coords->y1  + dsc->ofs_y - dsc->spread;
49     core_area.y2 = coords->y2  + dsc->ofs_y + dsc->spread;
50 
51     /*Calculate the bounding box of the shadow*/
52     lv_area_t shadow_area;
53     shadow_area.x1 = core_area.x1 - dsc->width / 2 - 1;
54     shadow_area.x2 = core_area.x2 + dsc->width / 2 + 1;
55     shadow_area.y1 = core_area.y1 - dsc->width / 2 - 1;
56     shadow_area.y2 = core_area.y2 + dsc->width / 2 + 1;
57 
58     /*Get clipped draw area which is the real draw area.
59      *It is always the same or inside `shadow_area`*/
60     lv_area_t draw_area;
61     if(!lv_area_intersect(&draw_area, &shadow_area, draw_unit->clip_area)) return;
62 
63     LV_PROFILER_DRAW_BEGIN;
64 
65     lv_draw_border_dsc_t border_dsc;
66     lv_draw_border_dsc_init(&border_dsc);
67     border_dsc.width = 3;
68     border_dsc.color = dsc->color;
69     border_dsc.radius = dsc->radius;
70 
71     lv_area_move(&draw_area, dsc->ofs_x, dsc->ofs_y);
72     draw_area = core_area;
73     int32_t half_w = dsc->width / 2;
74 
75     for(int32_t w = 0; w < half_w; w++) {
76         border_dsc.opa = lv_map(w, 0, half_w, dsc->opa / 4, LV_OPA_0);
77         border_dsc.radius++;
78         lv_area_increase(&draw_area, 1, 1);
79         lv_draw_vg_lite_border(draw_unit, &border_dsc, &draw_area);
80 
81         /* fill center */
82         if(dsc->ofs_x || dsc->ofs_y) {
83             lv_draw_fill_dsc_t fill_dsc;
84             lv_draw_fill_dsc_init(&fill_dsc);
85             fill_dsc.radius = dsc->radius;
86             fill_dsc.opa = dsc->opa;
87             fill_dsc.color = dsc->color;
88             lv_draw_vg_lite_fill(draw_unit, &fill_dsc, &core_area);
89         }
90     }
91     LV_PROFILER_DRAW_END;
92 }
93 
94 /**********************
95  *   STATIC FUNCTIONS
96  **********************/
97 
98 #endif /*LV_USE_DRAW_VG_LITE*/
99