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*/