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