diff options
Diffstat (limited to 'firmware/drivers/lcd-2bit-horz.c')
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 165 |
1 files changed, 152 insertions, 13 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index f9a53ee20c..2e965b35fa 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c | |||
@@ -87,6 +87,28 @@ void lcd_set_viewport(struct viewport* vp) | |||
87 | 87 | ||
88 | fg_pattern = 0x55 * (~current_vp->fg_pattern & 3); | 88 | fg_pattern = 0x55 * (~current_vp->fg_pattern & 3); |
89 | bg_pattern = 0x55 * (~current_vp->bg_pattern & 3); | 89 | bg_pattern = 0x55 * (~current_vp->bg_pattern & 3); |
90 | |||
91 | #if defined(SIMULATOR) | ||
92 | /* Force the viewport to be within bounds. If this happens it should | ||
93 | * be considered an error - the viewport will not draw as it might be | ||
94 | * expected. | ||
95 | */ | ||
96 | if((unsigned) current_vp->x > (unsigned) LCD_WIDTH | ||
97 | || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT | ||
98 | || current_vp->x + current_vp->width > LCD_WIDTH | ||
99 | || current_vp->y + current_vp->height > LCD_HEIGHT) | ||
100 | { | ||
101 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
102 | DEBUGF("ERROR: " | ||
103 | #else | ||
104 | DEBUGF("NOTE: " | ||
105 | #endif | ||
106 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
107 | current_vp->x, current_vp->y, | ||
108 | current_vp->width, current_vp->height); | ||
109 | } | ||
110 | |||
111 | #endif | ||
90 | } | 112 | } |
91 | 113 | ||
92 | void lcd_update_viewport(void) | 114 | void lcd_update_viewport(void) |
@@ -415,8 +437,13 @@ void lcd_clear_viewport(void) | |||
415 | /* Set a single pixel */ | 437 | /* Set a single pixel */ |
416 | void lcd_drawpixel(int x, int y) | 438 | void lcd_drawpixel(int x, int y) |
417 | { | 439 | { |
418 | if (((unsigned)x < (unsigned)current_vp->width) && | 440 | if ( ((unsigned)x < (unsigned)current_vp->width) |
419 | ((unsigned)y < (unsigned)current_vp->height)) | 441 | && ((unsigned)y < (unsigned)current_vp->height) |
442 | #if defined(HAVE_VIEWPORT_CLIP) | ||
443 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
444 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
445 | #endif | ||
446 | ) | ||
420 | lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); | 447 | lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); |
421 | } | 448 | } |
422 | 449 | ||
@@ -485,8 +512,13 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
485 | 512 | ||
486 | for (i = 0; i < numpixels; i++) | 513 | for (i = 0; i < numpixels; i++) |
487 | { | 514 | { |
488 | if (((unsigned)x < (unsigned)current_vp->width) && | 515 | if ( ((unsigned)x < (unsigned)current_vp->width) |
489 | ((unsigned)y < (unsigned)current_vp->height)) | 516 | && ((unsigned)y < (unsigned)current_vp->height) |
517 | #if defined(HAVE_VIEWPORT_CLIP) | ||
518 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
519 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
520 | #endif | ||
521 | ) | ||
490 | pfunc(current_vp->x + x, current_vp->y + y); | 522 | pfunc(current_vp->x + x, current_vp->y + y); |
491 | 523 | ||
492 | if (d < 0) | 524 | if (d < 0) |
@@ -520,12 +552,12 @@ void lcd_hline(int x1, int x2, int y) | |||
520 | x2 = nx; | 552 | x2 = nx; |
521 | } | 553 | } |
522 | 554 | ||
555 | /******************** In viewport clipping **********************/ | ||
523 | /* nothing to draw? */ | 556 | /* nothing to draw? */ |
524 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) | 557 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
525 | || (x2 < 0)) | 558 | || (x2 < 0)) |
526 | return; | 559 | return; |
527 | 560 | ||
528 | /* clipping */ | ||
529 | if (x1 < 0) | 561 | if (x1 < 0) |
530 | x1 = 0; | 562 | x1 = 0; |
531 | if (x2 >= current_vp->width) | 563 | if (x2 >= current_vp->width) |
@@ -535,6 +567,20 @@ void lcd_hline(int x1, int x2, int y) | |||
535 | x1 += current_vp->x; | 567 | x1 += current_vp->x; |
536 | x2 += current_vp->x; | 568 | x2 += current_vp->x; |
537 | y += current_vp->y; | 569 | y += current_vp->y; |
570 | |||
571 | #if defined(HAVE_VIEWPORT_CLIP) | ||
572 | /********************* Viewport on screen clipping ********************/ | ||
573 | /* nothing to draw? */ | ||
574 | if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH) | ||
575 | || (x2 < 0)) | ||
576 | return; | ||
577 | |||
578 | /* clipping */ | ||
579 | if (x1 < 0) | ||
580 | x1 = 0; | ||
581 | if (x2 >= LCD_WIDTH) | ||
582 | x2 = LCD_WIDTH-1; | ||
583 | #endif | ||
538 | 584 | ||
539 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | 585 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
540 | dst = &lcd_framebuffer[y][x1>>2]; | 586 | dst = &lcd_framebuffer[y][x1>>2]; |
@@ -567,12 +613,12 @@ void lcd_vline(int x, int y1, int y2) | |||
567 | y2 = y; | 613 | y2 = y; |
568 | } | 614 | } |
569 | 615 | ||
616 | /******************** In viewport clipping **********************/ | ||
570 | /* nothing to draw? */ | 617 | /* nothing to draw? */ |
571 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) | 618 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
572 | || (y2 < 0)) | 619 | || (y2 < 0)) |
573 | return; | 620 | return; |
574 | 621 | ||
575 | /* clipping */ | ||
576 | if (y1 < 0) | 622 | if (y1 < 0) |
577 | y1 = 0; | 623 | y1 = 0; |
578 | if (y2 >= current_vp->height) | 624 | if (y2 >= current_vp->height) |
@@ -582,6 +628,20 @@ void lcd_vline(int x, int y1, int y2) | |||
582 | y1 += current_vp->y; | 628 | y1 += current_vp->y; |
583 | y2 += current_vp->y; | 629 | y2 += current_vp->y; |
584 | x += current_vp->x; | 630 | x += current_vp->x; |
631 | |||
632 | #if defined(HAVE_VIEWPORT_CLIP) | ||
633 | /********************* Viewport on screen clipping ********************/ | ||
634 | /* nothing to draw? */ | ||
635 | if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT) | ||
636 | || (y2 < 0)) | ||
637 | return; | ||
638 | |||
639 | /* clipping */ | ||
640 | if (y1 < 0) | ||
641 | y1 = 0; | ||
642 | if (y2 >= LCD_HEIGHT) | ||
643 | y2 = LCD_HEIGHT-1; | ||
644 | #endif | ||
585 | 645 | ||
586 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | 646 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
587 | dst = &lcd_framebuffer[y1][x>>2]; | 647 | dst = &lcd_framebuffer[y1][x>>2]; |
@@ -619,12 +679,12 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
619 | unsigned mask, mask_right; | 679 | unsigned mask, mask_right; |
620 | lcd_blockfunc_type *bfunc; | 680 | lcd_blockfunc_type *bfunc; |
621 | 681 | ||
682 | /******************** In viewport clipping **********************/ | ||
622 | /* nothing to draw? */ | 683 | /* nothing to draw? */ |
623 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height) | 684 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height) |
624 | || (x + width <= 0) || (y + height <= 0)) | 685 | || (x + width <= 0) || (y + height <= 0)) |
625 | return; | 686 | return; |
626 | 687 | ||
627 | /* clipping */ | ||
628 | if (x < 0) | 688 | if (x < 0) |
629 | { | 689 | { |
630 | width += x; | 690 | width += x; |
@@ -643,6 +703,30 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
643 | /* adjust for viewport */ | 703 | /* adjust for viewport */ |
644 | x += current_vp->x; | 704 | x += current_vp->x; |
645 | y += current_vp->y; | 705 | y += current_vp->y; |
706 | |||
707 | #if defined(HAVE_VIEWPORT_CLIP) | ||
708 | /********************* Viewport on screen clipping ********************/ | ||
709 | /* nothing to draw? */ | ||
710 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
711 | || (x + width <= 0) || (y + height <= 0)) | ||
712 | return; | ||
713 | |||
714 | /* clip image in viewport in screen */ | ||
715 | if (x < 0) | ||
716 | { | ||
717 | width += x; | ||
718 | x = 0; | ||
719 | } | ||
720 | if (y < 0) | ||
721 | { | ||
722 | height += y; | ||
723 | y = 0; | ||
724 | } | ||
725 | if (x + width > LCD_WIDTH) | ||
726 | width = LCD_WIDTH - x; | ||
727 | if (y + height > LCD_HEIGHT) | ||
728 | height = LCD_HEIGHT - y; | ||
729 | #endif | ||
646 | 730 | ||
647 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | 731 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
648 | dst = &lcd_framebuffer[y][x>>2]; | 732 | dst = &lcd_framebuffer[y][x>>2]; |
@@ -696,12 +780,12 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
696 | unsigned dst_mask; | 780 | unsigned dst_mask; |
697 | int drmode = current_vp->drawmode; | 781 | int drmode = current_vp->drawmode; |
698 | 782 | ||
783 | /******************** Image in viewport clipping **********************/ | ||
699 | /* nothing to draw? */ | 784 | /* nothing to draw? */ |
700 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 785 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
701 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 786 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
702 | return; | 787 | return; |
703 | 788 | ||
704 | /* clipping */ | ||
705 | if (x < 0) | 789 | if (x < 0) |
706 | { | 790 | { |
707 | width += x; | 791 | width += x; |
@@ -718,12 +802,41 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
718 | width = current_vp->width - x; | 802 | width = current_vp->width - x; |
719 | if (y + height > current_vp->height) | 803 | if (y + height > current_vp->height) |
720 | height = current_vp->height - y; | 804 | height = current_vp->height - y; |
805 | |||
806 | x += current_vp->x; /* adjust for viewport */ | ||
807 | y += current_vp->y; /* adjust for viewport */ | ||
808 | |||
809 | #if defined(HAVE_VIEWPORT_CLIP) | ||
810 | /********************* Viewport on screen clipping ********************/ | ||
811 | /* nothing to draw? */ | ||
812 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
813 | || (x + width <= 0) || (y + height <= 0)) | ||
814 | return; | ||
815 | |||
816 | /* clip image in viewport in screen */ | ||
817 | if (x < 0) | ||
818 | { | ||
819 | width += x; | ||
820 | src_x -= x; | ||
821 | x = 0; | ||
822 | } | ||
823 | if (y < 0) | ||
824 | { | ||
825 | height += y; | ||
826 | src_y -= y; | ||
827 | y = 0; | ||
828 | } | ||
829 | if (x + width > LCD_WIDTH) | ||
830 | width = LCD_WIDTH - x; | ||
831 | if (y + height > LCD_HEIGHT) | ||
832 | height = LCD_HEIGHT - y; | ||
833 | #endif | ||
721 | 834 | ||
722 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 835 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
723 | src_y &= 7; | 836 | src_y &= 7; |
724 | src_end = src + width; | 837 | src_end = src + width; |
725 | x += current_vp->x; /* adjust for viewport */ | 838 | |
726 | dst = &lcd_framebuffer[current_vp->y + y][x >> 2]; | 839 | dst = &lcd_framebuffer[y][x >> 2]; |
727 | dst_end = dst + height * LCD_FBWIDTH; | 840 | dst_end = dst + height * LCD_FBWIDTH; |
728 | dst_mask = pixmask[x & 3]; | 841 | dst_mask = pixmask[x & 3]; |
729 | 842 | ||
@@ -879,12 +992,12 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x, | |||
879 | unsigned char *dst, *dst_end; | 992 | unsigned char *dst, *dst_end; |
880 | unsigned mask, mask_right; | 993 | unsigned mask, mask_right; |
881 | 994 | ||
995 | /******************** Image in viewport clipping **********************/ | ||
882 | /* nothing to draw? */ | 996 | /* nothing to draw? */ |
883 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 997 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
884 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 998 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
885 | return; | 999 | return; |
886 | 1000 | ||
887 | /* clipping */ | ||
888 | if (x < 0) | 1001 | if (x < 0) |
889 | { | 1002 | { |
890 | width += x; | 1003 | width += x; |
@@ -905,6 +1018,32 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x, | |||
905 | /* adjust for viewport */ | 1018 | /* adjust for viewport */ |
906 | x += current_vp->x; | 1019 | x += current_vp->x; |
907 | y += current_vp->y; | 1020 | y += current_vp->y; |
1021 | |||
1022 | #if defined(HAVE_VIEWPORT_CLIP) | ||
1023 | /********************* Viewport on screen clipping ********************/ | ||
1024 | /* nothing to draw? */ | ||
1025 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
1026 | || (x + width <= 0) || (y + height <= 0)) | ||
1027 | return; | ||
1028 | |||
1029 | /* clip image in viewport in screen */ | ||
1030 | if (x < 0) | ||
1031 | { | ||
1032 | width += x; | ||
1033 | src_x -= x; | ||
1034 | x = 0; | ||
1035 | } | ||
1036 | if (y < 0) | ||
1037 | { | ||
1038 | height += y; | ||
1039 | src_y -= y; | ||
1040 | y = 0; | ||
1041 | } | ||
1042 | if (x + width > LCD_WIDTH) | ||
1043 | width = LCD_WIDTH - x; | ||
1044 | if (y + height > LCD_HEIGHT) | ||
1045 | height = LCD_HEIGHT - y; | ||
1046 | #endif | ||
908 | 1047 | ||
909 | stride = (stride + 3) >> 2; /* convert to no. of bytes */ | 1048 | stride = (stride + 3) >> 2; /* convert to no. of bytes */ |
910 | 1049 | ||