diff options
author | Karl Kurbjun <kkurbjun@gmail.com> | 2009-11-07 18:38:46 +0000 |
---|---|---|
committer | Karl Kurbjun <kkurbjun@gmail.com> | 2009-11-07 18:38:46 +0000 |
commit | 765ff0130ab58c67e82a2ed17c64c577c6434d57 (patch) | |
tree | c825c50286a468ecb421eca0cc571c1a07dfca24 /firmware/drivers/lcd-2bit-vert.c | |
parent | b1783c3c64d530e77ea2301e70a000f2a624bb74 (diff) | |
download | rockbox-765ff0130ab58c67e82a2ed17c64c577c6434d57.tar.gz rockbox-765ff0130ab58c67e82a2ed17c64c577c6434d57.zip |
Add optional viewport clipping, can be enabled with HAVE_VIEWPORT_CLIP. A simulator check is also added to set_viewport that will show an error/note when DEBUGF is enabled.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23551 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-2bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 165 |
1 files changed, 151 insertions, 14 deletions
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index a124e3e15d..3a089722f4 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c | |||
@@ -89,6 +89,28 @@ void lcd_set_viewport(struct viewport* vp) | |||
89 | 89 | ||
90 | fg_pattern = 0x55 * (~current_vp->fg_pattern & 3); | 90 | fg_pattern = 0x55 * (~current_vp->fg_pattern & 3); |
91 | bg_pattern = 0x55 * (~current_vp->bg_pattern & 3); | 91 | bg_pattern = 0x55 * (~current_vp->bg_pattern & 3); |
92 | |||
93 | #if defined(SIMULATOR) | ||
94 | /* Force the viewport to be within bounds. If this happens it should | ||
95 | * be considered an error - the viewport will not draw as it might be | ||
96 | * expected. | ||
97 | */ | ||
98 | if((unsigned) current_vp->x > (unsigned) LCD_WIDTH | ||
99 | || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT | ||
100 | || current_vp->x + current_vp->width > LCD_WIDTH | ||
101 | || current_vp->y + current_vp->height > LCD_HEIGHT) | ||
102 | { | ||
103 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
104 | DEBUGF("ERROR: " | ||
105 | #else | ||
106 | DEBUGF("NOTE: " | ||
107 | #endif | ||
108 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
109 | current_vp->x, current_vp->y, | ||
110 | current_vp->width, current_vp->height); | ||
111 | } | ||
112 | |||
113 | #endif | ||
92 | } | 114 | } |
93 | 115 | ||
94 | void lcd_update_viewport(void) | 116 | void lcd_update_viewport(void) |
@@ -418,8 +440,13 @@ void lcd_clear_viewport(void) | |||
418 | /* Set a single pixel */ | 440 | /* Set a single pixel */ |
419 | void lcd_drawpixel(int x, int y) | 441 | void lcd_drawpixel(int x, int y) |
420 | { | 442 | { |
421 | if (((unsigned)x < (unsigned)current_vp->width) && | 443 | if ( ((unsigned)x < (unsigned)current_vp->width) |
422 | ((unsigned)y < (unsigned)current_vp->height)) | 444 | && ((unsigned)y < (unsigned)current_vp->height) |
445 | #if defined(HAVE_VIEWPORT_CLIP) | ||
446 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
447 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
448 | #endif | ||
449 | ) | ||
423 | lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); | 450 | lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); |
424 | } | 451 | } |
425 | 452 | ||
@@ -488,8 +515,13 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
488 | 515 | ||
489 | for (i = 0; i < numpixels; i++) | 516 | for (i = 0; i < numpixels; i++) |
490 | { | 517 | { |
491 | if (((unsigned)x < (unsigned)current_vp->width) && | 518 | if ( ((unsigned)x < (unsigned)current_vp->width) |
492 | ((unsigned)y < (unsigned)current_vp->height)) | 519 | && ((unsigned)y < (unsigned)current_vp->height) |
520 | #if defined(HAVE_VIEWPORT_CLIP) | ||
521 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
522 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
523 | #endif | ||
524 | ) | ||
493 | pfunc(current_vp->x + x, current_vp->y + y); | 525 | pfunc(current_vp->x + x, current_vp->y + y); |
494 | 526 | ||
495 | if (d < 0) | 527 | if (d < 0) |
@@ -524,22 +556,37 @@ void lcd_hline(int x1, int x2, int y) | |||
524 | x2 = x; | 556 | x2 = x; |
525 | } | 557 | } |
526 | 558 | ||
559 | /******************** In viewport clipping **********************/ | ||
527 | /* nothing to draw? */ | 560 | /* nothing to draw? */ |
528 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) | 561 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
529 | || (x2 < 0)) | 562 | || (x2 < 0)) |
530 | return; | 563 | return; |
531 | 564 | ||
532 | /* clipping */ | ||
533 | if (x1 < 0) | 565 | if (x1 < 0) |
534 | x1 = 0; | 566 | x1 = 0; |
535 | if (x2 >= current_vp->width) | 567 | if (x2 >= current_vp->width) |
536 | x2 = current_vp->width-1; | 568 | x2 = current_vp->width-1; |
537 | 569 | ||
538 | width = x2 - x1 + 1; | ||
539 | |||
540 | /* adjust x1 and y to viewport */ | 570 | /* adjust x1 and y to viewport */ |
541 | x1 += current_vp->x; | 571 | x1 += current_vp->x; |
572 | x2 += current_vp->x; | ||
542 | y += current_vp->y; | 573 | y += current_vp->y; |
574 | |||
575 | #if defined(HAVE_VIEWPORT_CLIP) | ||
576 | /********************* Viewport on screen clipping ********************/ | ||
577 | /* nothing to draw? */ | ||
578 | if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH) | ||
579 | || (x2 < 0)) | ||
580 | return; | ||
581 | |||
582 | /* clipping */ | ||
583 | if (x1 < 0) | ||
584 | x1 = 0; | ||
585 | if (x2 >= LCD_WIDTH) | ||
586 | x2 = LCD_WIDTH-1; | ||
587 | #endif | ||
588 | |||
589 | width = x2 - x1 + 1; | ||
543 | 590 | ||
544 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | 591 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
545 | dst = &lcd_framebuffer[y>>2][x1]; | 592 | dst = &lcd_framebuffer[y>>2][x1]; |
@@ -567,12 +614,12 @@ void lcd_vline(int x, int y1, int y2) | |||
567 | y2 = ny; | 614 | y2 = ny; |
568 | } | 615 | } |
569 | 616 | ||
617 | /******************** In viewport clipping **********************/ | ||
570 | /* nothing to draw? */ | 618 | /* nothing to draw? */ |
571 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) | 619 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
572 | || (y2 < 0)) | 620 | || (y2 < 0)) |
573 | return; | 621 | return; |
574 | 622 | ||
575 | /* clipping */ | ||
576 | if (y1 < 0) | 623 | if (y1 < 0) |
577 | y1 = 0; | 624 | y1 = 0; |
578 | if (y2 >= current_vp->height) | 625 | if (y2 >= current_vp->height) |
@@ -582,6 +629,20 @@ void lcd_vline(int x, int y1, int y2) | |||
582 | y1 += current_vp->y; | 629 | y1 += current_vp->y; |
583 | y2 += current_vp->y; | 630 | y2 += current_vp->y; |
584 | x += current_vp->x; | 631 | x += current_vp->x; |
632 | |||
633 | #if defined(HAVE_VIEWPORT_CLIP) | ||
634 | /********************* Viewport on screen clipping ********************/ | ||
635 | /* nothing to draw? */ | ||
636 | if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT) | ||
637 | || (y2 < 0)) | ||
638 | return; | ||
639 | |||
640 | /* clipping */ | ||
641 | if (y1 < 0) | ||
642 | y1 = 0; | ||
643 | if (y2 >= LCD_HEIGHT) | ||
644 | y2 = LCD_HEIGHT-1; | ||
645 | #endif | ||
585 | 646 | ||
586 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | 647 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
587 | dst = &lcd_framebuffer[y1>>2][x]; | 648 | dst = &lcd_framebuffer[y1>>2][x]; |
@@ -624,12 +685,12 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
624 | lcd_blockfunc_type *bfunc; | 685 | lcd_blockfunc_type *bfunc; |
625 | bool fillopt = false; | 686 | bool fillopt = false; |
626 | 687 | ||
688 | /******************** In viewport clipping **********************/ | ||
627 | /* nothing to draw? */ | 689 | /* nothing to draw? */ |
628 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 690 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
629 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 691 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
630 | return; | 692 | return; |
631 | 693 | ||
632 | /* clipping */ | ||
633 | if (x < 0) | 694 | if (x < 0) |
634 | { | 695 | { |
635 | width += x; | 696 | width += x; |
@@ -648,6 +709,30 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
648 | /* adjust for viewport */ | 709 | /* adjust for viewport */ |
649 | x += current_vp->x; | 710 | x += current_vp->x; |
650 | y += current_vp->y; | 711 | y += current_vp->y; |
712 | |||
713 | #if defined(HAVE_VIEWPORT_CLIP) | ||
714 | /********************* Viewport on screen clipping ********************/ | ||
715 | /* nothing to draw? */ | ||
716 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
717 | || (x + width <= 0) || (y + height <= 0)) | ||
718 | return; | ||
719 | |||
720 | /* clip image in viewport in screen */ | ||
721 | if (x < 0) | ||
722 | { | ||
723 | width += x; | ||
724 | x = 0; | ||
725 | } | ||
726 | if (y < 0) | ||
727 | { | ||
728 | height += y; | ||
729 | y = 0; | ||
730 | } | ||
731 | if (x + width > LCD_WIDTH) | ||
732 | width = LCD_WIDTH - x; | ||
733 | if (y + height > LCD_HEIGHT) | ||
734 | height = LCD_HEIGHT - y; | ||
735 | #endif | ||
651 | 736 | ||
652 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 737 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
653 | { | 738 | { |
@@ -722,12 +807,12 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
722 | unsigned mask, mask_bottom; | 807 | unsigned mask, mask_bottom; |
723 | lcd_blockfunc_type *bfunc; | 808 | lcd_blockfunc_type *bfunc; |
724 | 809 | ||
810 | /******************** Image in viewport clipping **********************/ | ||
725 | /* nothing to draw? */ | 811 | /* nothing to draw? */ |
726 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 812 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
727 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 813 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
728 | return; | 814 | return; |
729 | 815 | ||
730 | /* clipping */ | ||
731 | if (x < 0) | 816 | if (x < 0) |
732 | { | 817 | { |
733 | width += x; | 818 | width += x; |
@@ -748,6 +833,32 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
748 | /* adjust for viewport */ | 833 | /* adjust for viewport */ |
749 | x += current_vp->x; | 834 | x += current_vp->x; |
750 | y += current_vp->y; | 835 | y += current_vp->y; |
836 | |||
837 | #if defined(HAVE_VIEWPORT_CLIP) | ||
838 | /********************* Viewport on screen clipping ********************/ | ||
839 | /* nothing to draw? */ | ||
840 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
841 | || (x + width <= 0) || (y + height <= 0)) | ||
842 | return; | ||
843 | |||
844 | /* clip image in viewport in screen */ | ||
845 | if (x < 0) | ||
846 | { | ||
847 | width += x; | ||
848 | src_x -= x; | ||
849 | x = 0; | ||
850 | } | ||
851 | if (y < 0) | ||
852 | { | ||
853 | height += y; | ||
854 | src_y -= y; | ||
855 | y = 0; | ||
856 | } | ||
857 | if (x + width > LCD_WIDTH) | ||
858 | width = LCD_WIDTH - x; | ||
859 | if (y + height > LCD_HEIGHT) | ||
860 | height = LCD_HEIGHT - y; | ||
861 | #endif | ||
751 | 862 | ||
752 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 863 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
753 | src_y &= 7; | 864 | src_y &= 7; |
@@ -893,12 +1004,12 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
893 | fb_data *dst, *dst_end; | 1004 | fb_data *dst, *dst_end; |
894 | unsigned mask, mask_bottom; | 1005 | unsigned mask, mask_bottom; |
895 | 1006 | ||
1007 | /******************** Image in viewport clipping **********************/ | ||
896 | /* nothing to draw? */ | 1008 | /* nothing to draw? */ |
897 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 1009 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
898 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 1010 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
899 | return; | 1011 | return; |
900 | 1012 | ||
901 | /* clipping */ | ||
902 | if (x < 0) | 1013 | if (x < 0) |
903 | { | 1014 | { |
904 | width += x; | 1015 | width += x; |
@@ -919,6 +1030,32 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
919 | /* adjust for viewport */ | 1030 | /* adjust for viewport */ |
920 | x += current_vp->x; | 1031 | x += current_vp->x; |
921 | y += current_vp->y; | 1032 | y += current_vp->y; |
1033 | |||
1034 | #if defined(HAVE_VIEWPORT_CLIP) | ||
1035 | /********************* Viewport on screen clipping ********************/ | ||
1036 | /* nothing to draw? */ | ||
1037 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
1038 | || (x + width <= 0) || (y + height <= 0)) | ||
1039 | return; | ||
1040 | |||
1041 | /* clip image in viewport in screen */ | ||
1042 | if (x < 0) | ||
1043 | { | ||
1044 | width += x; | ||
1045 | src_x -= x; | ||
1046 | x = 0; | ||
1047 | } | ||
1048 | if (y < 0) | ||
1049 | { | ||
1050 | height += y; | ||
1051 | src_y -= y; | ||
1052 | y = 0; | ||
1053 | } | ||
1054 | if (x + width > LCD_WIDTH) | ||
1055 | width = LCD_WIDTH - x; | ||
1056 | if (y + height > LCD_HEIGHT) | ||
1057 | height = LCD_HEIGHT - y; | ||
1058 | #endif | ||
922 | 1059 | ||
923 | src += stride * (src_y >> 2) + src_x; /* move starting point */ | 1060 | src += stride * (src_y >> 2) + src_x; /* move starting point */ |
924 | src_y &= 3; | 1061 | src_y &= 3; |