1 #include "lv_draw_dave2d.h"
2 #if LV_USE_DRAW_DAVE2D
3 
4 #include "../../../misc/lv_area_private.h"
5 
lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u,const lv_draw_triangle_dsc_t * dsc)6 void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_dsc_t * dsc)
7 {
8     lv_area_t clipped_area;
9     d2_u32      flags = 0;
10     d2_u8 current_alpha_mode = 0;
11     int32_t x;
12     int32_t y;
13 
14     lv_area_t tri_area;
15     tri_area.x1 = LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
16     tri_area.y1 = LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
17     tri_area.x2 = LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
18     tri_area.y2 = LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
19 
20     if(!lv_area_intersect(&clipped_area, &tri_area, u->base_unit.clip_area)) return;
21 
22 #if LV_USE_OS
23     lv_result_t  status;
24     status = lv_mutex_lock(u->pd2Mutex);
25     LV_ASSERT(LV_RESULT_OK == status);
26 #endif
27 
28     x = 0 - u->base_unit.target_layer->buf_area.x1;
29     y = 0 - u->base_unit.target_layer->buf_area.y1;
30 
31     lv_area_move(&clipped_area, x, y);
32 
33 #if D2_RENDER_EACH_OPERATION
34     d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
35 #endif
36 
37     lv_point_precise_t p[3];
38     p[0] = dsc->p[0];
39     p[1] = dsc->p[1];
40     p[2] = dsc->p[2];
41 
42     /*Order the points like this:
43      * [0]: top
44      * [1]: right bottom
45      * [2]: left bottom */
46 
47     if(dsc->p[0].y <= dsc->p[1].y && dsc->p[0].y <= dsc->p[2].y) {
48         p[0] = dsc->p[0];
49         if(dsc->p[1].x < dsc->p[2].x) {
50             p[2] = dsc->p[1];
51             p[1] = dsc->p[2];
52         }
53         else {
54             p[2] = dsc->p[2];
55             p[1] = dsc->p[1];
56         }
57     }
58     else if(dsc->p[1].y <= dsc->p[0].y && dsc->p[1].y <= dsc->p[2].y) {
59         p[0] = dsc->p[1];
60         if(dsc->p[0].x < dsc->p[2].x) {
61             p[2] = dsc->p[0];
62             p[1] = dsc->p[2];
63         }
64         else {
65             p[2] = dsc->p[2];
66             p[1] = dsc->p[0];
67         }
68     }
69     else {
70         p[0] = dsc->p[2];
71         if(dsc->p[0].x < dsc->p[1].x) {
72             p[2] = dsc->p[0];
73             p[1] = dsc->p[1];
74         }
75         else {
76             p[2] = dsc->p[1];
77             p[1] = dsc->p[0];
78         }
79     }
80 
81     p[0].x -= u->base_unit.target_layer->buf_area.x1;
82     p[1].x -= u->base_unit.target_layer->buf_area.x1;
83     p[2].x -= u->base_unit.target_layer->buf_area.x1;
84 
85     p[0].y -= u->base_unit.target_layer->buf_area.y1;
86     p[1].y -= u->base_unit.target_layer->buf_area.y1;
87     p[2].y -= u->base_unit.target_layer->buf_area.y1;
88 
89     p[1].y -= 1;
90     p[2].y -= 1;
91 
92     current_alpha_mode = d2_getalphamode(u->d2_handle);
93 
94     if(LV_GRAD_DIR_NONE != dsc->bg_grad.dir) {
95         float a1;
96         float a2;
97 
98         float y1;
99         float y2;
100 
101         float y3;
102         float y0;
103         int32_t y0_i ;
104         int32_t y3_i ;
105 
106         if(LV_GRAD_DIR_VER == dsc->bg_grad.dir) {
107             a1 = dsc->bg_grad.stops[0].opa;
108             a2 = dsc->bg_grad.stops[dsc->bg_grad.stops_count - 1].opa;
109 
110             y1 = LV_MIN3(p[0].y, p[1].y, p[2].y);
111             y2 = LV_MAX3(p[0].y, p[1].y, p[2].y);
112 
113             if(a1 < a2) {
114                 /* TODO */
115                 LV_ASSERT(0);
116                 y0 = 0.0f;//silence the compiler warning
117                 y3 = 0.0f;
118 
119             }
120             else {
121                 y0 = y2 - ((y2 - y1) / (a2 - a1) * (a2)); //point where alpha is 0
122                 y3 = y1 + ((y2 - y1) / (a2 - a1) * (255 - a1)); //point where alpha is 255
123             }
124 
125             y0_i = (int16_t)y0;
126             y3_i = (int16_t)y3;
127 
128             d2_setalphagradient(u->d2_handle, 0, D2_FIX4(0),  D2_FIX4(y0_i), D2_FIX4(0), D2_FIX4((y3_i - y0_i)));
129         }
130         else if(LV_GRAD_DIR_HOR == dsc->bg_grad.dir) {
131             /* TODO */
132             LV_ASSERT(0);
133         }
134 
135         d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_grad.stops[0].color));
136         d2_setalphamode(u->d2_handle, d2_am_gradient1);
137     }
138     else {
139         d2_setalpha(u->d2_handle, dsc->bg_opa);
140         d2_setalphamode(u->d2_handle, d2_am_constant);
141         d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_color));
142 
143     }
144 
145     d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer);
146 
147     d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
148                 (d2_border)clipped_area.y2);
149 
150     d2_rendertri(u->d2_handle,
151                  (d2_point)      D2_FIX4(p[0].x),
152                  (d2_point)      D2_FIX4(p[0].y),
153                  (d2_point)      D2_FIX4(p[1].x),
154                  (d2_point)      D2_FIX4(p[1].y),
155                  (d2_point)      D2_FIX4(p[2].x),
156                  (d2_point)      D2_FIX4(p[2].y),
157                  flags);
158 
159     //
160     // Execute render operations
161     //
162 #if D2_RENDER_EACH_OPERATION
163     d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
164     d2_flushframe(u->d2_handle);
165 #endif
166 
167     d2_setalphamode(u->d2_handle, current_alpha_mode);
168 
169 #if LV_USE_OS
170     status = lv_mutex_unlock(u->pd2Mutex);
171     LV_ASSERT(LV_RESULT_OK == status);
172 #endif
173 
174 }
175 
176 #endif /*LV_USE_DRAW_DAVE2D*/
177