diff options
Diffstat (limited to 'firmware/drivers/lcd-2bit-vi.c')
-rw-r--r-- | firmware/drivers/lcd-2bit-vi.c | 167 |
1 files changed, 153 insertions, 14 deletions
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c index 9ce952b9e0..5edb588ce0 100644 --- a/firmware/drivers/lcd-2bit-vi.c +++ b/firmware/drivers/lcd-2bit-vi.c | |||
@@ -82,6 +82,28 @@ void LCDFN(set_viewport)(struct viewport* vp) | |||
82 | 82 | ||
83 | fg_pattern = patterns[current_vp->fg_pattern & 3]; | 83 | fg_pattern = patterns[current_vp->fg_pattern & 3]; |
84 | bg_pattern = patterns[current_vp->bg_pattern & 3]; | 84 | bg_pattern = patterns[current_vp->bg_pattern & 3]; |
85 | |||
86 | #if defined(SIMULATOR) | ||
87 | /* Force the viewport to be within bounds. If this happens it should | ||
88 | * be considered an error - the viewport will not draw as it might be | ||
89 | * expected. | ||
90 | */ | ||
91 | if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH) | ||
92 | || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT) | ||
93 | || current_vp->x + current_vp->width > LCDM(WIDTH) | ||
94 | || current_vp->y + current_vp->height > LCDM(HEIGHT)) | ||
95 | { | ||
96 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
97 | DEBUGF("ERROR: " | ||
98 | #else | ||
99 | DEBUGF("NOTE: " | ||
100 | #endif | ||
101 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
102 | current_vp->x, current_vp->y, | ||
103 | current_vp->width, current_vp->height); | ||
104 | } | ||
105 | |||
106 | #endif | ||
85 | } | 107 | } |
86 | 108 | ||
87 | void LCDFN(update_viewport)(void) | 109 | void LCDFN(update_viewport)(void) |
@@ -443,8 +465,13 @@ void LCDFN(clear_viewport)(void) | |||
443 | /* Set a single pixel */ | 465 | /* Set a single pixel */ |
444 | void LCDFN(drawpixel)(int x, int y) | 466 | void LCDFN(drawpixel)(int x, int y) |
445 | { | 467 | { |
446 | if (((unsigned)x < (unsigned)current_vp->width) && | 468 | if ( ((unsigned)x < (unsigned)current_vp->width) |
447 | ((unsigned)y < (unsigned)current_vp->height)) | 469 | && ((unsigned)y < (unsigned)current_vp->height) |
470 | #if defined(HAVE_VIEWPORT_CLIP) | ||
471 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | ||
472 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | ||
473 | #endif | ||
474 | ) | ||
448 | LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x+x, current_vp->y+y); | 475 | LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x+x, current_vp->y+y); |
449 | } | 476 | } |
450 | 477 | ||
@@ -513,8 +540,13 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
513 | 540 | ||
514 | for (i = 0; i < numpixels; i++) | 541 | for (i = 0; i < numpixels; i++) |
515 | { | 542 | { |
516 | if (((unsigned)x < (unsigned)current_vp->width) && | 543 | if ( ((unsigned)x < (unsigned)current_vp->width) |
517 | ((unsigned)y < (unsigned)current_vp->height)) | 544 | && ((unsigned)y < (unsigned)current_vp->height) |
545 | #if defined(HAVE_VIEWPORT_CLIP) | ||
546 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | ||
547 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | ||
548 | #endif | ||
549 | ) | ||
518 | pfunc(current_vp->x + x, current_vp->y + y); | 550 | pfunc(current_vp->x + x, current_vp->y + y); |
519 | 551 | ||
520 | if (d < 0) | 552 | if (d < 0) |
@@ -548,24 +580,40 @@ void LCDFN(hline)(int x1, int x2, int y) | |||
548 | x1 = x2; | 580 | x1 = x2; |
549 | x2 = x; | 581 | x2 = x; |
550 | } | 582 | } |
551 | 583 | ||
584 | /******************** In viewport clipping **********************/ | ||
552 | /* nothing to draw? */ | 585 | /* nothing to draw? */ |
553 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) | 586 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
554 | || (x2 < 0)) | 587 | || (x2 < 0)) |
555 | return; | 588 | return; |
556 | 589 | ||
557 | /* clipping */ | ||
558 | if (x1 < 0) | 590 | if (x1 < 0) |
559 | x1 = 0; | 591 | x1 = 0; |
560 | if (x2 >= current_vp->width) | 592 | if (x2 >= current_vp->width) |
561 | x2 = current_vp->width-1; | 593 | x2 = current_vp->width-1; |
562 | 594 | ||
563 | width = x2 - x1 + 1; | ||
564 | |||
565 | /* adjust x1 and y to viewport */ | 595 | /* adjust x1 and y to viewport */ |
566 | x1 += current_vp->x; | 596 | x1 += current_vp->x; |
567 | y += current_vp->y; | 597 | y += current_vp->y; |
568 | 598 | ||
599 | #if defined(HAVE_VIEWPORT_CLIP) | ||
600 | x2 += current_vp->x; | ||
601 | |||
602 | /********************* Viewport on screen clipping ********************/ | ||
603 | /* nothing to draw? */ | ||
604 | if (((unsigned)y >= (unsigned) LCDM(HEIGHT)) || (x1 >= LCDM(WIDTH)) | ||
605 | || (x2 < 0)) | ||
606 | return; | ||
607 | |||
608 | /* clipping */ | ||
609 | if (x1 < 0) | ||
610 | x1 = 0; | ||
611 | if (x2 >= LCDM(WIDTH)) | ||
612 | x2 = LCDM(WIDTH)-1; | ||
613 | #endif | ||
614 | |||
615 | width = x2 - x1 + 1; | ||
616 | |||
569 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 617 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; |
570 | dst = &LCDFN(framebuffer)[y>>3][x1]; | 618 | dst = &LCDFN(framebuffer)[y>>3][x1]; |
571 | mask = 0x0101 << (y & 7); | 619 | mask = 0x0101 << (y & 7); |
@@ -592,12 +640,12 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
592 | y2 = ny; | 640 | y2 = ny; |
593 | } | 641 | } |
594 | 642 | ||
643 | /******************** In viewport clipping **********************/ | ||
595 | /* nothing to draw? */ | 644 | /* nothing to draw? */ |
596 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) | 645 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
597 | || (y2 < 0)) | 646 | || (y2 < 0)) |
598 | return; | 647 | return; |
599 | 648 | ||
600 | /* clipping */ | ||
601 | if (y1 < 0) | 649 | if (y1 < 0) |
602 | y1 = 0; | 650 | y1 = 0; |
603 | if (y2 >= current_vp->height) | 651 | if (y2 >= current_vp->height) |
@@ -607,6 +655,20 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
607 | y1 += current_vp->y; | 655 | y1 += current_vp->y; |
608 | y2 += current_vp->y; | 656 | y2 += current_vp->y; |
609 | x += current_vp->x; | 657 | x += current_vp->x; |
658 | |||
659 | #if defined(HAVE_VIEWPORT_CLIP) | ||
660 | /********************* Viewport on screen clipping ********************/ | ||
661 | /* nothing to draw? */ | ||
662 | if (( (unsigned) x >= (unsigned)LCDM(WIDTH)) || (y1 >= LCDM(HEIGHT)) | ||
663 | || (y2 < 0)) | ||
664 | return; | ||
665 | |||
666 | /* clipping */ | ||
667 | if (y1 < 0) | ||
668 | y1 = 0; | ||
669 | if (y2 >= LCDM(HEIGHT)) | ||
670 | y2 = LCDM(HEIGHT)-1; | ||
671 | #endif | ||
610 | 672 | ||
611 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 673 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; |
612 | dst = &LCDFN(framebuffer)[y1>>3][x]; | 674 | dst = &LCDFN(framebuffer)[y1>>3][x]; |
@@ -651,12 +713,12 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
651 | LCDFN(blockfunc_type) *bfunc; | 713 | LCDFN(blockfunc_type) *bfunc; |
652 | bool fillopt = false; | 714 | bool fillopt = false; |
653 | 715 | ||
716 | /******************** In viewport clipping **********************/ | ||
654 | /* nothing to draw? */ | 717 | /* nothing to draw? */ |
655 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 718 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
656 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 719 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
657 | return; | 720 | return; |
658 | 721 | ||
659 | /* clipping */ | ||
660 | if (x < 0) | 722 | if (x < 0) |
661 | { | 723 | { |
662 | width += x; | 724 | width += x; |
@@ -675,6 +737,31 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
675 | /* adjust for viewport */ | 737 | /* adjust for viewport */ |
676 | x += current_vp->x; | 738 | x += current_vp->x; |
677 | y += current_vp->y; | 739 | y += current_vp->y; |
740 | |||
741 | #if defined(HAVE_VIEWPORT_CLIP) | ||
742 | /********************* Viewport on screen clipping ********************/ | ||
743 | /* nothing to draw? */ | ||
744 | if ((x >= LCDM(WIDTH)) || (y >= LCDM(HEIGHT)) | ||
745 | || (x + width <= 0) || (y + height <= 0)) | ||
746 | return; | ||
747 | |||
748 | /* clip image in viewport in screen */ | ||
749 | if (x < 0) | ||
750 | { | ||
751 | width += x; | ||
752 | x = 0; | ||
753 | } | ||
754 | if (y < 0) | ||
755 | { | ||
756 | height += y; | ||
757 | y = 0; | ||
758 | } | ||
759 | if (x + width > LCDM(WIDTH)) | ||
760 | width = LCDM(WIDTH) - x; | ||
761 | if (y + height > LCDM(HEIGHT)) | ||
762 | height = LCDM(HEIGHT) - y; | ||
763 | #endif | ||
764 | |||
678 | 765 | ||
679 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 766 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
680 | { | 767 | { |
@@ -751,12 +838,12 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x, | |||
751 | unsigned data, mask, mask_bottom; | 838 | unsigned data, mask, mask_bottom; |
752 | LCDFN(blockfunc_type) *bfunc; | 839 | LCDFN(blockfunc_type) *bfunc; |
753 | 840 | ||
841 | /******************** Image in viewport clipping **********************/ | ||
754 | /* nothing to draw? */ | 842 | /* nothing to draw? */ |
755 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 843 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
756 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 844 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
757 | return; | 845 | return; |
758 | 846 | ||
759 | /* clipping */ | ||
760 | if (x < 0) | 847 | if (x < 0) |
761 | { | 848 | { |
762 | width += x; | 849 | width += x; |
@@ -777,6 +864,32 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x, | |||
777 | /* adjust for viewport */ | 864 | /* adjust for viewport */ |
778 | x += current_vp->x; | 865 | x += current_vp->x; |
779 | y += current_vp->y; | 866 | y += current_vp->y; |
867 | |||
868 | #if defined(HAVE_VIEWPORT_CLIP) | ||
869 | /********************* Viewport on screen clipping ********************/ | ||
870 | /* nothing to draw? */ | ||
871 | if ((x >= LCDM(WIDTH)) || (y >= LCDM(HEIGHT)) | ||
872 | || (x + width <= 0) || (y + height <= 0)) | ||
873 | return; | ||
874 | |||
875 | /* clip image in viewport in screen */ | ||
876 | if (x < 0) | ||
877 | { | ||
878 | width += x; | ||
879 | src_x -= x; | ||
880 | x = 0; | ||
881 | } | ||
882 | if (y < 0) | ||
883 | { | ||
884 | height += y; | ||
885 | src_y -= y; | ||
886 | y = 0; | ||
887 | } | ||
888 | if (x + width > LCDM(WIDTH)) | ||
889 | width = LCDM(WIDTH) - x; | ||
890 | if (y + height > LCDM(HEIGHT)) | ||
891 | height = LCDM(HEIGHT) - y; | ||
892 | #endif | ||
780 | 893 | ||
781 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 894 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
782 | src_y &= 7; | 895 | src_y &= 7; |
@@ -893,12 +1006,12 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x, | |||
893 | FBFN(data) *dst, *dst_end; | 1006 | FBFN(data) *dst, *dst_end; |
894 | unsigned mask, mask_bottom; | 1007 | unsigned mask, mask_bottom; |
895 | 1008 | ||
1009 | /******************** Image in viewport clipping **********************/ | ||
896 | /* nothing to draw? */ | 1010 | /* nothing to draw? */ |
897 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 1011 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
898 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 1012 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
899 | return; | 1013 | return; |
900 | 1014 | ||
901 | /* clipping */ | ||
902 | if (x < 0) | 1015 | if (x < 0) |
903 | { | 1016 | { |
904 | width += x; | 1017 | width += x; |
@@ -920,6 +1033,32 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x, | |||
920 | x += current_vp->x; | 1033 | x += current_vp->x; |
921 | y += current_vp->y; | 1034 | y += current_vp->y; |
922 | 1035 | ||
1036 | #if defined(HAVE_VIEWPORT_CLIP) | ||
1037 | /********************* Viewport on screen clipping ********************/ | ||
1038 | /* nothing to draw? */ | ||
1039 | if ((x >= LCDM(WIDTH)) || (y >= LCDM(HEIGHT)) | ||
1040 | || (x + width <= 0) || (y + height <= 0)) | ||
1041 | return; | ||
1042 | |||
1043 | /* clip image in viewport in screen */ | ||
1044 | if (x < 0) | ||
1045 | { | ||
1046 | width += x; | ||
1047 | src_x -= x; | ||
1048 | x = 0; | ||
1049 | } | ||
1050 | if (y < 0) | ||
1051 | { | ||
1052 | height += y; | ||
1053 | src_y -= y; | ||
1054 | y = 0; | ||
1055 | } | ||
1056 | if (x + width > LCDM(WIDTH)) | ||
1057 | width = LCDM(WIDTH) - x; | ||
1058 | if (y + height > LCDM(HEIGHT)) | ||
1059 | height = LCDM(HEIGHT) - y; | ||
1060 | #endif | ||
1061 | |||
923 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 1062 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
924 | src_y &= 7; | 1063 | src_y &= 7; |
925 | y -= src_y; | 1064 | y -= src_y; |