1 /**
2  * @file lv_draw_sdl_utils.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_utils.h"
14 
15 #include "../lv_draw.h"
16 #include "../lv_draw_label.h"
17 #include "../../core/lv_refr.h"
18 
19 /*********************
20  *      DEFINES
21  *********************/
22 
23 /**********************
24  *      TYPEDEFS
25  **********************/
26 
27 /**********************
28  *  STATIC PROTOTYPES
29  **********************/
30 /**********************
31  *  STATIC VARIABLES
32  **********************/
33 extern const uint8_t _lv_bpp1_opa_table[2];
34 extern const uint8_t _lv_bpp2_opa_table[4];
35 extern const uint8_t _lv_bpp4_opa_table[16];
36 extern const uint8_t _lv_bpp8_opa_table[256];
37 
38 static int utils_init_count = 0;
39 static SDL_Palette * lv_sdl_palette_grayscale8 = NULL;
40 
41 /**********************
42  *      MACROS
43  **********************/
44 
45 /**********************
46  *   GLOBAL FUNCTIONS
47  **********************/
48 
_lv_draw_sdl_utils_init()49 void _lv_draw_sdl_utils_init()
50 {
51     utils_init_count++;
52     if(utils_init_count > 1) {
53         return;
54     }
55     lv_sdl_palette_grayscale8 = lv_sdl_alloc_palette_for_bpp(_lv_bpp8_opa_table, 8);
56 }
57 
_lv_draw_sdl_utils_deinit()58 void _lv_draw_sdl_utils_deinit()
59 {
60     if(utils_init_count == 0) {
61         return;
62     }
63     utils_init_count--;
64     if(utils_init_count == 0) {
65         SDL_FreePalette(lv_sdl_palette_grayscale8);
66         lv_sdl_palette_grayscale8 = NULL;
67     }
68 }
69 
lv_area_to_sdl_rect(const lv_area_t * in,SDL_Rect * out)70 void lv_area_to_sdl_rect(const lv_area_t * in, SDL_Rect * out)
71 {
72     out->x = in->x1;
73     out->y = in->y1;
74     out->w = in->x2 - in->x1 + 1;
75     out->h = in->y2 - in->y1 + 1;
76 }
77 
lv_color_to_sdl_color(const lv_color_t * in,SDL_Color * out)78 void lv_color_to_sdl_color(const lv_color_t * in, SDL_Color * out)
79 {
80 #if LV_COLOR_DEPTH == 32
81     out->a = in->ch.alpha;
82     out->r = in->ch.red;
83     out->g = in->ch.green;
84     out->b = in->ch.blue;
85 #else
86     uint32_t color32 = lv_color_to32(*in);
87     lv_color32_t * color32_t = (lv_color32_t *) &color32;
88     out->a = color32_t->ch.alpha;
89     out->r = color32_t->ch.red;
90     out->g = color32_t->ch.green;
91     out->b = color32_t->ch.blue;
92 #endif
93 }
94 
lv_area_zoom_to_sdl_rect(const lv_area_t * in,SDL_Rect * out,uint16_t zoom,const lv_point_t * pivot)95 void lv_area_zoom_to_sdl_rect(const lv_area_t * in, SDL_Rect * out, uint16_t zoom, const lv_point_t * pivot)
96 {
97     if(zoom == LV_IMG_ZOOM_NONE) {
98         lv_area_to_sdl_rect(in, out);
99         return;
100     }
101     lv_area_t tmp;
102     _lv_img_buf_get_transformed_area(&tmp, lv_area_get_width(in), lv_area_get_height(in), 0, zoom, pivot);
103     lv_area_move(&tmp, in->x1, in->y1);
104     lv_area_to_sdl_rect(&tmp, out);
105 }
106 
lv_sdl_alloc_palette_for_bpp(const uint8_t * mapping,uint8_t bpp)107 SDL_Palette * lv_sdl_alloc_palette_for_bpp(const uint8_t * mapping, uint8_t bpp)
108 {
109     SDL_assert(bpp >= 1 && bpp <= 8);
110     int color_cnt = 1 << bpp;
111     SDL_Palette * result = SDL_AllocPalette(color_cnt);
112     SDL_Color palette[256];
113     for(int i = 0; i < color_cnt; i++) {
114         palette[i].r = palette[i].g = palette[i].b = 0xFF;
115         palette[i].a = mapping ? mapping[i] : i;
116     }
117     SDL_SetPaletteColors(result, palette, 0, color_cnt);
118     return result;
119 }
120 
lv_sdl_create_opa_surface(lv_opa_t * opa,lv_coord_t width,lv_coord_t height,lv_coord_t stride)121 SDL_Surface * lv_sdl_create_opa_surface(lv_opa_t * opa, lv_coord_t width, lv_coord_t height, lv_coord_t stride)
122 {
123     SDL_Surface * indexed = SDL_CreateRGBSurfaceFrom(opa, width, height, 8, stride, 0, 0, 0, 0);
124     SDL_SetSurfacePalette(indexed, lv_sdl_palette_grayscale8);
125     SDL_Surface * converted = SDL_ConvertSurfaceFormat(indexed, LV_DRAW_SDL_TEXTURE_FORMAT, 0);
126     SDL_FreeSurface(indexed);
127     return converted;
128 }
129 
lv_sdl_create_opa_texture(SDL_Renderer * renderer,lv_opa_t * pixels,lv_coord_t width,lv_coord_t height,lv_coord_t stride)130 SDL_Texture * lv_sdl_create_opa_texture(SDL_Renderer * renderer, lv_opa_t * pixels, lv_coord_t width,
131                                         lv_coord_t height, lv_coord_t stride)
132 {
133     SDL_Surface * indexed = lv_sdl_create_opa_surface(pixels, width, height, stride);
134     SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, indexed);
135     SDL_FreeSurface(indexed);
136     return texture;
137 }
138 
lv_sdl_to_8bpp(uint8_t * dest,const uint8_t * src,int width,int height,int stride,uint8_t bpp)139 void lv_sdl_to_8bpp(uint8_t * dest, const uint8_t * src, int width, int height, int stride, uint8_t bpp)
140 {
141     int src_len = width * height;
142     int cur = 0;
143     int curbit;
144     uint8_t opa_mask;
145     const uint8_t * opa_table;
146     switch(bpp) {
147         case 1:
148             opa_mask = 0x1;
149             opa_table = _lv_bpp1_opa_table;
150             break;
151         case 2:
152             opa_mask = 0x4;
153             opa_table = _lv_bpp2_opa_table;
154             break;
155         case 4:
156             opa_mask = 0xF;
157             opa_table = _lv_bpp4_opa_table;
158             break;
159         case 8:
160             opa_mask = 0xFF;
161             opa_table = _lv_bpp8_opa_table;
162             break;
163         default:
164             return;
165     }
166     /* Does this work well on big endian systems? */
167     while(cur < src_len) {
168         curbit = 8 - bpp;
169         uint8_t src_byte = src[cur * bpp / 8];
170         while(curbit >= 0 && cur < src_len) {
171             uint8_t src_bits = opa_mask & (src_byte >> curbit);
172             dest[(cur / width * stride) + (cur % width)] = opa_table[src_bits];
173             curbit -= bpp;
174             cur++;
175         }
176     }
177 }
178 
179 /**********************
180  *   STATIC FUNCTIONS
181  **********************/
182 
183 #endif /*LV_USE_GPU_SDL*/
184