Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/libs/lvgl/lv_draw/lv_draw_rbasic.c
1476 views
1
/**
2
* @file lv_draw_rbasic.c
3
*
4
*/
5
6
/*********************
7
* INCLUDES
8
*********************/
9
#include "lv_draw_rbasic.h"
10
#if USE_LV_REAL_DRAW != 0
11
12
#include "../lv_hal/lv_hal_disp.h"
13
#include "../lv_misc/lv_font.h"
14
#include "lv_draw.h"
15
16
/*********************
17
* DEFINES
18
*********************/
19
20
/**********************
21
* TYPEDEFS
22
**********************/
23
24
/**********************
25
* STATIC PROTOTYPES
26
**********************/
27
28
/**********************
29
* STATIC VARIABLES
30
**********************/
31
static lv_color_t letter_bg_color;
32
33
/**********************
34
* MACROS
35
**********************/
36
37
/**********************
38
* GLOBAL FUNCTIONS
39
**********************/
40
41
/**
42
* Put a pixel to the display
43
* @param x x coordinate of the pixel
44
* @param y y coordinate of the pixel
45
* @param mask_p the pixel will be drawn on this area
46
* @param color color of the pixel
47
* @param opa opacity (ignored, only for compatibility with lv_vpx)
48
*/
49
void lv_rpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
50
{
51
(void)opa; /*Opa is used only for compatibility with lv_vpx*/
52
53
lv_area_t area;
54
area.x1 = x;
55
area.y1 = y;
56
area.x2 = x;
57
area.y2 = y;
58
59
lv_rfill(&area, mask_p, color, LV_OPA_COVER);
60
}
61
62
/**
63
* Fill an area on the display
64
* @param cords_p coordinates of the area to fill
65
* @param mask_p fill only o this mask
66
* @param color fill color
67
* @param opa opacity (ignored, only for compatibility with lv_vfill)
68
*/
69
void lv_rfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
70
lv_color_t color, lv_opa_t opa)
71
{
72
73
(void)opa; /*Opa is used only for compatibility with lv_vfill*/
74
75
lv_area_t masked_area;
76
bool union_ok = true;
77
78
if(mask_p != NULL) {
79
union_ok = lv_area_intersect(&masked_area, cords_p, mask_p);
80
} else {
81
lv_area_t scr_area;
82
lv_area_set(&scr_area, 0, 0, LV_HOR_RES - 1, LV_VER_RES - 1);
83
union_ok = lv_area_intersect(&masked_area, cords_p, &scr_area);
84
}
85
86
if(union_ok != false) {
87
lv_disp_fill(masked_area.x1, masked_area.y1, masked_area.x2, masked_area.y2, color);
88
}
89
}
90
91
/**
92
* Draw a letter to the display
93
* @param pos_p left-top coordinate of the latter
94
* @param mask_p the letter will be drawn only on this area
95
* @param font_p pointer to font
96
* @param letter a letter to draw
97
* @param color color of letter
98
* @param opa opacity of letter (ignored, only for compatibility with lv_vletter)
99
*/
100
void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
101
const lv_font_t * font_p, uint32_t letter,
102
lv_color_t color, lv_opa_t opa)
103
{
104
(void)opa; /*Opa is used only for compatibility with lv_vletter*/
105
106
static uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
107
static uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
108
static uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
109
68, 85, 102, 119,
110
136, 153, 170, 187,
111
204, 221, 238, 255
112
};
113
114
if(font_p == NULL) return;
115
116
uint8_t letter_w = lv_font_get_width(font_p, letter);
117
uint8_t letter_h = lv_font_get_height(font_p);
118
uint8_t bpp = lv_font_get_bpp(font_p, letter); /*Bit per pixel (1,2, 4 or 8)*/
119
uint8_t * bpp_opa_table;
120
uint8_t mask_init;
121
uint8_t mask;
122
123
switch(bpp) {
124
case 1:
125
bpp_opa_table = bpp1_opa_table;
126
mask_init = 0x80;
127
break;
128
case 2:
129
bpp_opa_table = bpp2_opa_table;
130
mask_init = 0xC0;
131
break;
132
case 4:
133
bpp_opa_table = bpp4_opa_table;
134
mask_init = 0xF0;
135
break;
136
case 8:
137
bpp_opa_table = NULL;
138
mask_init = 0xFF;
139
break; /*No opa table, pixel value will be used directly*/
140
default:
141
return; /*Invalid bpp. Can't render the letter*/
142
}
143
144
const uint8_t * map_p = lv_font_get_bitmap(font_p, letter);
145
146
if(map_p == NULL) return;
147
148
/*If the letter is completely out of mask don't draw it */
149
if(pos_p->x + letter_w < mask_p->x1 || pos_p->x > mask_p->x2 ||
150
pos_p->y + letter_h < mask_p->y1 || pos_p->y > mask_p->y2) return;
151
152
lv_coord_t col, row;
153
uint8_t col_bit;
154
uint8_t col_byte_cnt;
155
uint8_t width_byte_scr = letter_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
156
if(letter_w & 0x7) width_byte_scr++;
157
uint8_t width_byte_bpp = (letter_w * bpp) >> 3; /*Letter width in byte. Real width in the font*/
158
if((letter_w * bpp) & 0x7) width_byte_bpp++;
159
160
/* Calculate the col/row start/end on the map*/
161
lv_coord_t col_start = pos_p->x >= mask_p->x1 ? 0 : mask_p->x1 - pos_p->x;
162
lv_coord_t col_end = pos_p->x + letter_w <= mask_p->x2 ? letter_w : mask_p->x2 - pos_p->x + 1;
163
lv_coord_t row_start = pos_p->y >= mask_p->y1 ? 0 : mask_p->y1 - pos_p->y;
164
lv_coord_t row_end = pos_p->y + letter_h <= mask_p->y2 ? letter_h : mask_p->y2 - pos_p->y + 1;
165
166
/*Move on the map too*/
167
map_p += (row_start * width_byte_bpp) + ((col_start * bpp) >> 3);
168
169
uint8_t letter_px;
170
for(row = row_start; row < row_end; row ++) {
171
col_byte_cnt = 0;
172
col_bit = (col_start * bpp) % 8;
173
mask = mask_init >> col_bit;
174
for(col = col_start; col < col_end; col ++) {
175
letter_px = (*map_p & mask) >> (8 - col_bit - bpp);
176
if(letter_px != 0) {
177
lv_rpx(pos_p->x + col, pos_p->y + row, mask_p, lv_color_mix(color, letter_bg_color, bpp == 8 ? letter_px : bpp_opa_table[letter_px]), LV_OPA_COVER);
178
}
179
180
if(col_bit < 8 - bpp) {
181
col_bit += bpp;
182
mask = mask >> bpp;
183
} else {
184
col_bit = 0;
185
col_byte_cnt ++;
186
mask = mask_init;
187
map_p ++;
188
}
189
}
190
191
map_p += (width_byte_bpp) - col_byte_cnt;
192
}
193
}
194
195
/**
196
* When the letter is ant-aliased it needs to know the background color
197
* @param bg_color the background color of the currently drawn letter
198
*/
199
void lv_rletter_set_background(lv_color_t color)
200
{
201
letter_bg_color = color;
202
}
203
204
/**
205
* Draw a color map to the display (image)
206
* @param cords_p coordinates the color map
207
* @param mask_p the map will drawn only on this area
208
* @param map_p pointer to a lv_color_t array
209
* @param opa opacity of the map (ignored, only for compatibility with 'lv_vmap')
210
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
211
* @param alpha_byte true: extra alpha byte is inserted for every pixel (not supported, only l'v_vmap' can draw it)
212
* @param recolor mix the pixels with this color
213
* @param recolor_opa the intense of recoloring
214
*/
215
void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
216
const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
217
lv_color_t recolor, lv_opa_t recolor_opa)
218
{
219
if(alpha_byte) return; /*Pixel level opacity i not supported in real map drawing*/
220
221
(void)opa; /*opa is used only for compatibility with lv_vmap*/
222
lv_area_t masked_a;
223
bool union_ok;
224
225
union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
226
227
/*If there are common part of the mask and map then draw the map*/
228
if(union_ok == false) return;
229
230
/*Go to the first pixel*/
231
lv_coord_t map_width = lv_area_get_width(cords_p);
232
map_p += (masked_a.y1 - cords_p->y1) * map_width * sizeof(lv_color_t);
233
map_p += (masked_a.x1 - cords_p->x1) * sizeof(lv_color_t);
234
235
lv_coord_t row;
236
if(recolor_opa == LV_OPA_TRANSP && chroma_key == false) {
237
lv_coord_t mask_w = lv_area_get_width(&masked_a) - 1;
238
for(row = masked_a.y1; row <= masked_a.y2; row++) {
239
lv_disp_map(masked_a.x1, row, masked_a.x1 + mask_w, row, (lv_color_t *)map_p);
240
map_p += map_width * sizeof(lv_color_t); /*Next row on the map*/
241
}
242
} else {
243
lv_color_t chroma_key_color = LV_COLOR_TRANSP;
244
lv_coord_t col;
245
for(row = masked_a.y1; row <= masked_a.y2; row++) {
246
for(col = masked_a.x1; col <= masked_a.x2; col++) {
247
lv_color_t * px_color = (lv_color_t *) &map_p[(uint32_t)(col - masked_a.x1) * sizeof(lv_color_t)];
248
249
if(chroma_key && chroma_key_color.full == px_color->full) continue;
250
251
if(recolor_opa != LV_OPA_TRANSP) {
252
lv_color_t recolored_px = lv_color_mix(recolor, *px_color, recolor_opa);
253
254
lv_rpx(col, row, mask_p, recolored_px, LV_OPA_COVER);
255
} else {
256
lv_rpx(col, row, mask_p, *px_color, LV_OPA_COVER);
257
}
258
259
}
260
map_p += map_width * sizeof(lv_color_t); /*Next row on the map*/
261
}
262
}
263
}
264
265
/**********************
266
* STATIC FUNCTIONS
267
**********************/
268
269
#endif /*USE_LV_REAL_DRAW*/
270
271