summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-16bit-common.c')
-rw-r--r--firmware/drivers/lcd-16bit-common.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index bbac2b295a..7b37bf7c30 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -229,7 +229,6 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig
229 lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height); 229 lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height);
230} 230}
231 231
232/* draw alpha bitmap for anti-alias font */
233#define ALPHA_COLOR_FONT_DEPTH 2 232#define ALPHA_COLOR_FONT_DEPTH 2
234#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) 233#define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
235#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) 234#define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
@@ -285,11 +284,17 @@ static inline unsigned blend_color(unsigned c, unsigned a)
285 return blend_two_colors(c, current_vp->fg_pattern, a); 284 return blend_two_colors(c, current_vp->fg_pattern, a);
286} 285}
287 286
288void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, 287/* Blend an image with an alpha channel
289 int src_y, int stride, int x, int y, 288 * if image is NULL, drawing will happen according to the drawmode
290 int width, int height) 289 * src is the alpha channel (4bit per pixel) */
290static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
291 const unsigned char *src, int src_x,
292 int src_y, int x, int y,
293 int width, int height,
294 int stride_image, int stride_src)
291{ 295{
292 fb_data *dst, *dst_row; 296 fb_data *dst, *dst_row;
297 const fb_data *image_row;
293 unsigned dmask = 0x00000000; 298 unsigned dmask = 0x00000000;
294 int drmode = current_vp->drawmode; 299 int drmode = current_vp->drawmode;
295 /* nothing to draw? */ 300 /* nothing to draw? */
@@ -356,13 +361,22 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
356 { 361 {
357 dmask = ~dmask; 362 dmask = ~dmask;
358 } 363 }
364 /* sourcing from an image ignore drawmode.
365 * Set to DRMODE_BG as we use its code path in the switch below */
366 if (image != NULL)
367 {
368 dmask = 0;
369 drmode = DRMODE_BG;
370 }
359 371
360 dst_row = LCDADDR(x, y); 372 dst_row = LCDADDR(x, y);
361 373
362 int col, row = height; 374 int col, row = height;
363 unsigned data, pixels; 375 unsigned data, pixels;
364 unsigned skip_end = (stride - width); 376 unsigned skip_end = (stride_src - width);
365 unsigned skip_start = src_y * stride + src_x; 377 unsigned skip_start = src_y * stride_src + src_x;
378 unsigned skip_start_image = STRIDE_MAIN(src_y * stride_image + src_x,
379 src_x * stride_image + src_y);
366 380
367#ifdef ALPHA_BITMAP_READ_WORDS 381#ifdef ALPHA_BITMAP_READ_WORDS
368 uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); 382 uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3);
@@ -379,6 +393,9 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
379#ifdef ALPHA_BITMAP_READ_WORDS 393#ifdef ALPHA_BITMAP_READ_WORDS
380 pixels = 8 - pixels; 394 pixels = 8 - pixels;
381#endif 395#endif
396 if (image)
397 image += skip_start_image;
398 image_row = image;
382 399
383 /* go through the rows and update each pixel */ 400 /* go through the rows and update each pixel */
384 do 401 do
@@ -386,6 +403,12 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
386 col = width; 403 col = width;
387 dst = dst_row; 404 dst = dst_row;
388 dst_row += ROW_INC; 405 dst_row += ROW_INC;
406 if (image_row) {
407 image = image_row;
408 image_row += STRIDE_MAIN(stride_image,1);
409 }
410 else
411 image = dst;
389#ifdef ALPHA_BITMAP_READ_WORDS 412#ifdef ALPHA_BITMAP_READ_WORDS
390#define UPDATE_SRC_ALPHA do { \ 413#define UPDATE_SRC_ALPHA do { \
391 if (--pixels) \ 414 if (--pixels) \
@@ -431,10 +454,11 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
431 uintptr_t bo = lcd_backdrop_offset; 454 uintptr_t bo = lcd_backdrop_offset;
432 do 455 do
433 { 456 {
434 *dst = blend_two_colors(*dst, *(fb_data *)((uintptr_t)dst + bo), 457 *dst = blend_two_colors(*(fb_data *)((uintptr_t)dst + bo),
435 data & ALPHA_COLOR_LOOKUP_SIZE ); 458 *image, data & ALPHA_COLOR_LOOKUP_SIZE );
436 459
437 dst += COL_INC; 460 dst += COL_INC;
461 image += STRIDE_MAIN(1, stride_image);
438 UPDATE_SRC_ALPHA; 462 UPDATE_SRC_ALPHA;
439 } 463 }
440 while (--col); 464 while (--col);
@@ -443,9 +467,10 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
443 { 467 {
444 do 468 do
445 { 469 {
446 *dst = blend_two_colors(*dst, current_vp->bg_pattern, 470 *dst = blend_two_colors(current_vp->bg_pattern,
447 data & ALPHA_COLOR_LOOKUP_SIZE ); 471 *image, data & ALPHA_COLOR_LOOKUP_SIZE );
448 dst += COL_INC; 472 dst += COL_INC;
473 image += STRIDE_MAIN(1, stride_image);
449 UPDATE_SRC_ALPHA; 474 UPDATE_SRC_ALPHA;
450 } 475 }
451 while (--col); 476 while (--col);
@@ -516,6 +541,15 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
516 } while (--row); 541 } while (--row);
517} 542}
518 543
544
545/* draw alpha bitmap for anti-alias font */
546void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x,
547 int src_y, int stride, int x, int y,
548 int width, int height)
549{
550 lcd_alpha_bitmap_part_mix(NULL, src, src_x, src_y, x, y, width, height, 0, stride);
551}
552
519/* Draw a partial bitmap (mono or native) including alpha channel */ 553/* Draw a partial bitmap (mono or native) including alpha channel */
520void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, 554void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y,
521 int x, int y, int width, int height) 555 int x, int y, int width, int height)
@@ -523,6 +557,10 @@ void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y,
523 int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); 557 int bitmap_stride = STRIDE_MAIN(bm->width, bm->height);
524 if (bm->format == FORMAT_MONO) 558 if (bm->format == FORMAT_MONO)
525 lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); 559 lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height);
560 else if (bm->alpha_offset > 0)
561 lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset,
562 src_x, src_y, x, y, width, height,
563 bitmap_stride, bm->width);
526 else 564 else
527 lcd_bitmap_transparent_part((fb_data*)bm->data, 565 lcd_bitmap_transparent_part((fb_data*)bm->data,
528 src_x, src_y, bitmap_stride, x, y, width, height); 566 src_x, src_y, bitmap_stride, x, y, width, height);