acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
lv_draw_sw_arc.c (20946B)
1 /** 2 * @file lv_draw_arc.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_draw_sw.h" 10 #include "../../misc/lv_math.h" 11 #include "../../misc/lv_log.h" 12 #include "../../misc/lv_mem.h" 13 #include "../lv_draw.h" 14 15 /********************* 16 * DEFINES 17 *********************/ 18 #define SPLIT_RADIUS_LIMIT 10 /*With radius greater than this the arc will drawn in quarters. A quarter is drawn only if there is arc in it*/ 19 #define SPLIT_ANGLE_GAP_LIMIT 60 /*With small gaps in the arc don't bother with splitting because there is nothing to skip.*/ 20 21 /********************** 22 * TYPEDEFS 23 **********************/ 24 typedef struct { 25 const lv_point_t * center; 26 lv_coord_t radius; 27 uint16_t start_angle; 28 uint16_t end_angle; 29 uint16_t start_quarter; 30 uint16_t end_quarter; 31 lv_coord_t width; 32 lv_draw_rect_dsc_t * draw_dsc; 33 const lv_area_t * draw_area; 34 lv_draw_ctx_t * draw_ctx; 35 } quarter_draw_dsc_t; 36 37 /********************** 38 * STATIC PROTOTYPES 39 **********************/ 40 #if LV_DRAW_COMPLEX 41 static void draw_quarter_0(quarter_draw_dsc_t * q); 42 static void draw_quarter_1(quarter_draw_dsc_t * q); 43 static void draw_quarter_2(quarter_draw_dsc_t * q); 44 static void draw_quarter_3(quarter_draw_dsc_t * q); 45 static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t thickness, lv_area_t * res_area); 46 #endif /*LV_DRAW_COMPLEX*/ 47 48 /********************** 49 * STATIC VARIABLES 50 **********************/ 51 52 /********************** 53 * MACROS 54 **********************/ 55 56 /********************** 57 * GLOBAL FUNCTIONS 58 **********************/ 59 60 void lv_draw_sw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center, uint16_t radius, 61 uint16_t start_angle, uint16_t end_angle) 62 { 63 #if LV_DRAW_COMPLEX 64 if(dsc->opa <= LV_OPA_MIN) return; 65 if(dsc->width == 0) return; 66 if(start_angle == end_angle) return; 67 68 lv_coord_t width = dsc->width; 69 if(width > radius) width = radius; 70 71 lv_draw_rect_dsc_t cir_dsc; 72 lv_draw_rect_dsc_init(&cir_dsc); 73 cir_dsc.blend_mode = dsc->blend_mode; 74 if(dsc->img_src) { 75 cir_dsc.bg_opa = LV_OPA_TRANSP; 76 cir_dsc.bg_img_src = dsc->img_src; 77 cir_dsc.bg_img_opa = dsc->opa; 78 } 79 else { 80 cir_dsc.bg_opa = dsc->opa; 81 cir_dsc.bg_color = dsc->color; 82 } 83 84 lv_area_t area_out; 85 area_out.x1 = center->x - radius; 86 area_out.y1 = center->y - radius; 87 area_out.x2 = center->x + radius - 1; /*-1 because the center already belongs to the left/bottom part*/ 88 area_out.y2 = center->y + radius - 1; 89 90 lv_area_t area_in; 91 lv_area_copy(&area_in, &area_out); 92 area_in.x1 += dsc->width; 93 area_in.y1 += dsc->width; 94 area_in.x2 -= dsc->width; 95 area_in.y2 -= dsc->width; 96 97 /*Create inner the mask*/ 98 int16_t mask_in_id = LV_MASK_ID_INV; 99 lv_draw_mask_radius_param_t mask_in_param; 100 if(lv_area_get_width(&area_in) > 0 && lv_area_get_height(&area_in) > 0) { 101 lv_draw_mask_radius_init(&mask_in_param, &area_in, LV_RADIUS_CIRCLE, true); 102 mask_in_id = lv_draw_mask_add(&mask_in_param, NULL); 103 } 104 105 lv_draw_mask_radius_param_t mask_out_param; 106 lv_draw_mask_radius_init(&mask_out_param, &area_out, LV_RADIUS_CIRCLE, false); 107 int16_t mask_out_id = lv_draw_mask_add(&mask_out_param, NULL); 108 109 /*Draw a full ring*/ 110 if(start_angle + 360 == end_angle || start_angle == end_angle + 360) { 111 cir_dsc.radius = LV_RADIUS_CIRCLE; 112 lv_draw_rect(draw_ctx, &cir_dsc, &area_out); 113 114 lv_draw_mask_remove_id(mask_out_id); 115 if(mask_in_id != LV_MASK_ID_INV) lv_draw_mask_remove_id(mask_in_id); 116 117 lv_draw_mask_free_param(&mask_out_param); 118 lv_draw_mask_free_param(&mask_in_param); 119 120 return; 121 } 122 123 while(start_angle >= 360) start_angle -= 360; 124 while(end_angle >= 360) end_angle -= 360; 125 126 lv_draw_mask_angle_param_t mask_angle_param; 127 lv_draw_mask_angle_init(&mask_angle_param, center->x, center->y, start_angle, end_angle); 128 int16_t mask_angle_id = lv_draw_mask_add(&mask_angle_param, NULL); 129 130 int32_t angle_gap; 131 if(end_angle > start_angle) { 132 angle_gap = 360 - (end_angle - start_angle); 133 } 134 else { 135 angle_gap = start_angle - end_angle; 136 } 137 138 const lv_area_t * clip_area_ori = draw_ctx->clip_area; 139 140 if(angle_gap > SPLIT_ANGLE_GAP_LIMIT && radius > SPLIT_RADIUS_LIMIT) { 141 /*Handle each quarter individually and skip which is empty*/ 142 quarter_draw_dsc_t q_dsc; 143 q_dsc.center = center; 144 q_dsc.radius = radius; 145 q_dsc.start_angle = start_angle; 146 q_dsc.end_angle = end_angle; 147 q_dsc.start_quarter = (start_angle / 90) & 0x3; 148 q_dsc.end_quarter = (end_angle / 90) & 0x3; 149 q_dsc.width = width; 150 q_dsc.draw_dsc = &cir_dsc; 151 q_dsc.draw_area = &area_out; 152 q_dsc.draw_ctx = draw_ctx; 153 154 draw_quarter_0(&q_dsc); 155 draw_quarter_1(&q_dsc); 156 draw_quarter_2(&q_dsc); 157 draw_quarter_3(&q_dsc); 158 } 159 else { 160 lv_draw_rect(draw_ctx, &cir_dsc, &area_out); 161 } 162 163 lv_draw_mask_free_param(&mask_angle_param); 164 lv_draw_mask_free_param(&mask_out_param); 165 lv_draw_mask_free_param(&mask_in_param); 166 167 lv_draw_mask_remove_id(mask_angle_id); 168 lv_draw_mask_remove_id(mask_out_id); 169 if(mask_in_id != LV_MASK_ID_INV) lv_draw_mask_remove_id(mask_in_id); 170 171 if(dsc->rounded) { 172 173 lv_draw_mask_radius_param_t mask_end_param; 174 175 lv_area_t round_area; 176 get_rounded_area(start_angle, radius, width, &round_area); 177 round_area.x1 += center->x; 178 round_area.x2 += center->x; 179 round_area.y1 += center->y; 180 round_area.y2 += center->y; 181 lv_area_t clip_area2; 182 if(_lv_area_intersect(&clip_area2, clip_area_ori, &round_area)) { 183 lv_draw_mask_radius_init(&mask_end_param, &round_area, LV_RADIUS_CIRCLE, false); 184 int16_t mask_end_id = lv_draw_mask_add(&mask_end_param, NULL); 185 186 draw_ctx->clip_area = &clip_area2; 187 lv_draw_rect(draw_ctx, &cir_dsc, &area_out); 188 lv_draw_mask_remove_id(mask_end_id); 189 lv_draw_mask_free_param(&mask_end_param); 190 } 191 192 get_rounded_area(end_angle, radius, width, &round_area); 193 round_area.x1 += center->x; 194 round_area.x2 += center->x; 195 round_area.y1 += center->y; 196 round_area.y2 += center->y; 197 if(_lv_area_intersect(&clip_area2, clip_area_ori, &round_area)) { 198 lv_draw_mask_radius_init(&mask_end_param, &round_area, LV_RADIUS_CIRCLE, false); 199 int16_t mask_end_id = lv_draw_mask_add(&mask_end_param, NULL); 200 201 draw_ctx->clip_area = &clip_area2; 202 lv_draw_rect(draw_ctx, &cir_dsc, &area_out); 203 lv_draw_mask_remove_id(mask_end_id); 204 lv_draw_mask_free_param(&mask_end_param); 205 } 206 draw_ctx->clip_area = clip_area_ori; 207 } 208 #else 209 LV_LOG_WARN("Can't draw arc with LV_DRAW_COMPLEX == 0"); 210 LV_UNUSED(center); 211 LV_UNUSED(radius); 212 LV_UNUSED(start_angle); 213 LV_UNUSED(end_angle); 214 LV_UNUSED(draw_ctx); 215 LV_UNUSED(dsc); 216 #endif /*LV_DRAW_COMPLEX*/ 217 } 218 219 /********************** 220 * STATIC FUNCTIONS 221 **********************/ 222 223 #if LV_DRAW_COMPLEX 224 static void draw_quarter_0(quarter_draw_dsc_t * q) 225 { 226 const lv_area_t * clip_area_ori = q->draw_ctx->clip_area; 227 lv_area_t quarter_area; 228 229 if(q->start_quarter == 0 && q->end_quarter == 0 && q->start_angle < q->end_angle) { 230 /*Small arc here*/ 231 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 232 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 233 234 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT); 235 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 236 237 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 238 if(ok) { 239 q->draw_ctx->clip_area = &quarter_area; 240 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 241 } 242 } 243 else if(q->start_quarter == 0 || q->end_quarter == 0) { 244 /*Start and/or end arcs here*/ 245 if(q->start_quarter == 0) { 246 quarter_area.x1 = q->center->x; 247 quarter_area.y2 = q->center->y + q->radius; 248 249 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 250 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 251 252 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 253 if(ok) { 254 q->draw_ctx->clip_area = &quarter_area; 255 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 256 } 257 } 258 if(q->end_quarter == 0) { 259 quarter_area.x2 = q->center->x + q->radius; 260 quarter_area.y1 = q->center->y; 261 262 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT); 263 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 264 265 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 266 if(ok) { 267 q->draw_ctx->clip_area = &quarter_area; 268 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 269 } 270 } 271 } 272 else if((q->start_quarter == q->end_quarter && q->start_quarter != 0 && q->end_angle < q->start_angle) || 273 (q->start_quarter == 2 && q->end_quarter == 1) || 274 (q->start_quarter == 3 && q->end_quarter == 2) || 275 (q->start_quarter == 3 && q->end_quarter == 1)) { 276 /*Arc crosses here*/ 277 quarter_area.x1 = q->center->x; 278 quarter_area.y1 = q->center->y; 279 quarter_area.x2 = q->center->x + q->radius; 280 quarter_area.y2 = q->center->y + q->radius; 281 282 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 283 if(ok) { 284 q->draw_ctx->clip_area = &quarter_area; 285 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 286 } 287 } 288 q->draw_ctx->clip_area = clip_area_ori; 289 } 290 291 static void draw_quarter_1(quarter_draw_dsc_t * q) 292 { 293 const lv_area_t * clip_area_ori = q->draw_ctx->clip_area; 294 lv_area_t quarter_area; 295 296 if(q->start_quarter == 1 && q->end_quarter == 1 && q->start_angle < q->end_angle) { 297 /*Small arc here*/ 298 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT); 299 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 300 301 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 302 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 303 304 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 305 if(ok) { 306 q->draw_ctx->clip_area = &quarter_area; 307 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 308 } 309 } 310 else if(q->start_quarter == 1 || q->end_quarter == 1) { 311 /*Start and/or end arcs here*/ 312 if(q->start_quarter == 1) { 313 quarter_area.x1 = q->center->x - q->radius; 314 quarter_area.y1 = q->center->y; 315 316 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT); 317 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 318 319 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 320 if(ok) { 321 q->draw_ctx->clip_area = &quarter_area; 322 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 323 } 324 } 325 if(q->end_quarter == 1) { 326 quarter_area.x2 = q->center->x - 1; 327 quarter_area.y2 = q->center->y + q->radius; 328 329 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 330 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 331 332 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 333 if(ok) { 334 q->draw_ctx->clip_area = &quarter_area; 335 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 336 } 337 } 338 } 339 else if((q->start_quarter == q->end_quarter && q->start_quarter != 1 && q->end_angle < q->start_angle) || 340 (q->start_quarter == 0 && q->end_quarter == 2) || 341 (q->start_quarter == 0 && q->end_quarter == 3) || 342 (q->start_quarter == 3 && q->end_quarter == 2)) { 343 /*Arc crosses here*/ 344 quarter_area.x1 = q->center->x - q->radius; 345 quarter_area.y1 = q->center->y; 346 quarter_area.x2 = q->center->x - 1; 347 quarter_area.y2 = q->center->y + q->radius; 348 349 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 350 if(ok) { 351 q->draw_ctx->clip_area = &quarter_area; 352 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 353 } 354 } 355 q->draw_ctx->clip_area = clip_area_ori; 356 } 357 358 static void draw_quarter_2(quarter_draw_dsc_t * q) 359 { 360 const lv_area_t * clip_area_ori = q->draw_ctx->clip_area; 361 lv_area_t quarter_area; 362 363 if(q->start_quarter == 2 && q->end_quarter == 2 && q->start_angle < q->end_angle) { 364 /*Small arc here*/ 365 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 366 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 367 368 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT); 369 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 370 371 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 372 if(ok) { 373 q->draw_ctx->clip_area = &quarter_area; 374 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 375 } 376 } 377 else if(q->start_quarter == 2 || q->end_quarter == 2) { 378 /*Start and/or end arcs here*/ 379 if(q->start_quarter == 2) { 380 quarter_area.x2 = q->center->x - 1; 381 quarter_area.y1 = q->center->y - q->radius; 382 383 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 384 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 385 386 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 387 if(ok) { 388 q->draw_ctx->clip_area = &quarter_area; 389 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 390 } 391 } 392 if(q->end_quarter == 2) { 393 quarter_area.x1 = q->center->x - q->radius; 394 quarter_area.y2 = q->center->y - 1; 395 396 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 397 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->end_angle) * (q->radius)) >> LV_TRIGO_SHIFT); 398 399 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 400 if(ok) { 401 q->draw_ctx->clip_area = &quarter_area; 402 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 403 } 404 } 405 } 406 else if((q->start_quarter == q->end_quarter && q->start_quarter != 2 && q->end_angle < q->start_angle) || 407 (q->start_quarter == 0 && q->end_quarter == 3) || 408 (q->start_quarter == 1 && q->end_quarter == 3) || 409 (q->start_quarter == 1 && q->end_quarter == 0)) { 410 /*Arc crosses here*/ 411 quarter_area.x1 = q->center->x - q->radius; 412 quarter_area.y1 = q->center->y - q->radius; 413 quarter_area.x2 = q->center->x - 1; 414 quarter_area.y2 = q->center->y - 1; 415 416 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 417 if(ok) { 418 q->draw_ctx->clip_area = &quarter_area; 419 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 420 } 421 } 422 q->draw_ctx->clip_area = clip_area_ori; 423 } 424 425 static void draw_quarter_3(quarter_draw_dsc_t * q) 426 { 427 const lv_area_t * clip_area_ori = q->draw_ctx->clip_area; 428 lv_area_t quarter_area; 429 430 if(q->start_quarter == 3 && q->end_quarter == 3 && q->start_angle < q->end_angle) { 431 /*Small arc here*/ 432 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 433 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT); 434 435 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 436 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 437 438 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 439 if(ok) { 440 q->draw_ctx->clip_area = &quarter_area; 441 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 442 } 443 } 444 else if(q->start_quarter == 3 || q->end_quarter == 3) { 445 /*Start and/or end arcs here*/ 446 if(q->start_quarter == 3) { 447 quarter_area.x2 = q->center->x + q->radius; 448 quarter_area.y2 = q->center->y - 1; 449 450 quarter_area.x1 = q->center->x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 451 quarter_area.y1 = q->center->y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT); 452 453 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 454 if(ok) { 455 q->draw_ctx->clip_area = &quarter_area; 456 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 457 } 458 } 459 if(q->end_quarter == 3) { 460 quarter_area.x1 = q->center->x; 461 quarter_area.y1 = q->center->y - q->radius; 462 463 quarter_area.x2 = q->center->x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT); 464 quarter_area.y2 = q->center->y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT); 465 466 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 467 if(ok) { 468 q->draw_ctx->clip_area = &quarter_area; 469 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 470 } 471 } 472 } 473 else if((q->start_quarter == q->end_quarter && q->start_quarter != 3 && q->end_angle < q->start_angle) || 474 (q->start_quarter == 2 && q->end_quarter == 0) || 475 (q->start_quarter == 1 && q->end_quarter == 0) || 476 (q->start_quarter == 2 && q->end_quarter == 1)) { 477 /*Arc crosses here*/ 478 quarter_area.x1 = q->center->x; 479 quarter_area.y1 = q->center->y - q->radius; 480 quarter_area.x2 = q->center->x + q->radius; 481 quarter_area.y2 = q->center->y - 1; 482 483 bool ok = _lv_area_intersect(&quarter_area, &quarter_area, clip_area_ori); 484 if(ok) { 485 q->draw_ctx->clip_area = &quarter_area; 486 lv_draw_rect(q->draw_ctx, q->draw_dsc, q->draw_area); 487 } 488 } 489 490 q->draw_ctx->clip_area = clip_area_ori; 491 } 492 493 static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t thickness, lv_area_t * res_area) 494 { 495 const uint8_t ps = 8; 496 const uint8_t pa = 127; 497 498 int32_t thick_half = thickness / 2; 499 uint8_t thick_corr = (thickness & 0x01) ? 0 : 1; 500 501 int32_t cir_x; 502 int32_t cir_y; 503 504 cir_x = ((radius - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps); 505 cir_y = ((radius - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps); 506 507 /*Actually the center of the pixel need to be calculated so apply 1/2 px offset*/ 508 if(cir_x > 0) { 509 cir_x = (cir_x - pa) >> ps; 510 res_area->x1 = cir_x - thick_half + thick_corr; 511 res_area->x2 = cir_x + thick_half; 512 } 513 else { 514 cir_x = (cir_x + pa) >> ps; 515 res_area->x1 = cir_x - thick_half; 516 res_area->x2 = cir_x + thick_half - thick_corr; 517 } 518 519 if(cir_y > 0) { 520 cir_y = (cir_y - pa) >> ps; 521 res_area->y1 = cir_y - thick_half + thick_corr; 522 res_area->y2 = cir_y + thick_half; 523 } 524 else { 525 cir_y = (cir_y + pa) >> ps; 526 res_area->y1 = cir_y - thick_half; 527 res_area->y2 = cir_y + thick_half - thick_corr; 528 } 529 } 530 531 #endif /*LV_DRAW_COMPLEX*/