1 #include "lv_draw_dave2d.h"
2 #if LV_USE_DRAW_DAVE2D
3
4 #include "../../../misc/lv_area_private.h"
5
lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u,const lv_draw_arc_dsc_t * dsc,const lv_area_t * coords)6 void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords)
7 {
8
9 uint32_t flags = 0;
10 int32_t sin_start;
11 int32_t cos_start;
12 int32_t sin_end;
13 int32_t cos_end;
14 d2_s32 result;
15 lv_area_t clipped_area;
16 lv_area_t buffer_area;
17 lv_point_t arc_centre;
18 int32_t x;
19 int32_t y;
20
21 if(!lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return;
22
23 x = 0 - u->base_unit.target_layer->buf_area.x1;
24 y = 0 - u->base_unit.target_layer->buf_area.y1;
25
26 buffer_area = u->base_unit.target_layer->buf_area;
27
28 arc_centre = dsc->center;
29 arc_centre.x = arc_centre.x - buffer_area.x1;
30 arc_centre.y = arc_centre.y - buffer_area.y1;
31
32 lv_area_move(&clipped_area, x, y);
33 lv_area_move(&buffer_area, x, y);
34
35 //
36 // If both angles are equal (e.g. 0 and 0 or 180 and 180) nothing has to be done
37 //
38 if(dsc->start_angle == dsc->end_angle) {
39 return; // Nothing to do, no angle - no arc
40 }
41
42 #if LV_USE_OS
43 lv_result_t status;
44 status = lv_mutex_lock(u->pd2Mutex);
45 LV_ASSERT(LV_RESULT_OK == status);
46 #endif
47
48 #if D2_RENDER_EACH_OPERATION
49 d2_selectrenderbuffer(u->d2_handle, u->renderbuffer);
50 #endif
51
52 //
53 // Generate render operations
54 //
55 d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer);
56
57 d2_setalpha(u->d2_handle, dsc->opa);
58
59 d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color));
60
61 result = d2_cliprect(u->d2_handle, (d2_border)clipped_area.x1, (d2_border)clipped_area.y1, (d2_border)clipped_area.x2,
62 (d2_border)clipped_area.y2);
63 LV_ASSERT(D2_OK == result);
64
65 if(360 <= LV_ABS(dsc->start_angle - dsc->end_angle)) {
66 d2_rendercircle(u->d2_handle,
67 (d2_point)D2_FIX4(arc_centre.x),
68 (d2_point) D2_FIX4(arc_centre.y),
69 (d2_width) D2_FIX4(dsc->radius - dsc->width / 2),
70 (d2_width) D2_FIX4(dsc->width));
71 }
72 else { //An ARC, not a full circle
73 //
74 // If the difference between both is larger than 180 degrees we must use the concave flag
75 //
76 /** Set d2_wf_concave flag if the pie object to draw is concave shape. */
77 if((LV_ABS(dsc->start_angle - dsc->end_angle) > 180) || ((dsc->end_angle < dsc->start_angle) &&
78 (LV_ABS(dsc->start_angle - (dsc->end_angle + 360)) > 180))) {
79 flags = d2_wf_concave;
80 }
81 else {
82 flags = 0;
83 }
84
85 sin_start = lv_trigo_sin((int16_t)dsc->start_angle);
86 cos_start = lv_trigo_cos((int16_t)dsc->start_angle);
87
88 sin_end = lv_trigo_sin((int16_t)dsc->end_angle);
89 cos_end = lv_trigo_cos((int16_t)dsc->end_angle);
90
91 bool draw_arc;
92 lv_area_t arc_area;
93 lv_area_t clip_arc;
94 lv_point_t start_point;
95 lv_point_t end_point;
96
97 start_point.x = arc_centre.x + (int16_t)(((dsc->radius) * cos_start) >> LV_TRIGO_SHIFT);
98 start_point.y = arc_centre.y + (int16_t)(((dsc->radius) * sin_start) >> LV_TRIGO_SHIFT);
99
100 end_point.x = arc_centre.x + (int16_t)(((dsc->radius) * cos_end) >> LV_TRIGO_SHIFT);
101 end_point.y = arc_centre.y + (int16_t)(((dsc->radius) * sin_end) >> LV_TRIGO_SHIFT);
102
103 arc_area.x1 = LV_MIN3(start_point.x, end_point.x, arc_centre.x);
104 arc_area.y1 = LV_MIN3(start_point.y, end_point.y, arc_centre.y);
105
106 arc_area.x2 = LV_MAX3(start_point.x, end_point.x, arc_centre.x);
107 arc_area.y2 = LV_MAX3(start_point.y, end_point.y, arc_centre.y);
108
109 /* 0 degrees */
110 if((dsc->end_angle < dsc->start_angle) || ((dsc->start_angle < 360) && (dsc->end_angle > 360))) {
111 arc_area.x2 = arc_centre.x + dsc->radius;
112 }
113
114 /* 90 degrees */
115 if(((dsc->end_angle > 90) && (dsc->start_angle < 90)) || ((dsc->start_angle < 90) &&
116 (dsc->end_angle < dsc->start_angle))) {
117 arc_area.y2 = arc_centre.y + dsc->radius;
118 }
119
120 /* 180 degrees */
121 if(((dsc->end_angle > 180) && (dsc->start_angle < 180)) || ((dsc->start_angle < 180) &&
122 (dsc->end_angle < dsc->start_angle))) {
123 arc_area.x1 = arc_centre.x - dsc->radius;
124 }
125
126 /* 270 degrees */
127 if(((dsc->end_angle > 270) && (dsc->start_angle < 270)) || ((dsc->start_angle < 270) &&
128 (dsc->end_angle < dsc->start_angle))) {
129 arc_area.y1 = arc_centre.y - dsc->radius;
130 }
131
132 draw_arc = lv_area_intersect(&clip_arc, &arc_area, &clipped_area);
133
134 if(draw_arc) {
135
136 result = d2_renderwedge(u->d2_handle,
137 (d2_point)D2_FIX4(arc_centre.x),
138 (d2_point) D2_FIX4(arc_centre.y),
139 (d2_width) D2_FIX4(dsc->radius - dsc->width / 2),
140 (d2_width) D2_FIX4(dsc->width),
141 -(d2_s32)(sin_start << 1),
142 (d2_s32)(cos_start << 1),
143 (d2_s32)(sin_end << 1),
144 -(d2_s32)(cos_end << 1),
145 flags);
146 LV_ASSERT(D2_OK == result);
147
148 if(dsc->rounded) {
149 lv_point_t start_coord;
150 lv_point_t end_coord;
151
152 start_coord.x = arc_centre.x + (int16_t)(((dsc->radius - dsc->width / 2) * cos_start) >> LV_TRIGO_SHIFT);
153 start_coord.y = arc_centre.y + (int16_t)(((dsc->radius - dsc->width / 2) * sin_start) >> LV_TRIGO_SHIFT);
154
155 /** Render a circle. */
156 d2_rendercircle(u->d2_handle,
157 (d2_point) D2_FIX4((uint16_t)(start_coord.x)),
158 (d2_point) D2_FIX4((uint16_t)(start_coord.y)),
159 (d2_width) D2_FIX4(dsc->width / 2), 0);
160
161 end_coord.x = arc_centre.x + (int16_t)(((dsc->radius - dsc->width / 2) * cos_end) >> LV_TRIGO_SHIFT);
162 end_coord.y = arc_centre.y + (int16_t)(((dsc->radius - dsc->width / 2) * sin_end) >> LV_TRIGO_SHIFT);
163
164 /** Render a circle. */
165 d2_rendercircle(u->d2_handle,
166 (d2_point) D2_FIX4((uint16_t)(end_coord.x)),
167 (d2_point) D2_FIX4((uint16_t)(end_coord.y)),
168 (d2_width) D2_FIX4(dsc->width / 2), 0);
169 }
170 }
171 }
172
173 //
174 // Execute render operations
175 //
176
177 #if D2_RENDER_EACH_OPERATION
178 d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0);
179 d2_flushframe(u->d2_handle);
180 #endif
181
182 #if LV_USE_OS
183 status = lv_mutex_unlock(u->pd2Mutex);
184 LV_ASSERT(LV_RESULT_OK == status);
185 #endif
186 }
187
188 #endif /*LV_USE_DRAW_DAVE2D*/
189