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_sdl_polygon.c (4142B)

      1 /**
      2  * @file lv_draw_sdl_polygon.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 #include "../../lv_conf_internal.h"
     10 
     11 #if LV_USE_GPU_SDL
     12 
     13 #include "lv_draw_sdl.h"
     14 #include "lv_draw_sdl_utils.h"
     15 #include "lv_draw_sdl_texture_cache.h"
     16 #include "lv_draw_sdl_composite.h"
     17 
     18 /*********************
     19  *      DEFINES
     20  *********************/
     21 
     22 /**********************
     23  *      TYPEDEFS
     24  **********************/
     25 
     26 /**********************
     27  *  STATIC PROTOTYPES
     28  **********************/
     29 
     30 /**********************
     31  *  STATIC VARIABLES
     32  **********************/
     33 
     34 /**********************
     35  *      MACROS
     36  **********************/
     37 
     38 static void dump_masks(SDL_Texture * texture, const lv_area_t * coords);
     39 
     40 /**********************
     41  *   GLOBAL FUNCTIONS
     42  **********************/
     43 void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * draw_dsc, const lv_point_t * points,
     44                          uint16_t point_cnt)
     45 {
     46     if(point_cnt < 3) return;
     47     if(points == NULL) return;
     48 
     49     lv_draw_mask_polygon_param_t polygon_param;
     50     lv_draw_mask_polygon_init(&polygon_param, points, point_cnt);
     51 
     52     if(polygon_param.cfg.point_cnt < 3) {
     53         lv_draw_mask_free_param(&polygon_param);
     54         return;
     55     }
     56 
     57     lv_area_t poly_coords = {.x1 = LV_COORD_MAX, .y1 = LV_COORD_MAX, .x2 = LV_COORD_MIN, .y2 = LV_COORD_MIN};
     58 
     59     uint16_t i;
     60     for(i = 0; i < point_cnt; i++) {
     61         poly_coords.x1 = LV_MIN(poly_coords.x1, polygon_param.cfg.points[i].x);
     62         poly_coords.y1 = LV_MIN(poly_coords.y1, polygon_param.cfg.points[i].y);
     63         poly_coords.x2 = LV_MAX(poly_coords.x2, polygon_param.cfg.points[i].x);
     64         poly_coords.y2 = LV_MAX(poly_coords.y2, polygon_param.cfg.points[i].y);
     65     }
     66 
     67     bool is_common;
     68     lv_area_t draw_area;
     69     is_common = _lv_area_intersect(&draw_area, &poly_coords, draw_ctx->clip_area);
     70     if(!is_common) {
     71         lv_draw_mask_free_param(&polygon_param);
     72         return;
     73     }
     74 
     75     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
     76 
     77     int16_t mask_id = lv_draw_mask_add(&polygon_param, NULL);
     78 
     79     lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
     80     SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
     81     SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
     82     dump_masks(texture, &draw_area);
     83 
     84     lv_draw_mask_remove_id(mask_id);
     85     lv_draw_mask_free_param(&polygon_param);
     86 
     87     SDL_Rect srcrect = {0, 0, w, h}, dstrect;
     88     lv_area_to_sdl_rect(&draw_area, &dstrect);
     89     SDL_Color color;
     90     lv_color_to_sdl_color(&draw_dsc->bg_color, &color);
     91     SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
     92     SDL_SetTextureAlphaMod(texture, draw_dsc->bg_opa);
     93     SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
     94 }
     95 
     96 /**********************
     97  *   STATIC FUNCTIONS
     98  **********************/
     99 
    100 static void dump_masks(SDL_Texture * texture, const lv_area_t * coords)
    101 {
    102     lv_coord_t w = lv_area_get_width(coords), h = lv_area_get_height(coords);
    103     SDL_assert(w > 0 && h > 0);
    104     SDL_Rect rect = {0, 0, w, h};
    105     uint8_t * pixels;
    106     int pitch;
    107     if(SDL_LockTexture(texture, &rect, (void **) &pixels, &pitch) != 0) return;
    108 
    109     lv_opa_t * line_buf = lv_mem_buf_get(rect.w);
    110     for(lv_coord_t y = 0; y < rect.h; y++) {
    111         lv_memset_ff(line_buf, rect.w);
    112         lv_coord_t abs_x = (lv_coord_t) coords->x1, abs_y = (lv_coord_t)(y + coords->y1), len = (lv_coord_t) rect.w;
    113         lv_draw_mask_res_t res;
    114         res = lv_draw_mask_apply(line_buf, abs_x, abs_y, len);
    115         if(res == LV_DRAW_MASK_RES_TRANSP) {
    116             lv_memset_00(&pixels[y * pitch], 4 * rect.w);
    117         }
    118         else if(res == LV_DRAW_MASK_RES_FULL_COVER) {
    119             lv_memset_ff(&pixels[y * pitch], 4 * rect.w);
    120         }
    121         else {
    122             for(int x = 0; x < rect.w; x++) {
    123                 uint8_t * pixel = &pixels[y * pitch + x * 4];
    124                 *pixel = line_buf[x];
    125                 pixel[1] = pixel[2] = pixel[3] = 0xFF;
    126             }
    127         }
    128     }
    129     lv_mem_buf_release(line_buf);
    130     SDL_UnlockTexture(texture);
    131 }
    132 
    133 #endif /*LV_USE_GPU_SDL*/