diff options
Diffstat (limited to 'firmware/drivers/lcd-16bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-16bit-vert.c | 283 |
1 files changed, 235 insertions, 48 deletions
diff --git a/firmware/drivers/lcd-16bit-vert.c b/firmware/drivers/lcd-16bit-vert.c index 1e49bb354d..586feabeca 100644 --- a/firmware/drivers/lcd-16bit-vert.c +++ b/firmware/drivers/lcd-16bit-vert.c | |||
@@ -92,6 +92,28 @@ void lcd_set_viewport(struct viewport* vp) | |||
92 | current_vp = &default_vp; | 92 | current_vp = &default_vp; |
93 | else | 93 | else |
94 | current_vp = vp; | 94 | current_vp = vp; |
95 | |||
96 | #if defined(SIMULATOR) | ||
97 | /* Force the viewport to be within bounds. If this happens it should | ||
98 | * be considered an error - the viewport will not draw as it might be | ||
99 | * expected. | ||
100 | */ | ||
101 | if((unsigned) current_vp->x > (unsigned) LCD_WIDTH | ||
102 | || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT | ||
103 | || current_vp->x + current_vp->width > LCD_WIDTH | ||
104 | || current_vp->y + current_vp->height > LCD_HEIGHT) | ||
105 | { | ||
106 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
107 | DEBUGF("ERROR: " | ||
108 | #else | ||
109 | DEBUGF("NOTE: " | ||
110 | #endif | ||
111 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
112 | current_vp->x, current_vp->y, | ||
113 | current_vp->width, current_vp->height); | ||
114 | } | ||
115 | |||
116 | #endif | ||
95 | } | 117 | } |
96 | 118 | ||
97 | void lcd_update_viewport(void) | 119 | void lcd_update_viewport(void) |
@@ -312,8 +334,13 @@ void lcd_clear_display(void) | |||
312 | /* Set a single pixel */ | 334 | /* Set a single pixel */ |
313 | void lcd_drawpixel(int x, int y) | 335 | void lcd_drawpixel(int x, int y) |
314 | { | 336 | { |
315 | if (((unsigned)x < (unsigned)current_vp->width) && | 337 | if ( ((unsigned)x < (unsigned)current_vp->width) |
316 | ((unsigned)y < (unsigned)current_vp->height)) | 338 | && ((unsigned)y < (unsigned)current_vp->height) |
339 | #if defined(HAVE_VIEWPORT_CLIP) | ||
340 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
341 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
342 | #endif | ||
343 | ) | ||
317 | lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y)); | 344 | lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y)); |
318 | } | 345 | } |
319 | 346 | ||
@@ -382,7 +409,13 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
382 | 409 | ||
383 | for (i = 0; i < numpixels; i++) | 410 | for (i = 0; i < numpixels; i++) |
384 | { | 411 | { |
385 | if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height)) | 412 | if ( ((unsigned)x < (unsigned)current_vp->width) |
413 | && ((unsigned)y < (unsigned)current_vp->height) | ||
414 | #if defined(HAVE_VIEWPORT_CLIP) | ||
415 | && ((unsigned)x < (unsigned)LCD_WIDTH) | ||
416 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | ||
417 | #endif | ||
418 | ) | ||
386 | pfunc(LCDADDR(x + current_vp->x, y + current_vp->y)); | 419 | pfunc(LCDADDR(x + current_vp->x, y + current_vp->y)); |
387 | 420 | ||
388 | if (d < 0) | 421 | if (d < 0) |
@@ -415,19 +448,38 @@ void lcd_hline(int x1, int x2, int y) | |||
415 | x2 = x; | 448 | x2 = x; |
416 | } | 449 | } |
417 | 450 | ||
451 | /******************** In viewport clipping **********************/ | ||
418 | /* nothing to draw? */ | 452 | /* nothing to draw? */ |
419 | if (((unsigned)y >= (unsigned)current_vp->height) || | 453 | if (((unsigned)y >= (unsigned)current_vp->height) || |
420 | (x1 >= current_vp->width) || | 454 | (x1 >= current_vp->width) || |
421 | (x2 < 0)) | 455 | (x2 < 0)) |
422 | return; | 456 | return; |
423 | 457 | ||
424 | /* clipping */ | ||
425 | if (x1 < 0) | 458 | if (x1 < 0) |
426 | x1 = 0; | 459 | x1 = 0; |
427 | if (x2 >= current_vp->width) | 460 | if (x2 >= current_vp->width) |
428 | x2 = current_vp->width-1; | 461 | x2 = current_vp->width-1; |
462 | |||
463 | /* Adjust x1 and y to viewport */ | ||
464 | x1 += current_vp->x; | ||
465 | x2 += current_vp->x; | ||
466 | y += current_vp->y; | ||
467 | |||
468 | #if defined(HAVE_VIEWPORT_CLIP) | ||
469 | /********************* Viewport on screen clipping ********************/ | ||
470 | /* nothing to draw? */ | ||
471 | if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH) | ||
472 | || (x2 < 0)) | ||
473 | return; | ||
474 | |||
475 | /* clipping */ | ||
476 | if (x1 < 0) | ||
477 | x1 = 0; | ||
478 | if (x2 >= LCD_WIDTH) | ||
479 | x2 = LCD_WIDTH-1; | ||
480 | #endif | ||
429 | 481 | ||
430 | dst = LCDADDR(x1 + current_vp->x, y + current_vp->y); | 482 | dst = LCDADDR(x1 , y ); |
431 | dst_end = dst + (x2 - x1) * LCD_HEIGHT; | 483 | dst_end = dst + (x2 - x1) * LCD_HEIGHT; |
432 | 484 | ||
433 | do | 485 | do |
@@ -454,12 +506,39 @@ void lcd_vline(int x, int y1, int y2) | |||
454 | y2 = y; | 506 | y2 = y; |
455 | } | 507 | } |
456 | 508 | ||
509 | /******************** In viewport clipping **********************/ | ||
457 | /* nothing to draw? */ | 510 | /* nothing to draw? */ |
458 | if (((unsigned)x >= (unsigned)current_vp->width) || | 511 | if (((unsigned)x >= (unsigned)current_vp->width) || |
459 | (y1 >= current_vp->height) || | 512 | (y1 >= current_vp->height) || |
460 | (y2 < 0)) | 513 | (y2 < 0)) |
461 | return; | 514 | return; |
462 | 515 | ||
516 | if (y1 < 0) | ||
517 | y1 = 0; | ||
518 | if (y2 >= current_vp->height) | ||
519 | y2 = current_vp->height-1; | ||
520 | |||
521 | /* adjust for viewport */ | ||
522 | x += current_vp->x; | ||
523 | y1 += current_vp->y; | ||
524 | y2 += current_vp->y; | ||
525 | |||
526 | #if defined(HAVE_VIEWPORT_CLIP) | ||
527 | /********************* Viewport on screen clipping ********************/ | ||
528 | /* nothing to draw? */ | ||
529 | if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT) | ||
530 | || (y2 < 0)) | ||
531 | return; | ||
532 | |||
533 | /* clipping */ | ||
534 | if (y1 < 0) | ||
535 | y1 = 0; | ||
536 | if (y2 >= LCD_HEIGHT) | ||
537 | y2 = LCD_HEIGHT-1; | ||
538 | #endif | ||
539 | |||
540 | height = y2 - y1 + 1; | ||
541 | |||
463 | /* drawmode and optimisation */ | 542 | /* drawmode and optimisation */ |
464 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 543 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
465 | { | 544 | { |
@@ -485,18 +564,6 @@ void lcd_vline(int x, int y1, int y2) | |||
485 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 564 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) |
486 | return; | 565 | return; |
487 | 566 | ||
488 | /* clipping */ | ||
489 | if (y1 < 0) | ||
490 | y1 = 0; | ||
491 | if (y2 >= current_vp->height) | ||
492 | y2 = current_vp->height-1; | ||
493 | |||
494 | height = y2 - y1 + 1; | ||
495 | |||
496 | /* Adjust y1 and x to viewport */ | ||
497 | y1 += current_vp->y; | ||
498 | x += current_vp->x; | ||
499 | |||
500 | dst = LCDADDR(x, y1); | 567 | dst = LCDADDR(x, y1); |
501 | 568 | ||
502 | switch (fillopt) | 569 | switch (fillopt) |
@@ -541,11 +608,55 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
541 | enum fill_opt fillopt = OPT_NONE; | 608 | enum fill_opt fillopt = OPT_NONE; |
542 | fb_data *dst, *dst_end; | 609 | fb_data *dst, *dst_end; |
543 | 610 | ||
611 | /******************** In viewport clipping **********************/ | ||
544 | /* nothing to draw? */ | 612 | /* nothing to draw? */ |
545 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 613 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
546 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 614 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
547 | return; | 615 | return; |
548 | 616 | ||
617 | if (x < 0) | ||
618 | { | ||
619 | width += x; | ||
620 | x = 0; | ||
621 | } | ||
622 | if (y < 0) | ||
623 | { | ||
624 | height += y; | ||
625 | y = 0; | ||
626 | } | ||
627 | if (x + width > current_vp->width) | ||
628 | width = current_vp->width - x; | ||
629 | if (y + height > current_vp->height) | ||
630 | height = current_vp->height - y; | ||
631 | |||
632 | /* adjust for viewport */ | ||
633 | x += current_vp->x; | ||
634 | y += current_vp->y; | ||
635 | |||
636 | #if defined(HAVE_VIEWPORT_CLIP) | ||
637 | /********************* Viewport on screen clipping ********************/ | ||
638 | /* nothing to draw? */ | ||
639 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
640 | || (x + width <= 0) || (y + height <= 0)) | ||
641 | return; | ||
642 | |||
643 | /* clip image in viewport in screen */ | ||
644 | if (x < 0) | ||
645 | { | ||
646 | width += x; | ||
647 | x = 0; | ||
648 | } | ||
649 | if (y < 0) | ||
650 | { | ||
651 | height += y; | ||
652 | y = 0; | ||
653 | } | ||
654 | if (x + width > LCD_WIDTH) | ||
655 | width = LCD_WIDTH - x; | ||
656 | if (y + height > LCD_HEIGHT) | ||
657 | height = LCD_HEIGHT - y; | ||
658 | #endif | ||
659 | |||
549 | /* drawmode and optimisation */ | 660 | /* drawmode and optimisation */ |
550 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 661 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
551 | { | 662 | { |
@@ -571,23 +682,7 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
571 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 682 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) |
572 | return; | 683 | return; |
573 | 684 | ||
574 | /* clipping */ | 685 | dst = LCDADDR(x, y); |
575 | if (x < 0) | ||
576 | { | ||
577 | width += x; | ||
578 | x = 0; | ||
579 | } | ||
580 | if (y < 0) | ||
581 | { | ||
582 | height += y; | ||
583 | y = 0; | ||
584 | } | ||
585 | if (x + width > current_vp->width) | ||
586 | width = current_vp->width - x; | ||
587 | if (y + height > current_vp->height) | ||
588 | height = current_vp->height - y; | ||
589 | |||
590 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); | ||
591 | dst_end = dst + width * LCD_HEIGHT; | 686 | dst_end = dst + width * LCD_HEIGHT; |
592 | 687 | ||
593 | do | 688 | do |
@@ -641,12 +736,12 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
641 | unsigned dmask = 0x100; /* bit 8 == sentinel */ | 736 | unsigned dmask = 0x100; /* bit 8 == sentinel */ |
642 | int drmode = current_vp->drawmode; | 737 | int drmode = current_vp->drawmode; |
643 | 738 | ||
739 | /******************** Image in viewport clipping **********************/ | ||
644 | /* nothing to draw? */ | 740 | /* nothing to draw? */ |
645 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 741 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
646 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 742 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
647 | return; | 743 | return; |
648 | 744 | ||
649 | /* clipping */ | ||
650 | if (x < 0) | 745 | if (x < 0) |
651 | { | 746 | { |
652 | width += x; | 747 | width += x; |
@@ -663,11 +758,41 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
663 | width = current_vp->width - x; | 758 | width = current_vp->width - x; |
664 | if (y + height > current_vp->height) | 759 | if (y + height > current_vp->height) |
665 | height = current_vp->height - y; | 760 | height = current_vp->height - y; |
761 | |||
762 | /* adjust for viewport */ | ||
763 | x += current_vp->x; | ||
764 | y += current_vp->y; | ||
765 | |||
766 | #if defined(HAVE_VIEWPORT_CLIP) | ||
767 | /********************* Viewport on screen clipping ********************/ | ||
768 | /* nothing to draw? */ | ||
769 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
770 | || (x + width <= 0) || (y + height <= 0)) | ||
771 | return; | ||
772 | |||
773 | /* clip image in viewport in screen */ | ||
774 | if (x < 0) | ||
775 | { | ||
776 | width += x; | ||
777 | src_x -= x; | ||
778 | x = 0; | ||
779 | } | ||
780 | if (y < 0) | ||
781 | { | ||
782 | height += y; | ||
783 | src_y -= y; | ||
784 | y = 0; | ||
785 | } | ||
786 | if (x + width > LCD_WIDTH) | ||
787 | width = LCD_WIDTH - x; | ||
788 | if (y + height > LCD_HEIGHT) | ||
789 | height = LCD_HEIGHT - y; | ||
790 | #endif | ||
666 | 791 | ||
667 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 792 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
668 | src_y &= 7; | 793 | src_y &= 7; |
669 | src_end = src + width; | 794 | src_end = src + width; |
670 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); | 795 | dst = LCDADDR(x, y); |
671 | dst_end = dst + height; | 796 | dst_end = dst + height; |
672 | 797 | ||
673 | if (drmode & DRMODE_INVERSEVID) | 798 | if (drmode & DRMODE_INVERSEVID) |
@@ -793,12 +918,12 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
793 | { | 918 | { |
794 | fb_data *dst, *dst_end; | 919 | fb_data *dst, *dst_end; |
795 | 920 | ||
921 | /******************** Image in viewport clipping **********************/ | ||
796 | /* nothing to draw? */ | 922 | /* nothing to draw? */ |
797 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 923 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
798 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 924 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
799 | return; | 925 | return; |
800 | 926 | ||
801 | /* clipping */ | ||
802 | if (x < 0) | 927 | if (x < 0) |
803 | { | 928 | { |
804 | width += x; | 929 | width += x; |
@@ -811,13 +936,44 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
811 | src_y -= y; | 936 | src_y -= y; |
812 | y = 0; | 937 | y = 0; |
813 | } | 938 | } |
939 | |||
814 | if (x + width > current_vp->width) | 940 | if (x + width > current_vp->width) |
815 | width = current_vp->width - x; | 941 | width = current_vp->width - x; |
816 | if (y + height > current_vp->height) | 942 | if (y + height > current_vp->height) |
817 | height = current_vp->height - y; | 943 | height = current_vp->height - y; |
944 | |||
945 | /* adjust for viewport */ | ||
946 | x += current_vp->x; | ||
947 | y += current_vp->y; | ||
948 | |||
949 | #if defined(HAVE_VIEWPORT_CLIP) | ||
950 | /********************* Viewport on screen clipping ********************/ | ||
951 | /* nothing to draw? */ | ||
952 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
953 | || (x + width <= 0) || (y + height <= 0)) | ||
954 | return; | ||
955 | |||
956 | /* clip image in viewport in screen */ | ||
957 | if (x < 0) | ||
958 | { | ||
959 | width += x; | ||
960 | src_x -= x; | ||
961 | x = 0; | ||
962 | } | ||
963 | if (y < 0) | ||
964 | { | ||
965 | height += y; | ||
966 | src_y -= y; | ||
967 | y = 0; | ||
968 | } | ||
969 | if (x + width > LCD_WIDTH) | ||
970 | width = LCD_WIDTH - x; | ||
971 | if (y + height > LCD_HEIGHT) | ||
972 | height = LCD_HEIGHT - y; | ||
973 | #endif | ||
818 | 974 | ||
819 | src += stride * src_x + src_y; /* move starting point */ | 975 | src += stride * src_x + src_y; /* move starting point */ |
820 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); | 976 | dst = LCDADDR(x, y); |
821 | dst_end = dst + width * LCD_HEIGHT; | 977 | dst_end = dst + width * LCD_HEIGHT; |
822 | 978 | ||
823 | do | 979 | do |
@@ -843,13 +999,13 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
843 | int y, int width, int height) | 999 | int y, int width, int height) |
844 | { | 1000 | { |
845 | fb_data *dst, *dst_end; | 1001 | fb_data *dst, *dst_end; |
846 | 1002 | ||
1003 | /******************** Image in viewport clipping **********************/ | ||
847 | /* nothing to draw? */ | 1004 | /* nothing to draw? */ |
848 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 1005 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
849 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 1006 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
850 | return; | 1007 | return; |
851 | 1008 | ||
852 | /* clipping */ | ||
853 | if (x < 0) | 1009 | if (x < 0) |
854 | { | 1010 | { |
855 | width += x; | 1011 | width += x; |
@@ -862,13 +1018,44 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
862 | src_y -= y; | 1018 | src_y -= y; |
863 | y = 0; | 1019 | y = 0; |
864 | } | 1020 | } |
1021 | |||
865 | if (x + width > current_vp->width) | 1022 | if (x + width > current_vp->width) |
866 | width = current_vp->width - x; | 1023 | width = current_vp->width - x; |
867 | if (y + height > current_vp->height) | 1024 | if (y + height > current_vp->height) |
868 | height = current_vp->height - y; | 1025 | height = current_vp->height - y; |
1026 | |||
1027 | /* adjust for viewport */ | ||
1028 | x += current_vp->x; | ||
1029 | y += current_vp->y; | ||
1030 | |||
1031 | #if defined(HAVE_VIEWPORT_CLIP) | ||
1032 | /********************* Viewport on screen clipping ********************/ | ||
1033 | /* nothing to draw? */ | ||
1034 | if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
1035 | || (x + width <= 0) || (y + height <= 0)) | ||
1036 | return; | ||
1037 | |||
1038 | /* clip image in viewport in screen */ | ||
1039 | if (x < 0) | ||
1040 | { | ||
1041 | width += x; | ||
1042 | src_x -= x; | ||
1043 | x = 0; | ||
1044 | } | ||
1045 | if (y < 0) | ||
1046 | { | ||
1047 | height += y; | ||
1048 | src_y -= y; | ||
1049 | y = 0; | ||
1050 | } | ||
1051 | if (x + width > LCD_WIDTH) | ||
1052 | width = LCD_WIDTH - x; | ||
1053 | if (y + height > LCD_HEIGHT) | ||
1054 | height = LCD_HEIGHT - y; | ||
1055 | #endif | ||
869 | 1056 | ||
870 | src += stride * src_x + src_y; /* move starting point */ | 1057 | src += stride * src_x + src_y; /* move starting point */ |
871 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); | 1058 | dst = LCDADDR(x, y); |
872 | dst_end = dst + width * LCD_HEIGHT; | 1059 | dst_end = dst + width * LCD_HEIGHT; |
873 | 1060 | ||
874 | do | 1061 | do |