1 /**
2  * @file lv_draw_vg_lite_rect.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "../../misc/lv_area_private.h"
11 #include "../sw/lv_draw_sw_mask_private.h"
12 #include "../lv_draw_mask_private.h"
13 #include "lv_draw_vg_lite.h"
14 
15 #if LV_USE_DRAW_VG_LITE
16 
17 #include "lv_vg_lite_utils.h"
18 #include "lv_draw_vg_lite_type.h"
19 #include "lv_vg_lite_path.h"
20 
21 /*********************
22  *      DEFINES
23  *********************/
24 
25 /**********************
26  *      TYPEDEFS
27  **********************/
28 
29 /**********************
30  *  STATIC PROTOTYPES
31  **********************/
32 
33 /**********************
34  *  STATIC VARIABLES
35  **********************/
36 
37 /**********************
38  *      MACROS
39  **********************/
40 
41 /**********************
42  *   GLOBAL FUNCTIONS
43  **********************/
44 
lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit,const lv_draw_mask_rect_dsc_t * dsc,const lv_area_t * coords)45 void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc,
46                                const lv_area_t * coords)
47 {
48     LV_UNUSED(coords);
49 
50     lv_area_t draw_area;
51     if(!lv_area_intersect(&draw_area, &dsc->area, draw_unit->clip_area)) {
52         return;
53     }
54 
55     LV_PROFILER_DRAW_BEGIN;
56 
57 #if LV_USE_VG_LITE_THORVG
58     /**
59      * ThorVG does not yet support simulating the VG_LITE_BLEND_DST_IN blend mode,
60      * and uses software rendering to achieve this
61      */
62     lv_layer_t * target_layer = draw_unit->target_layer;
63     const lv_area_t * buf_area = &target_layer->buf_area;
64     lv_area_t clear_area;
65 
66     lv_draw_buf_t * draw_buf = target_layer->draw_buf;
67 
68     /*Clear the top part*/
69     lv_area_set(&clear_area, draw_unit->clip_area->x1, draw_unit->clip_area->y1, draw_unit->clip_area->x2,
70                 dsc->area.y1 - 1);
71     lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
72     lv_draw_buf_clear(draw_buf, &clear_area);
73 
74     /*Clear the bottom part*/
75     lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y2 + 1, draw_unit->clip_area->x2,
76                 draw_unit->clip_area->y2);
77     lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
78     lv_draw_buf_clear(draw_buf, &clear_area);
79 
80     /*Clear the left part*/
81     lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y1, dsc->area.x1 - 1, dsc->area.y2);
82     lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
83     lv_draw_buf_clear(draw_buf, &clear_area);
84 
85     /*Clear the right part*/
86     lv_area_set(&clear_area, dsc->area.x2 + 1, dsc->area.y1, draw_unit->clip_area->x2, dsc->area.y2);
87     lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1);
88     lv_draw_buf_clear(draw_buf, &clear_area);
89 
90     lv_draw_sw_mask_radius_param_t param;
91     lv_draw_sw_mask_radius_init(&param, &dsc->area, dsc->radius, false);
92 
93     void * masks[2] = {0};
94     masks[0] = &param;
95 
96     uint32_t area_w = lv_area_get_width(&draw_area);
97     lv_opa_t * mask_buf = lv_malloc(area_w);
98 
99     int32_t y;
100     for(y = draw_area.y1; y <= draw_area.y2; y++) {
101         lv_memset(mask_buf, 0xff, area_w);
102         lv_draw_sw_mask_res_t res = lv_draw_sw_mask_apply(masks, mask_buf, draw_area.x1, y, area_w);
103         if(res == LV_DRAW_SW_MASK_RES_FULL_COVER) continue;
104 
105         lv_color32_t * c32_buf = lv_draw_layer_go_to_xy(target_layer, draw_area.x1 - target_layer->buf_area.x1,
106                                                         y - target_layer->buf_area.y1);
107 
108         if(res == LV_DRAW_SW_MASK_RES_TRANSP) {
109             lv_memzero(c32_buf, area_w * sizeof(lv_color32_t));
110         }
111         else {
112             uint32_t i;
113             for(i = 0; i < area_w; i++) {
114                 if(mask_buf[i] != LV_OPA_COVER) {
115                     c32_buf[i].alpha = LV_OPA_MIX2(c32_buf[i].alpha, mask_buf[i]);
116                 }
117 
118                 /*Pre-multiply the alpha*/
119                 lv_color_premultiply(&c32_buf[i]);
120             }
121         }
122     }
123 
124     lv_free(mask_buf);
125     lv_draw_sw_mask_free_param(&param);
126 #else
127     /* Using hardware rendering masks */
128     lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
129 
130     lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
131     lv_vg_lite_path_set_bounding_box_area(path, draw_unit->clip_area);
132 
133     /* Nesting cropping regions using rounded rectangles and normal rectangles */
134     lv_vg_lite_path_append_rect(
135         path,
136         dsc->area.x1, dsc->area.y1,
137         lv_area_get_width(&dsc->area), lv_area_get_height(&dsc->area),
138         dsc->radius);
139     lv_vg_lite_path_append_rect(
140         path,
141         draw_unit->clip_area->x1, draw_unit->clip_area->y1,
142         lv_area_get_width(draw_unit->clip_area), lv_area_get_height(draw_unit->clip_area),
143         0);
144     lv_vg_lite_path_end(path);
145 
146     vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
147 
148     vg_lite_matrix_t matrix = u->global_matrix;
149 
150     LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
151     LV_VG_LITE_ASSERT_PATH(vg_lite_path);
152     LV_VG_LITE_ASSERT_MATRIX(&matrix);
153 
154     /* Use VG_LITE_BLEND_DST_IN (Sa * D) blending mode to make the corners transparent */
155     LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw");
156     LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
157                                &u->target_buffer,
158                                vg_lite_path,
159                                VG_LITE_FILL_EVEN_ODD,
160                                &matrix,
161                                VG_LITE_BLEND_DST_IN,
162                                0));
163     LV_PROFILER_DRAW_END_TAG("vg_lite_draw");
164 
165     lv_vg_lite_path_drop(u, path);
166 #endif /*LV_USE_VG_LITE_THORVG*/
167 
168     LV_PROFILER_DRAW_END;
169 }
170 
171 /**********************
172  *   STATIC FUNCTIONS
173  **********************/
174 
175 #endif /*LV_USE_DRAW_VG_LITE*/
176