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_img.c (23560B)
1 /** 2 * @file lv_img.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_img.h" 10 #if LV_USE_IMG != 0 11 12 #include "../misc/lv_assert.h" 13 #include "../draw/lv_img_decoder.h" 14 #include "../misc/lv_fs.h" 15 #include "../misc/lv_txt.h" 16 #include "../misc/lv_math.h" 17 #include "../misc/lv_log.h" 18 19 /********************* 20 * DEFINES 21 *********************/ 22 #define MY_CLASS &lv_img_class 23 24 /********************** 25 * TYPEDEFS 26 **********************/ 27 28 /********************** 29 * STATIC PROTOTYPES 30 **********************/ 31 static void lv_img_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); 32 static void lv_img_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); 33 static void lv_img_event(const lv_obj_class_t * class_p, lv_event_t * e); 34 static void draw_img(lv_event_t * e); 35 36 /********************** 37 * STATIC VARIABLES 38 **********************/ 39 const lv_obj_class_t lv_img_class = { 40 .constructor_cb = lv_img_constructor, 41 .destructor_cb = lv_img_destructor, 42 .event_cb = lv_img_event, 43 .width_def = LV_SIZE_CONTENT, 44 .height_def = LV_SIZE_CONTENT, 45 .instance_size = sizeof(lv_img_t), 46 .base_class = &lv_obj_class 47 }; 48 49 /********************** 50 * MACROS 51 **********************/ 52 53 /********************** 54 * GLOBAL FUNCTIONS 55 **********************/ 56 57 lv_obj_t * lv_img_create(lv_obj_t * parent) 58 { 59 LV_LOG_INFO("begin"); 60 lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); 61 lv_obj_class_init_obj(obj); 62 return obj; 63 } 64 65 /*===================== 66 * Setter functions 67 *====================*/ 68 69 void lv_img_set_src(lv_obj_t * obj, const void * src) 70 { 71 LV_ASSERT_OBJ(obj, MY_CLASS); 72 73 lv_obj_invalidate(obj); 74 75 lv_img_src_t src_type = lv_img_src_get_type(src); 76 lv_img_t * img = (lv_img_t *)obj; 77 78 #if LV_USE_LOG && LV_LOG_LEVEL >= LV_LOG_LEVEL_INFO 79 switch(src_type) { 80 case LV_IMG_SRC_FILE: 81 LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_FILE` type found"); 82 break; 83 case LV_IMG_SRC_VARIABLE: 84 LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_VARIABLE` type found"); 85 break; 86 case LV_IMG_SRC_SYMBOL: 87 LV_LOG_TRACE("lv_img_set_src: `LV_IMG_SRC_SYMBOL` type found"); 88 break; 89 default: 90 LV_LOG_WARN("lv_img_set_src: unknown type"); 91 } 92 #endif 93 94 /*If the new source type is unknown free the memories of the old source*/ 95 if(src_type == LV_IMG_SRC_UNKNOWN) { 96 LV_LOG_WARN("lv_img_set_src: unknown image type"); 97 if(img->src_type == LV_IMG_SRC_SYMBOL || img->src_type == LV_IMG_SRC_FILE) { 98 lv_mem_free((void *)img->src); 99 } 100 img->src = NULL; 101 img->src_type = LV_IMG_SRC_UNKNOWN; 102 return; 103 } 104 105 lv_img_header_t header; 106 lv_img_decoder_get_info(src, &header); 107 108 /*Save the source*/ 109 if(src_type == LV_IMG_SRC_VARIABLE) { 110 /*If memory was allocated because of the previous `src_type` then free it*/ 111 if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_SYMBOL) { 112 lv_mem_free((void *)img->src); 113 } 114 img->src = src; 115 } 116 else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) { 117 /*If the new and the old src are the same then it was only a refresh.*/ 118 if(img->src != src) { 119 const void * old_src = NULL; 120 /*If memory was allocated because of the previous `src_type` then save its pointer and free after allocation. 121 *It's important to allocate first to be sure the new data will be on a new address. 122 *Else `img_cache` wouldn't see the change in source.*/ 123 if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_SYMBOL) { 124 old_src = img->src; 125 } 126 char * new_str = lv_mem_alloc(strlen(src) + 1); 127 LV_ASSERT_MALLOC(new_str); 128 if(new_str == NULL) return; 129 strcpy(new_str, src); 130 img->src = new_str; 131 132 if(old_src) lv_mem_free((void *)old_src); 133 } 134 } 135 136 if(src_type == LV_IMG_SRC_SYMBOL) { 137 /*`lv_img_dsc_get_info` couldn't set the width and height of a font so set it here*/ 138 const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); 139 lv_coord_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); 140 lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); 141 lv_point_t size; 142 lv_txt_get_size(&size, src, font, letter_space, line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); 143 header.w = size.x; 144 header.h = size.y; 145 } 146 147 img->src_type = src_type; 148 img->w = header.w; 149 img->h = header.h; 150 img->cf = header.cf; 151 img->pivot.x = header.w / 2; 152 img->pivot.y = header.h / 2; 153 154 lv_obj_refresh_self_size(obj); 155 156 /*Provide enough room for the rotated corners*/ 157 if(img->angle || img->zoom != LV_IMG_ZOOM_NONE) lv_obj_refresh_ext_draw_size(obj); 158 159 lv_obj_invalidate(obj); 160 } 161 162 void lv_img_set_offset_x(lv_obj_t * obj, lv_coord_t x) 163 { 164 LV_ASSERT_OBJ(obj, MY_CLASS); 165 166 lv_img_t * img = (lv_img_t *)obj; 167 168 x = x % img->w; 169 170 img->offset.x = x; 171 lv_obj_invalidate(obj); 172 } 173 174 void lv_img_set_offset_y(lv_obj_t * obj, lv_coord_t y) 175 { 176 LV_ASSERT_OBJ(obj, MY_CLASS); 177 178 lv_img_t * img = (lv_img_t *)obj; 179 180 y = y % img->h; 181 182 img->offset.y = y; 183 lv_obj_invalidate(obj); 184 } 185 186 void lv_img_set_angle(lv_obj_t * obj, int16_t angle) 187 { 188 if(angle < 0 || angle >= 3600) angle = angle % 3600; 189 190 lv_img_t * img = (lv_img_t *)obj; 191 if(angle == img->angle) return; 192 193 lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 194 transf_zoom = ((int32_t)transf_zoom * img->zoom) >> 8; 195 196 lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 197 198 lv_obj_update_layout(obj); /*Be sure the object's size is calculated*/ 199 lv_coord_t w = lv_obj_get_width(obj); 200 lv_coord_t h = lv_obj_get_height(obj); 201 lv_area_t a; 202 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle + img->angle, transf_zoom, &img->pivot); 203 a.x1 += obj->coords.x1; 204 a.y1 += obj->coords.y1; 205 a.x2 += obj->coords.x1; 206 a.y2 += obj->coords.y1; 207 lv_obj_invalidate_area(obj, &a); 208 209 img->angle = angle; 210 lv_obj_refresh_ext_draw_size(obj); 211 212 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle + img->angle, transf_zoom, &img->pivot); 213 a.x1 += obj->coords.x1; 214 a.y1 += obj->coords.y1; 215 a.x2 += obj->coords.x1; 216 a.y2 += obj->coords.y1; 217 lv_obj_invalidate_area(obj, &a); 218 } 219 220 void lv_img_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y) 221 { 222 lv_img_t * img = (lv_img_t *)obj; 223 if(img->pivot.x == x && img->pivot.y == y) return; 224 225 lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 226 transf_zoom = ((int32_t)transf_zoom * img->zoom) >> 8; 227 228 lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 229 transf_angle += img->angle; 230 231 lv_obj_update_layout(obj); /*Be sure the object's size is calculated*/ 232 lv_coord_t w = lv_obj_get_width(obj); 233 lv_coord_t h = lv_obj_get_height(obj); 234 lv_area_t a; 235 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); 236 a.x1 += obj->coords.x1; 237 a.y1 += obj->coords.y1; 238 a.x2 += obj->coords.x1; 239 a.y2 += obj->coords.y1; 240 lv_obj_invalidate_area(obj, &a); 241 242 img->pivot.x = x; 243 img->pivot.y = y; 244 lv_obj_refresh_ext_draw_size(obj); 245 246 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); 247 a.x1 += obj->coords.x1; 248 a.y1 += obj->coords.y1; 249 a.x2 += obj->coords.x1; 250 a.y2 += obj->coords.y1; 251 lv_obj_invalidate_area(obj, &a); 252 } 253 254 void lv_img_set_zoom(lv_obj_t * obj, uint16_t zoom) 255 { 256 lv_img_t * img = (lv_img_t *)obj; 257 if(zoom == img->zoom) return; 258 259 if(zoom == 0) zoom = 1; 260 261 lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 262 263 lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 264 transf_angle += img->angle; 265 266 lv_obj_update_layout(obj); /*Be sure the object's size is calculated*/ 267 lv_coord_t w = lv_obj_get_width(obj); 268 lv_coord_t h = lv_obj_get_height(obj); 269 lv_area_t a; 270 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, ((int32_t)transf_zoom * img->zoom) >> 8, &img->pivot); 271 a.x1 += obj->coords.x1 - 1; 272 a.y1 += obj->coords.y1 - 1; 273 a.x2 += obj->coords.x1 + 1; 274 a.y2 += obj->coords.y1 + 1; 275 lv_obj_invalidate_area(obj, &a); 276 277 img->zoom = zoom; 278 lv_obj_refresh_ext_draw_size(obj); 279 280 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, ((int32_t)transf_zoom * img->zoom) >> 8, &img->pivot); 281 a.x1 += obj->coords.x1 - 1; 282 a.y1 += obj->coords.y1 - 1; 283 a.x2 += obj->coords.x1 + 1; 284 a.y2 += obj->coords.y1 + 1; 285 lv_obj_invalidate_area(obj, &a); 286 } 287 288 void lv_img_set_antialias(lv_obj_t * obj, bool antialias) 289 { 290 lv_img_t * img = (lv_img_t *)obj; 291 if(antialias == img->antialias) return; 292 293 img->antialias = antialias; 294 lv_obj_invalidate(obj); 295 } 296 297 void lv_img_set_size_mode(lv_obj_t * obj, lv_img_size_mode_t mode) 298 { 299 LV_ASSERT_OBJ(obj, MY_CLASS); 300 lv_img_t * img = (lv_img_t *)obj; 301 if(mode == img->obj_size_mode) return; 302 303 img->obj_size_mode = mode; 304 lv_obj_invalidate(obj); 305 } 306 307 /*===================== 308 * Getter functions 309 *====================*/ 310 311 const void * lv_img_get_src(lv_obj_t * obj) 312 { 313 LV_ASSERT_OBJ(obj, MY_CLASS); 314 315 lv_img_t * img = (lv_img_t *)obj; 316 317 return img->src; 318 } 319 320 lv_coord_t lv_img_get_offset_x(lv_obj_t * obj) 321 { 322 LV_ASSERT_OBJ(obj, MY_CLASS); 323 324 lv_img_t * img = (lv_img_t *)obj; 325 326 return img->offset.x; 327 } 328 329 lv_coord_t lv_img_get_offset_y(lv_obj_t * obj) 330 { 331 LV_ASSERT_OBJ(obj, MY_CLASS); 332 333 lv_img_t * img = (lv_img_t *)obj; 334 335 return img->offset.y; 336 } 337 338 uint16_t lv_img_get_angle(lv_obj_t * obj) 339 { 340 LV_ASSERT_OBJ(obj, MY_CLASS); 341 342 lv_img_t * img = (lv_img_t *)obj; 343 344 return img->angle; 345 } 346 347 void lv_img_get_pivot(lv_obj_t * obj, lv_point_t * pivot) 348 { 349 LV_ASSERT_OBJ(obj, MY_CLASS); 350 351 lv_img_t * img = (lv_img_t *)obj; 352 353 *pivot = img->pivot; 354 } 355 356 uint16_t lv_img_get_zoom(lv_obj_t * obj) 357 { 358 LV_ASSERT_OBJ(obj, MY_CLASS); 359 360 lv_img_t * img = (lv_img_t *)obj; 361 362 return img->zoom; 363 } 364 365 bool lv_img_get_antialias(lv_obj_t * obj) 366 { 367 LV_ASSERT_OBJ(obj, MY_CLASS); 368 369 lv_img_t * img = (lv_img_t *)obj; 370 371 return img->antialias ? true : false; 372 } 373 374 lv_img_size_mode_t lv_img_get_size_mode(lv_obj_t * obj) 375 { 376 LV_ASSERT_OBJ(obj, MY_CLASS); 377 lv_img_t * img = (lv_img_t *)obj; 378 return img->obj_size_mode; 379 } 380 381 /********************** 382 * STATIC FUNCTIONS 383 **********************/ 384 385 static void lv_img_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) 386 { 387 LV_UNUSED(class_p); 388 LV_TRACE_OBJ_CREATE("begin"); 389 390 lv_img_t * img = (lv_img_t *)obj; 391 392 img->src = NULL; 393 img->src_type = LV_IMG_SRC_UNKNOWN; 394 img->cf = LV_IMG_CF_UNKNOWN; 395 img->w = lv_obj_get_width(obj); 396 img->h = lv_obj_get_height(obj); 397 img->angle = 0; 398 img->zoom = LV_IMG_ZOOM_NONE; 399 img->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0; 400 img->offset.x = 0; 401 img->offset.y = 0; 402 img->pivot.x = 0; 403 img->pivot.y = 0; 404 img->obj_size_mode = LV_IMG_SIZE_MODE_VIRTUAL; 405 406 lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); 407 lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST); 408 409 LV_TRACE_OBJ_CREATE("finished"); 410 } 411 412 static void lv_img_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) 413 { 414 LV_UNUSED(class_p); 415 lv_img_t * img = (lv_img_t *)obj; 416 if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_SYMBOL) { 417 lv_mem_free((void *)img->src); 418 img->src = NULL; 419 img->src_type = LV_IMG_SRC_UNKNOWN; 420 } 421 } 422 423 static lv_point_t lv_img_get_transformed_size(lv_obj_t * obj) 424 { 425 lv_img_t * img = (lv_img_t *)obj; 426 427 int32_t zoom_final = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 428 zoom_final = (zoom_final * img->zoom) >> 8; 429 int32_t angle_final = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 430 angle_final += img->angle; 431 432 lv_area_t area_transform; 433 _lv_img_buf_get_transformed_area(&area_transform, img->w, img->h, 434 angle_final, zoom_final, &img->pivot); 435 436 return (lv_point_t) { 437 lv_area_get_width(&area_transform), lv_area_get_height(&area_transform) 438 }; 439 } 440 441 static void lv_img_event(const lv_obj_class_t * class_p, lv_event_t * e) 442 { 443 LV_UNUSED(class_p); 444 445 lv_event_code_t code = lv_event_get_code(e); 446 447 /*Ancestor events will be called during drawing*/ 448 if(code != LV_EVENT_DRAW_MAIN && code != LV_EVENT_DRAW_POST) { 449 /*Call the ancestor's event handler*/ 450 lv_res_t res = lv_obj_event_base(MY_CLASS, e); 451 if(res != LV_RES_OK) return; 452 } 453 454 lv_obj_t * obj = lv_event_get_target(e); 455 lv_img_t * img = (lv_img_t *)obj; 456 457 if(code == LV_EVENT_STYLE_CHANGED) { 458 /*Refresh the file name to refresh the symbol text size*/ 459 if(img->src_type == LV_IMG_SRC_SYMBOL) { 460 lv_img_set_src(obj, img->src); 461 } 462 else { 463 /*With transformation it might change*/ 464 lv_obj_refresh_ext_draw_size(obj); 465 } 466 } 467 else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) { 468 469 lv_coord_t * s = lv_event_get_param(e); 470 lv_coord_t transf_zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 471 transf_zoom = ((int32_t)transf_zoom * img->zoom) >> 8; 472 473 lv_coord_t transf_angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 474 transf_angle += img->angle; 475 476 /*If the image has angle provide enough room for the rotated corners*/ 477 if(transf_angle || transf_zoom != LV_IMG_ZOOM_NONE) { 478 lv_area_t a; 479 lv_coord_t w = lv_obj_get_width(obj); 480 lv_coord_t h = lv_obj_get_height(obj); 481 _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &img->pivot); 482 lv_coord_t pad_ori = *s; 483 *s = LV_MAX(*s, pad_ori - a.x1); 484 *s = LV_MAX(*s, pad_ori - a.y1); 485 *s = LV_MAX(*s, pad_ori + a.x2 - w); 486 *s = LV_MAX(*s, pad_ori + a.y2 - h); 487 } 488 } 489 else if(code == LV_EVENT_HIT_TEST) { 490 lv_hit_test_info_t * info = lv_event_get_param(e); 491 lv_coord_t zoom = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 492 zoom = (zoom * img->zoom) >> 8; 493 494 lv_coord_t angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 495 angle += img->angle; 496 497 /*If the object is exactly image sized (not cropped, not mosaic) and transformed 498 *perform hit test on its transformed area*/ 499 if(img->w == lv_obj_get_width(obj) && img->h == lv_obj_get_height(obj) && 500 (zoom != LV_IMG_ZOOM_NONE || angle != 0 || img->pivot.x != img->w / 2 || img->pivot.y != img->h / 2)) { 501 502 lv_coord_t w = lv_obj_get_width(obj); 503 lv_coord_t h = lv_obj_get_height(obj); 504 lv_area_t coords; 505 _lv_img_buf_get_transformed_area(&coords, w, h, angle, zoom, &img->pivot); 506 coords.x1 += obj->coords.x1; 507 coords.y1 += obj->coords.y1; 508 coords.x2 += obj->coords.x1; 509 coords.y2 += obj->coords.y1; 510 511 info->res = _lv_area_is_point_on(&coords, info->point, 0); 512 } 513 else { 514 lv_area_t a; 515 lv_obj_get_click_area(obj, &a); 516 info->res = _lv_area_is_point_on(&a, info->point, 0); 517 } 518 } 519 else if(code == LV_EVENT_GET_SELF_SIZE) { 520 lv_point_t * p = lv_event_get_param(e); 521 if(img->obj_size_mode == LV_IMG_SIZE_MODE_REAL) { 522 *p = lv_img_get_transformed_size(obj); 523 } 524 else { 525 p->x = img->w; 526 p->y = img->h; 527 } 528 } 529 else if(code == LV_EVENT_DRAW_MAIN || code == LV_EVENT_DRAW_POST || code == LV_EVENT_COVER_CHECK) { 530 draw_img(e); 531 } 532 } 533 534 static void draw_img(lv_event_t * e) 535 { 536 lv_event_code_t code = lv_event_get_code(e); 537 lv_obj_t * obj = lv_event_get_target(e); 538 lv_img_t * img = (lv_img_t *)obj; 539 if(code == LV_EVENT_COVER_CHECK) { 540 lv_cover_check_info_t * info = lv_event_get_param(e); 541 if(info->res == LV_COVER_RES_MASKED) return; 542 if(img->src_type == LV_IMG_SRC_UNKNOWN || img->src_type == LV_IMG_SRC_SYMBOL) { 543 info->res = LV_COVER_RES_NOT_COVER; 544 return; 545 } 546 547 /*Non true color format might have "holes"*/ 548 if(img->cf != LV_IMG_CF_TRUE_COLOR && img->cf != LV_IMG_CF_RAW) { 549 info->res = LV_COVER_RES_NOT_COVER; 550 return; 551 } 552 553 /*With not LV_OPA_COVER images can't cover an area */ 554 if(lv_obj_get_style_img_opa(obj, LV_PART_MAIN) != LV_OPA_COVER) { 555 info->res = LV_COVER_RES_NOT_COVER; 556 return; 557 } 558 559 int32_t angle_final = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 560 angle_final += img->angle; 561 562 if(angle_final != 0) { 563 info->res = LV_COVER_RES_NOT_COVER; 564 return; 565 } 566 567 int32_t zoom_final = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 568 zoom_final = (zoom_final * img->zoom) >> 8; 569 570 const lv_area_t * clip_area = lv_event_get_param(e); 571 if(zoom_final == LV_IMG_ZOOM_NONE) { 572 if(_lv_area_is_in(clip_area, &obj->coords, 0) == false) { 573 info->res = LV_COVER_RES_NOT_COVER; 574 return; 575 } 576 } 577 else { 578 lv_area_t a; 579 _lv_img_buf_get_transformed_area(&a, lv_obj_get_width(obj), lv_obj_get_height(obj), 0, zoom_final, &img->pivot); 580 a.x1 += obj->coords.x1; 581 a.y1 += obj->coords.y1; 582 a.x2 += obj->coords.x1; 583 a.y2 += obj->coords.y1; 584 585 if(_lv_area_is_in(clip_area, &a, 0) == false) { 586 info->res = LV_COVER_RES_NOT_COVER; 587 return; 588 } 589 } 590 } 591 else if(code == LV_EVENT_DRAW_MAIN || code == LV_EVENT_DRAW_POST) { 592 593 int32_t zoom_final = lv_obj_get_style_transform_zoom(obj, LV_PART_MAIN); 594 zoom_final = (zoom_final * img->zoom) >> 8; 595 596 int32_t angle_final = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); 597 angle_final += img->angle; 598 599 lv_coord_t obj_w = lv_obj_get_width(obj); 600 lv_coord_t obj_h = lv_obj_get_height(obj); 601 602 lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); 603 lv_coord_t pleft = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width; 604 lv_coord_t pright = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width; 605 lv_coord_t ptop = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width; 606 lv_coord_t pbottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN) + border_width; 607 608 lv_point_t bg_pivot; 609 bg_pivot.x = img->pivot.x + pleft; 610 bg_pivot.y = img->pivot.y + ptop; 611 lv_area_t bg_coords; 612 613 if(img->obj_size_mode == LV_IMG_SIZE_MODE_REAL) { 614 /*Object size equals to transformed image size*/ 615 lv_obj_get_coords(obj, &bg_coords); 616 } 617 else { 618 _lv_img_buf_get_transformed_area(&bg_coords, obj_w, obj_h, 619 angle_final, zoom_final, &bg_pivot); 620 621 /*Modify the coordinates to draw the background for the rotated and scaled coordinates*/ 622 bg_coords.x1 += obj->coords.x1; 623 bg_coords.y1 += obj->coords.y1; 624 bg_coords.x2 += obj->coords.x1; 625 bg_coords.y2 += obj->coords.y1; 626 } 627 628 lv_area_t ori_coords; 629 lv_area_copy(&ori_coords, &obj->coords); 630 lv_area_copy(&obj->coords, &bg_coords); 631 632 lv_res_t res = lv_obj_event_base(MY_CLASS, e); 633 if(res != LV_RES_OK) return; 634 635 lv_area_copy(&obj->coords, &ori_coords); 636 637 if(code == LV_EVENT_DRAW_MAIN) { 638 if(img->h == 0 || img->w == 0) return; 639 if(zoom_final == 0) return; 640 641 lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e); 642 643 lv_area_t img_max_area; 644 lv_area_copy(&img_max_area, &obj->coords); 645 646 lv_point_t img_size_final = lv_img_get_transformed_size(obj); 647 648 if(img->obj_size_mode == LV_IMG_SIZE_MODE_REAL) { 649 img_max_area.x1 -= ((img->w - img_size_final.x) + 1) / 2; 650 img_max_area.x2 -= ((img->w - img_size_final.x) + 1) / 2; 651 img_max_area.y1 -= ((img->h - img_size_final.y) + 1) / 2; 652 img_max_area.y2 -= ((img->h - img_size_final.y) + 1) / 2; 653 } 654 else { 655 img_max_area.x2 = img_max_area.x1 + lv_area_get_width(&bg_coords) - 1; 656 img_max_area.y2 = img_max_area.y1 + lv_area_get_height(&bg_coords) - 1; 657 } 658 659 img_max_area.x1 += pleft; 660 img_max_area.y1 += ptop; 661 img_max_area.x2 -= pright; 662 img_max_area.y2 -= pbottom; 663 664 if(img->src_type == LV_IMG_SRC_FILE || img->src_type == LV_IMG_SRC_VARIABLE) { 665 lv_draw_img_dsc_t img_dsc; 666 lv_draw_img_dsc_init(&img_dsc); 667 lv_obj_init_draw_img_dsc(obj, LV_PART_MAIN, &img_dsc); 668 669 img_dsc.zoom = zoom_final; 670 img_dsc.angle = angle_final; 671 img_dsc.pivot.x = img->pivot.x; 672 img_dsc.pivot.y = img->pivot.y; 673 img_dsc.antialias = img->antialias; 674 675 lv_area_t img_clip_area; 676 img_clip_area.x1 = bg_coords.x1 + pleft; 677 img_clip_area.y1 = bg_coords.y1 + ptop; 678 img_clip_area.x2 = bg_coords.x2 - pright; 679 img_clip_area.y2 = bg_coords.y2 - pbottom; 680 const lv_area_t * clip_area_ori = draw_ctx->clip_area; 681 682 if(!_lv_area_intersect(&img_clip_area, draw_ctx->clip_area, &img_clip_area)) return; 683 draw_ctx->clip_area = &img_clip_area; 684 685 lv_area_t coords_tmp; 686 coords_tmp.y1 = img_max_area.y1 + img->offset.y; 687 if(coords_tmp.y1 > img_max_area.y1) coords_tmp.y1 -= img->h; 688 coords_tmp.y2 = coords_tmp.y1 + img->h - 1; 689 690 for(; coords_tmp.y1 < img_max_area.y2; coords_tmp.y1 += img_size_final.y, coords_tmp.y2 += img_size_final.y) { 691 coords_tmp.x1 = img_max_area.x1 + img->offset.x; 692 if(coords_tmp.x1 > img_max_area.x1) coords_tmp.x1 -= img->w; 693 coords_tmp.x2 = coords_tmp.x1 + img->w - 1; 694 695 for(; coords_tmp.x1 < img_max_area.x2; coords_tmp.x1 += img_size_final.x, coords_tmp.x2 += img_size_final.x) { 696 lv_draw_img(draw_ctx, &img_dsc, &coords_tmp, img->src); 697 } 698 } 699 draw_ctx->clip_area = clip_area_ori; 700 } 701 else if(img->src_type == LV_IMG_SRC_SYMBOL) { 702 lv_draw_label_dsc_t label_dsc; 703 lv_draw_label_dsc_init(&label_dsc); 704 lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc); 705 706 lv_draw_label(draw_ctx, &label_dsc, &obj->coords, img->src, NULL); 707 } 708 else { 709 /*Trigger the error handler of image draw*/ 710 LV_LOG_WARN("draw_img: image source type is unknown"); 711 lv_draw_img(draw_ctx, NULL, &obj->coords, NULL); 712 } 713 } 714 } 715 } 716 717 #endif