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_line.c (5660B)
1 /** 2 * @file lv_draw_sdl_line.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 #include "lv_draw_sdl_mask.h" 18 19 /********************* 20 * DEFINES 21 *********************/ 22 #define ROUND_START 0x01 23 #define ROUND_END 0x02 24 /********************** 25 * TYPEDEFS 26 **********************/ 27 28 typedef struct { 29 lv_sdl_cache_key_magic_t magic; 30 lv_coord_t length; 31 lv_coord_t width; 32 uint8_t round; 33 } lv_draw_line_key_t; 34 35 /********************** 36 * STATIC PROTOTYPES 37 **********************/ 38 39 /********************** 40 * STATIC VARIABLES 41 **********************/ 42 43 /********************** 44 * MACROS 45 **********************/ 46 47 static lv_draw_line_key_t line_key_create(const lv_draw_line_dsc_t * dsc, lv_coord_t length); 48 49 static SDL_Texture * line_texture_create(lv_draw_sdl_ctx_t * sdl_ctx, const lv_draw_line_dsc_t * dsc, 50 lv_coord_t length); 51 52 /********************** 53 * GLOBAL FUNCTIONS 54 **********************/ 55 void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t * dsc, const lv_point_t * point1, 56 const lv_point_t * point2) 57 { 58 lv_draw_sdl_ctx_t * sdl_ctx = (lv_draw_sdl_ctx_t *) draw_ctx; 59 SDL_Renderer * renderer = sdl_ctx->renderer; 60 lv_coord_t x1 = point1->x, x2 = point2->x, y1 = point1->y, y2 = point2->y; 61 double length = SDL_sqrt(SDL_pow(x2 - x1, 2) + SDL_pow(y2 - y1, 2)); 62 if(length - (long) length > 0.5) { 63 length = (long) length + 1; 64 } 65 66 double angle = SDL_atan2(y2 - y1, x2 - x1) * 180 / M_PI; 67 lv_draw_line_key_t key = line_key_create(dsc, (lv_coord_t) length); 68 SDL_Texture * texture = lv_draw_sdl_texture_cache_get(sdl_ctx, &key, sizeof(key), NULL); 69 if(!texture) { 70 texture = line_texture_create(sdl_ctx, dsc, (lv_coord_t) length); 71 lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture); 72 } 73 74 lv_area_t coords = {x1, y1, x2, y2}; 75 const lv_area_t * clip = draw_ctx->clip_area; 76 77 SDL_Rect coords_r, clip_r; 78 lv_area_to_sdl_rect(&coords, &coords_r); 79 lv_area_to_sdl_rect(clip, &clip_r); 80 81 lv_area_t t_coords = coords, t_clip = *clip, apply_area; 82 lv_area_t extension = {dsc->width / 2, dsc->width / 2, dsc->width / 2, dsc->width / 2}; 83 lv_draw_sdl_composite_begin(sdl_ctx, &coords, clip, &extension, dsc->blend_mode, &t_coords, &t_clip, 84 &apply_area); 85 86 SDL_Color color; 87 lv_color_to_sdl_color(&dsc->color, &color); 88 89 SDL_SetTextureColorMod(texture, color.r, color.g, color.b); 90 SDL_SetTextureAlphaMod(texture, dsc->opa); 91 SDL_Rect srcrect = {0, 0, (int) length + dsc->width + 2, dsc->width + 2}, 92 dstrect = {t_coords.x1 - 1 - dsc->width / 2, t_coords.y1 - 1, srcrect.w, srcrect.h}; 93 SDL_Point center = {1 + dsc->width / 2, 1 + dsc->width / 2}; 94 95 SDL_Rect clip_rect; 96 lv_area_to_sdl_rect(&t_clip, &clip_rect); 97 if(!SDL_RectEquals(&clip_rect, &dstrect) || angle != 0) { 98 SDL_RenderSetClipRect(renderer, &clip_rect); 99 } 100 SDL_RenderCopyEx(renderer, texture, &srcrect, &dstrect, angle, ¢er, 0); 101 SDL_RenderSetClipRect(renderer, NULL); 102 103 lv_draw_sdl_composite_end(sdl_ctx, &apply_area, dsc->blend_mode); 104 } 105 106 /********************** 107 * STATIC FUNCTIONS 108 **********************/ 109 110 static lv_draw_line_key_t line_key_create(const lv_draw_line_dsc_t * dsc, lv_coord_t length) 111 { 112 lv_draw_line_key_t key; 113 lv_memset_00(&key, sizeof(lv_draw_line_key_t)); 114 key.magic = LV_GPU_CACHE_KEY_MAGIC_LINE; 115 key.length = length; 116 key.width = dsc->width; 117 key.round = (dsc->round_start ? ROUND_START : 0) | (dsc->round_end ? ROUND_END : 0); 118 return key; 119 } 120 121 static SDL_Texture * line_texture_create(lv_draw_sdl_ctx_t * sdl_ctx, const lv_draw_line_dsc_t * dsc, lv_coord_t length) 122 { 123 SDL_Texture * texture = SDL_CreateTexture(sdl_ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET, 124 length + dsc->width + 2, dsc->width + 2); 125 SDL_Texture * target = SDL_GetRenderTarget(sdl_ctx->renderer); 126 SDL_SetRenderTarget(sdl_ctx->renderer, texture); 127 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); 128 SDL_SetRenderDrawColor(sdl_ctx->renderer, 0xFF, 0xFF, 0xFF, 0x0); 129 SDL_RenderClear(sdl_ctx->renderer); 130 SDL_SetRenderDrawColor(sdl_ctx->renderer, 0xFF, 0xFF, 0xFF, 0xFF); 131 SDL_Rect line_rect = {1 + dsc->width / 2, 1, length, dsc->width}; 132 SDL_RenderFillRect(sdl_ctx->renderer, &line_rect); 133 if(dsc->round_start || dsc->round_end) { 134 lv_draw_mask_radius_param_t param; 135 lv_area_t round_area = {0, 0, dsc->width - 1, dsc->width - 1}; 136 lv_draw_mask_radius_init(¶m, &round_area, LV_RADIUS_CIRCLE, false); 137 138 int16_t mask_id = lv_draw_mask_add(¶m, NULL); 139 SDL_Texture * round_texture = lv_draw_sdl_mask_dump_texture(sdl_ctx->renderer, &round_area, &mask_id, 1); 140 lv_draw_mask_remove_id(mask_id); 141 142 SDL_Rect round_src = {0, 0, dsc->width, dsc->width}; 143 SDL_Rect round_dst = {line_rect.x - dsc->width / 2, 1, dsc->width, dsc->width}; 144 SDL_RenderCopy(sdl_ctx->renderer, round_texture, &round_src, &round_dst); 145 round_dst.x = line_rect.w + dsc->width / 2; 146 SDL_RenderCopy(sdl_ctx->renderer, round_texture, &round_src, &round_dst); 147 SDL_DestroyTexture(round_texture); 148 } 149 150 SDL_SetRenderTarget(sdl_ctx->renderer, target); 151 return texture; 152 } 153 154 #endif /*LV_USE_GPU_SDL*/