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_label.c (5602B)
1 /** 2 * @file lv_draw_sdl_label.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 10 #include "../../lv_conf_internal.h" 11 12 #if LV_USE_GPU_SDL 13 14 #include LV_GPU_SDL_INCLUDE_PATH 15 16 #include "../lv_draw_label.h" 17 #include "../../misc/lv_utils.h" 18 19 #include "lv_draw_sdl_utils.h" 20 #include "lv_draw_sdl_texture_cache.h" 21 #include "lv_draw_sdl_composite.h" 22 23 /********************* 24 * DEFINES 25 *********************/ 26 27 /********************** 28 * TYPEDEFS 29 **********************/ 30 31 typedef struct { 32 lv_sdl_cache_key_magic_t magic; 33 const lv_font_t * font_p; 34 uint32_t letter; 35 } lv_font_glyph_key_t; 36 37 /********************** 38 * STATIC PROTOTYPES 39 **********************/ 40 41 static lv_font_glyph_key_t font_key_glyph_create(const lv_font_t * font_p, uint32_t letter); 42 43 44 /********************** 45 * STATIC VARIABLES 46 **********************/ 47 48 /********************** 49 * MACROS 50 **********************/ 51 52 /********************** 53 * GLOBAL FUNCTIONS 54 **********************/ 55 56 void lv_draw_sdl_draw_letter(lv_draw_ctx_t * draw_ctx, const lv_draw_label_dsc_t * dsc, const lv_point_t * pos_p, 57 uint32_t letter) 58 { 59 const lv_area_t * clip_area = draw_ctx->clip_area; 60 const lv_font_t * font_p = dsc->font; 61 lv_opa_t opa = dsc->opa; 62 lv_color_t color = dsc->color; 63 if(opa < LV_OPA_MIN) return; 64 if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; 65 66 if(font_p == NULL) { 67 LV_LOG_WARN("lv_draw_letter: font is NULL"); 68 return; 69 } 70 71 lv_font_glyph_dsc_t g; 72 bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0'); 73 if(g_ret == false) { 74 /*Add warning if the dsc is not found 75 *but do not print warning for non printable ASCII chars (e.g. '\n')*/ 76 if(letter >= 0x20 && 77 letter != 0xf8ff && /*LV_SYMBOL_DUMMY*/ 78 letter != 0x200c) { /*ZERO WIDTH NON-JOINER*/ 79 LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%X", letter); 80 81 /* draw placeholder */ 82 lv_area_t glyph_coords; 83 lv_draw_rect_dsc_t glyph_dsc; 84 lv_coord_t begin_x = pos_p->x + g.ofs_x; 85 lv_coord_t begin_y = pos_p->y + g.ofs_y; 86 lv_area_set(&glyph_coords, begin_x, begin_y, begin_x + g.box_w, begin_y + g.box_h); 87 lv_draw_rect_dsc_init(&glyph_dsc); 88 glyph_dsc.bg_opa = LV_OPA_MIN; 89 glyph_dsc.outline_opa = LV_OPA_MIN; 90 glyph_dsc.shadow_opa = LV_OPA_MIN; 91 glyph_dsc.bg_img_opa = LV_OPA_MIN; 92 glyph_dsc.border_color = dsc->color; 93 glyph_dsc.border_width = 1; 94 draw_ctx->draw_rect(draw_ctx, &glyph_dsc, &glyph_coords); 95 } 96 return; 97 } 98 99 /*Don't draw anything if the character is empty. E.g. space*/ 100 if((g.box_h == 0) || (g.box_w == 0)) return; 101 102 int32_t pos_x = pos_p->x + g.ofs_x; 103 int32_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y; 104 105 const lv_area_t letter_area = {pos_x, pos_y, pos_x + g.box_w - 1, pos_y + g.box_h - 1}; 106 lv_area_t draw_area; 107 108 /*If the letter is completely out of mask don't draw it*/ 109 if(!_lv_area_intersect(&draw_area, &letter_area, clip_area)) { 110 return; 111 } 112 113 lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx; 114 SDL_Renderer * renderer = ctx->renderer; 115 116 lv_font_glyph_key_t glyph_key = font_key_glyph_create(font_p, letter); 117 bool glyph_found = false; 118 SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &glyph_key, sizeof(glyph_key), &glyph_found); 119 if(!glyph_found) { 120 if(g.resolved_font) { 121 font_p = g.resolved_font; 122 } 123 const uint8_t * bmp = lv_font_get_glyph_bitmap(font_p, letter); 124 uint8_t * buf = lv_mem_alloc(g.box_w * g.box_h); 125 lv_sdl_to_8bpp(buf, bmp, g.box_w, g.box_h, g.box_w, g.bpp); 126 SDL_Surface * mask = lv_sdl_create_opa_surface(buf, g.box_w, g.box_h, g.box_w); 127 texture = SDL_CreateTextureFromSurface(renderer, mask); 128 SDL_FreeSurface(mask); 129 lv_mem_free(buf); 130 lv_draw_sdl_texture_cache_put(ctx, &glyph_key, sizeof(glyph_key), texture); 131 } 132 if(!texture) { 133 return; 134 } 135 136 lv_area_t t_letter = letter_area, t_clip = *clip_area, apply_area; 137 bool has_mask = lv_draw_sdl_composite_begin(ctx, &letter_area, clip_area, NULL, dsc->blend_mode, &t_letter, &t_clip, 138 &apply_area); 139 140 /*If the letter is completely out of mask don't draw it*/ 141 if(!_lv_area_intersect(&draw_area, &t_letter, &t_clip)) { 142 return; 143 } 144 SDL_Rect srcrect, dstrect; 145 lv_area_to_sdl_rect(&draw_area, &dstrect); 146 srcrect.x = draw_area.x1 - t_letter.x1; 147 srcrect.y = draw_area.y1 - t_letter.y1; 148 srcrect.w = dstrect.w; 149 srcrect.h = dstrect.h; 150 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); 151 SDL_SetTextureAlphaMod(texture, opa); 152 SDL_SetTextureColorMod(texture, color.ch.red, color.ch.green, color.ch.blue); 153 SDL_RenderCopy(renderer, texture, &srcrect, &dstrect); 154 155 lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode); 156 } 157 158 /********************** 159 * STATIC FUNCTIONS 160 **********************/ 161 162 static lv_font_glyph_key_t font_key_glyph_create(const lv_font_t * font_p, uint32_t letter) 163 { 164 lv_font_glyph_key_t key; 165 /* VERY IMPORTANT! Padding between members is uninitialized, so we have to wipe them manually */ 166 SDL_memset(&key, 0, sizeof(key)); 167 key.magic = LV_GPU_CACHE_KEY_MAGIC_FONT_GLYPH; 168 key.font_p = font_p; 169 key.letter = letter; 170 return key; 171 } 172 173 #endif /*LV_USE_GPU_SDL*/