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