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_snapshot.c (5458B)
1 /** 2 * @file lv_snapshot.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_snapshot.h" 10 #if LV_USE_SNAPSHOT 11 12 #include <stdbool.h> 13 #include "../../../core/lv_disp.h" 14 #include "../../../core/lv_refr.h" 15 /********************* 16 * DEFINES 17 *********************/ 18 19 /********************** 20 * TYPEDEFS 21 **********************/ 22 23 /********************** 24 * STATIC PROTOTYPES 25 **********************/ 26 27 /********************** 28 * STATIC VARIABLES 29 **********************/ 30 31 /********************** 32 * MACROS 33 **********************/ 34 35 /********************** 36 * GLOBAL FUNCTIONS 37 **********************/ 38 39 /** Get the buffer needed for object snapshot image. 40 * 41 * @param obj The object to generate snapshot. 42 * @param cf color format for generated image. 43 * 44 * @return the buffer size needed in bytes 45 */ 46 uint32_t lv_snapshot_buf_size_needed(lv_obj_t * obj, lv_img_cf_t cf) 47 { 48 switch(cf) { 49 case LV_IMG_CF_TRUE_COLOR_ALPHA: 50 case LV_IMG_CF_ALPHA_1BIT: 51 case LV_IMG_CF_ALPHA_2BIT: 52 case LV_IMG_CF_ALPHA_4BIT: 53 case LV_IMG_CF_ALPHA_8BIT: 54 break; 55 default: 56 return 0; 57 } 58 59 lv_obj_update_layout(obj); 60 61 /*Width and height determine snapshot image size.*/ 62 lv_coord_t w = lv_obj_get_width(obj); 63 lv_coord_t h = lv_obj_get_height(obj); 64 lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj); 65 w += ext_size * 2; 66 h += ext_size * 2; 67 68 uint8_t px_size = lv_img_cf_get_px_size(cf); 69 return w * h * ((px_size + 7) >> 3); 70 } 71 72 /** Take snapshot for object with its children, save image info to provided buffer. 73 * 74 * @param obj The object to generate snapshot. 75 * @param cf color format for generated image. 76 * @param dsc image descriptor to store the image result. 77 * @param buf the buffer to store image data. 78 * @param buff_size provided buffer size in bytes. 79 * 80 * @return LV_RES_OK on success, LV_RES_INV on error. 81 */ 82 lv_res_t lv_snapshot_take_to_buf(lv_obj_t * obj, lv_img_cf_t cf, lv_img_dsc_t * dsc, void * buf, uint32_t buff_size) 83 { 84 LV_ASSERT(dsc); 85 LV_ASSERT(buf); 86 87 switch(cf) { 88 case LV_IMG_CF_TRUE_COLOR_ALPHA: 89 case LV_IMG_CF_ALPHA_1BIT: 90 case LV_IMG_CF_ALPHA_2BIT: 91 case LV_IMG_CF_ALPHA_4BIT: 92 case LV_IMG_CF_ALPHA_8BIT: 93 break; 94 default: 95 return LV_RES_INV; 96 } 97 98 if(lv_snapshot_buf_size_needed(obj, cf) > buff_size) 99 return LV_RES_INV; 100 101 /*Width and height determine snapshot image size.*/ 102 lv_coord_t w = lv_obj_get_width(obj); 103 lv_coord_t h = lv_obj_get_height(obj); 104 lv_coord_t ext_size = _lv_obj_get_ext_draw_size(obj); 105 w += ext_size * 2; 106 h += ext_size * 2; 107 108 lv_area_t snapshot_area; 109 lv_obj_get_coords(obj, &snapshot_area); 110 lv_area_increase(&snapshot_area, ext_size, ext_size); 111 112 lv_memset(buf, 0x00, buff_size); 113 lv_memset_00(dsc, sizeof(lv_img_dsc_t)); 114 115 lv_disp_t * obj_disp = lv_obj_get_disp(obj); 116 lv_disp_drv_t driver; 117 lv_disp_drv_init(&driver); 118 /*In lack of a better idea use the resolution of the object's display*/ 119 driver.hor_res = lv_disp_get_hor_res(obj_disp); 120 driver.ver_res = lv_disp_get_hor_res(obj_disp); 121 lv_disp_drv_use_generic_set_px_cb(&driver, cf); 122 123 lv_disp_t fake_disp; 124 lv_memset_00(&fake_disp, sizeof(lv_disp_t)); 125 fake_disp.driver = &driver; 126 127 128 lv_draw_ctx_t * draw_ctx = lv_mem_alloc(obj_disp->driver->draw_ctx_size); 129 LV_ASSERT_MALLOC(draw_ctx); 130 if(draw_ctx == NULL) return LV_RES_INV; 131 obj_disp->driver->draw_ctx_init(fake_disp.driver, draw_ctx); 132 fake_disp.driver->draw_ctx = draw_ctx; 133 draw_ctx->clip_area = &snapshot_area; 134 draw_ctx->buf_area = &snapshot_area; 135 draw_ctx->buf = (void *)buf; 136 driver.draw_ctx = draw_ctx; 137 138 lv_disp_t * refr_ori = _lv_refr_get_disp_refreshing(); 139 _lv_refr_set_disp_refreshing(&fake_disp); 140 141 lv_refr_obj(draw_ctx, obj); 142 143 _lv_refr_set_disp_refreshing(refr_ori); 144 obj_disp->driver->draw_ctx_deinit(fake_disp.driver, draw_ctx); 145 lv_mem_free(draw_ctx); 146 147 dsc->data = buf; 148 dsc->header.w = w; 149 dsc->header.h = h; 150 dsc->header.cf = cf; 151 return LV_RES_OK; 152 } 153 154 /** Take snapshot for object with its children, alloc the memory needed. 155 * 156 * @param obj The object to generate snapshot. 157 * @param cf color format for generated image. 158 * 159 * @return a pointer to an image descriptor, or NULL if failed. 160 */ 161 lv_img_dsc_t * lv_snapshot_take(lv_obj_t * obj, lv_img_cf_t cf) 162 { 163 uint32_t buff_size = lv_snapshot_buf_size_needed(obj, cf); 164 165 void * buf = lv_mem_alloc(buff_size); 166 if(buf == NULL) { 167 return NULL; 168 } 169 170 lv_img_dsc_t * dsc = lv_mem_alloc(sizeof(lv_img_dsc_t)); 171 if(dsc == NULL) { 172 lv_mem_free(buf); 173 return NULL; 174 } 175 176 if(lv_snapshot_take_to_buf(obj, cf, dsc, buf, buff_size) == LV_RES_INV) { 177 lv_mem_free(buf); 178 lv_mem_free(dsc); 179 return NULL; 180 } 181 182 return dsc; 183 } 184 185 /** Free the snapshot image returned by @ref lv_snapshot_take 186 * 187 * It will firstly free the data image takes, then the image descriptor. 188 * 189 * @param dsc The image descriptor generated by lv_snapshot_take. 190 * 191 */ 192 void lv_snapshot_free(lv_img_dsc_t * dsc) 193 { 194 if(!dsc) 195 return; 196 197 if(dsc->data) 198 lv_mem_free((void *)dsc->data); 199 200 lv_mem_free(dsc); 201 } 202 203 /********************** 204 * STATIC FUNCTIONS 205 **********************/ 206 207 #endif /*LV_USE_SNAPSHOT*/