diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 3d5860473b..4b10dc7c44 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -44,7 +44,6 @@ static void refr_invalid_areas(void); static void refr_sync_areas(void); static void refr_area(const lv_area_t * area_p, int32_t y_offset); static void refr_configured_layer(lv_layer_t * layer); -static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj); static void refr_obj(lv_layer_t * layer, lv_obj_t * obj); static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h); @@ -432,6 +431,49 @@ refr_finish: LV_PROFILER_REFR_END; } +/** + * Search the most top object which fully covers an area + * @param area_p pointer to an area + * @param obj the first object to start the searching (typically a screen) + * @return + */ +lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) +{ + lv_obj_t * found_p = NULL; + + if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; + if(lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; + if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) return NULL; + + /*If this object is fully cover the draw area then check the children too*/ + lv_cover_check_info_t info; + info.res = LV_COVER_RES_COVER; + info.area = area_p; + lv_obj_send_event(obj, LV_EVENT_COVER_CHECK, &info); + if(info.res == LV_COVER_RES_MASKED) return NULL; + + int32_t i; + int32_t child_cnt = lv_obj_get_child_count(obj); + for(i = child_cnt - 1; i >= 0; i--) { + lv_obj_t * child = obj->spec_attr->children[i]; + found_p = lv_refr_get_top_obj(area_p, child); + + /*If a children is ok then break*/ + if(found_p != NULL) { + break; + } + } + + /*If no better children use this object*/ + if(found_p == NULL && info.res == LV_COVER_RES_COVER) { + found_p = obj; + } + + return found_p; +} + + /********************** * STATIC FUNCTIONS **********************/ @@ -902,48 +944,6 @@ static void refr_configured_layer(lv_layer_t * layer) LV_PROFILER_REFR_END; } -/** - * Search the most top object which fully covers an area - * @param area_p pointer to an area - * @param obj the first object to start the searching (typically a screen) - * @return - */ -static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) -{ - lv_obj_t * found_p = NULL; - - if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; - if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return NULL; - if(lv_obj_get_layer_type(obj) != LV_LAYER_TYPE_NONE) return NULL; - if(lv_obj_get_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) return NULL; - - /*If this object is fully cover the draw area then check the children too*/ - lv_cover_check_info_t info; - info.res = LV_COVER_RES_COVER; - info.area = area_p; - lv_obj_send_event(obj, LV_EVENT_COVER_CHECK, &info); - if(info.res == LV_COVER_RES_MASKED) return NULL; - - int32_t i; - int32_t child_cnt = lv_obj_get_child_count(obj); - for(i = child_cnt - 1; i >= 0; i--) { - lv_obj_t * child = obj->spec_attr->children[i]; - found_p = lv_refr_get_top_obj(area_p, child); - - /*If a children is ok then break*/ - if(found_p != NULL) { - break; - } - } - - /*If no better children use this object*/ - if(found_p == NULL && info.res == LV_COVER_RES_COVER) { - found_p = obj; - } - - return found_p; -} - /** * Make the refreshing from an object. Draw all its children and the youngers too. * @param top_p pointer to an objects. Start the drawing from it. diff --git a/src/core/lv_refr_private.h b/src/core/lv_refr_private.h index 3b2985b70e..bb5659e8d0 100644 --- a/src/core/lv_refr_private.h +++ b/src/core/lv_refr_private.h @@ -58,6 +58,14 @@ lv_display_t * lv_refr_get_disp_refreshing(void); */ void lv_refr_set_disp_refreshing(lv_display_t * disp); +/** + * Search the most top object which fully covers an area + * @param area_p pointer to an area + * @param obj the first object to start the searching (typically a screen) + * @return + */ +lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); + /********************** * MACROS **********************/ diff --git a/src/others/snapshot/lv_snapshot.c b/src/others/snapshot/lv_snapshot.c index 376d3b2af2..2c4d850213 100644 --- a/src/others/snapshot/lv_snapshot.c +++ b/src/others/snapshot/lv_snapshot.c @@ -98,9 +98,6 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l res = lv_snapshot_reshape_draw_buf(obj, draw_buf); if(res != LV_RESULT_OK) return res; - /* clear draw buffer*/ - lv_draw_buf_clear(draw_buf, NULL); - lv_area_t snapshot_area; int32_t w = draw_buf->header.w; int32_t h = draw_buf->header.h; @@ -108,6 +105,13 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l lv_obj_get_coords(obj, &snapshot_area); lv_area_increase(&snapshot_area, ext_size, ext_size); + lv_obj_t * top_obj = lv_refr_get_top_obj(&snapshot_area, obj); + if(top_obj == NULL) { + /* Clear draw buffer when no top object*/ + lv_draw_buf_clear(draw_buf, NULL); + top_obj = obj; + } + lv_layer_t layer; lv_layer_init(&layer); @@ -126,7 +130,7 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l disp_new->layer_head = &layer; lv_refr_set_disp_refreshing(disp_new); - lv_obj_redraw(&layer, obj); + lv_obj_redraw(&layer, top_obj); while(layer.draw_task_head) { lv_draw_dispatch_wait_for_request();