summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r--firmware/drivers/lcd-16bit.c315
1 files changed, 248 insertions, 67 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 6d6a3b2104..d8405235f7 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -85,6 +85,28 @@ void lcd_set_viewport(struct viewport* vp)
85 current_vp = &default_vp; 85 current_vp = &default_vp;
86 else 86 else
87 current_vp = vp; 87 current_vp = vp;
88
89#if defined(SIMULATOR)
90 /* Force the viewport to be within bounds. If this happens it should
91 * be considered an error - the viewport will not draw as it might be
92 * expected.
93 */
94 if((unsigned) current_vp->x > (unsigned) LCD_WIDTH
95 || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT
96 || current_vp->x + current_vp->width > LCD_WIDTH
97 || current_vp->y + current_vp->height > LCD_HEIGHT)
98 {
99#if !defined(HAVE_VIEWPORT_CLIP)
100 DEBUGF("ERROR: "
101#else
102 DEBUGF("NOTE: "
103#endif
104 "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n",
105 current_vp->x, current_vp->y,
106 current_vp->width, current_vp->height);
107 }
108
109#endif
88} 110}
89 111
90void lcd_update_viewport(void) 112void lcd_update_viewport(void)
@@ -305,8 +327,13 @@ void lcd_clear_display(void)
305/* Set a single pixel */ 327/* Set a single pixel */
306void lcd_drawpixel(int x, int y) 328void lcd_drawpixel(int x, int y)
307{ 329{
308 if (((unsigned)x < (unsigned)current_vp->width) && 330 if ( ((unsigned)x < (unsigned)current_vp->width)
309 ((unsigned)y < (unsigned)current_vp->height)) 331 && ((unsigned)y < (unsigned)current_vp->height)
332#if defined(HAVE_VIEWPORT_CLIP)
333 && ((unsigned)x < (unsigned)LCD_WIDTH)
334 && ((unsigned)y < (unsigned)LCD_HEIGHT)
335#endif
336 )
310 lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y)); 337 lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y));
311} 338}
312 339
@@ -375,7 +402,13 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
375 402
376 for (i = 0; i < numpixels; i++) 403 for (i = 0; i < numpixels; i++)
377 { 404 {
378 if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height)) 405 if ( ((unsigned)x < (unsigned)current_vp->width)
406 && ((unsigned)y < (unsigned)current_vp->height)
407#if defined(HAVE_VIEWPORT_CLIP)
408 && ((unsigned)x < (unsigned)LCD_WIDTH)
409 && ((unsigned)y < (unsigned)LCD_HEIGHT)
410#endif
411 )
379 pfunc(LCDADDR(x + current_vp->x, y + current_vp->y)); 412 pfunc(LCDADDR(x + current_vp->x, y + current_vp->y));
380 413
381 if (d < 0) 414 if (d < 0)
@@ -409,11 +442,38 @@ void lcd_hline(int x1, int x2, int y)
409 x2 = x; 442 x2 = x;
410 } 443 }
411 444
445 /******************** In viewport clipping **********************/
412 /* nothing to draw? */ 446 /* nothing to draw? */
413 if (((unsigned)y >= (unsigned)current_vp->height) || 447 if (((unsigned)y >= (unsigned)current_vp->height) ||
414 (x1 >= current_vp->width) || 448 (x1 >= current_vp->width) ||
415 (x2 < 0)) 449 (x2 < 0))
416 return; 450 return;
451
452 if (x1 < 0)
453 x1 = 0;
454 if (x2 >= current_vp->width)
455 x2 = current_vp->width-1;
456
457 /* Adjust x1 and y to viewport */
458 x1 += current_vp->x;
459 x2 += current_vp->x;
460 y += current_vp->y;
461
462#if defined(HAVE_VIEWPORT_CLIP)
463 /********************* Viewport on screen clipping ********************/
464 /* nothing to draw? */
465 if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH)
466 || (x2 < 0))
467 return;
468
469 /* clipping */
470 if (x1 < 0)
471 x1 = 0;
472 if (x2 >= LCD_WIDTH)
473 x2 = LCD_WIDTH-1;
474#endif
475
476 width = x2 - x1 + 1;
417 477
418 /* drawmode and optimisation */ 478 /* drawmode and optimisation */
419 if (current_vp->drawmode & DRMODE_INVERSEVID) 479 if (current_vp->drawmode & DRMODE_INVERSEVID)
@@ -440,18 +500,6 @@ void lcd_hline(int x1, int x2, int y)
440 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) 500 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
441 return; 501 return;
442 502
443 /* clipping */
444 if (x1 < 0)
445 x1 = 0;
446 if (x2 >= current_vp->width)
447 x2 = current_vp->width-1;
448
449 width = x2 - x1 + 1;
450
451 /* Adjust x1 and y to viewport */
452 x1 += current_vp->x;
453 y += current_vp->y;
454
455 dst = LCDADDR(x1, y); 503 dst = LCDADDR(x1, y);
456 504
457 switch (fillopt) 505 switch (fillopt)
@@ -489,19 +537,38 @@ void lcd_vline(int x, int y1, int y2)
489 y2 = y; 537 y2 = y;
490 } 538 }
491 539
540 /******************** In viewport clipping **********************/
492 /* nothing to draw? */ 541 /* nothing to draw? */
493 if (((unsigned)x >= (unsigned)current_vp->width) || 542 if (((unsigned)x >= (unsigned)current_vp->width) ||
494 (y1 >= current_vp->height) || 543 (y1 >= current_vp->height) ||
495 (y2 < 0)) 544 (y2 < 0))
496 return; 545 return;
497 546
498 /* clipping */
499 if (y1 < 0) 547 if (y1 < 0)
500 y1 = 0; 548 y1 = 0;
501 if (y2 >= current_vp->height) 549 if (y2 >= current_vp->height)
502 y2 = current_vp->height-1; 550 y2 = current_vp->height-1;
551
552 /* adjust for viewport */
553 x += current_vp->x;
554 y1 += current_vp->y;
555 y2 += current_vp->y;
556
557#if defined(HAVE_VIEWPORT_CLIP)
558 /********************* Viewport on screen clipping ********************/
559 /* nothing to draw? */
560 if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT)
561 || (y2 < 0))
562 return;
563
564 /* clipping */
565 if (y1 < 0)
566 y1 = 0;
567 if (y2 >= LCD_HEIGHT)
568 y2 = LCD_HEIGHT-1;
569#endif
503 570
504 dst = LCDADDR(x + current_vp->x, y1 + current_vp->y); 571 dst = LCDADDR(x , y1);
505 dst_end = dst + (y2 - y1) * LCD_WIDTH; 572 dst_end = dst + (y2 - y1) * LCD_WIDTH;
506 573
507 do 574 do
@@ -534,11 +601,55 @@ void lcd_fillrect(int x, int y, int width, int height)
534 enum fill_opt fillopt = OPT_NONE; 601 enum fill_opt fillopt = OPT_NONE;
535 fb_data *dst, *dst_end; 602 fb_data *dst, *dst_end;
536 603
604 /******************** In viewport clipping **********************/
537 /* nothing to draw? */ 605 /* nothing to draw? */
538 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 606 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
539 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 607 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
540 return; 608 return;
541 609
610 if (x < 0)
611 {
612 width += x;
613 x = 0;
614 }
615 if (y < 0)
616 {
617 height += y;
618 y = 0;
619 }
620 if (x + width > current_vp->width)
621 width = current_vp->width - x;
622 if (y + height > current_vp->height)
623 height = current_vp->height - y;
624
625 /* adjust for viewport */
626 x += current_vp->x;
627 y += current_vp->y;
628
629#if defined(HAVE_VIEWPORT_CLIP)
630 /********************* Viewport on screen clipping ********************/
631 /* nothing to draw? */
632 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
633 || (x + width <= 0) || (y + height <= 0))
634 return;
635
636 /* clip image in viewport in screen */
637 if (x < 0)
638 {
639 width += x;
640 x = 0;
641 }
642 if (y < 0)
643 {
644 height += y;
645 y = 0;
646 }
647 if (x + width > LCD_WIDTH)
648 width = LCD_WIDTH - x;
649 if (y + height > LCD_HEIGHT)
650 height = LCD_HEIGHT - y;
651#endif
652
542 /* drawmode and optimisation */ 653 /* drawmode and optimisation */
543 if (current_vp->drawmode & DRMODE_INVERSEVID) 654 if (current_vp->drawmode & DRMODE_INVERSEVID)
544 { 655 {
@@ -564,23 +675,7 @@ void lcd_fillrect(int x, int y, int width, int height)
564 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) 675 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
565 return; 676 return;
566 677
567 /* clipping */ 678 dst = LCDADDR(x, y);
568 if (x < 0)
569 {
570 width += x;
571 x = 0;
572 }
573 if (y < 0)
574 {
575 height += y;
576 y = 0;
577 }
578 if (x + width > current_vp->width)
579 width = current_vp->width - x;
580 if (y + height > current_vp->height)
581 height = current_vp->height - y;
582
583 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
584 dst_end = dst + height * LCD_WIDTH; 679 dst_end = dst + height * LCD_WIDTH;
585 680
586 do 681 do
@@ -634,12 +729,12 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
634 unsigned dmask = 0x100; /* bit 8 == sentinel */ 729 unsigned dmask = 0x100; /* bit 8 == sentinel */
635 int drmode = current_vp->drawmode; 730 int drmode = current_vp->drawmode;
636 731
732 /******************** Image in viewport clipping **********************/
637 /* nothing to draw? */ 733 /* nothing to draw? */
638 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 734 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
639 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 735 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
640 return; 736 return;
641 737
642 /* clipping */
643 if (x < 0) 738 if (x < 0)
644 { 739 {
645 width += x; 740 width += x;
@@ -656,11 +751,41 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
656 width = current_vp->width - x; 751 width = current_vp->width - x;
657 if (y + height > current_vp->height) 752 if (y + height > current_vp->height)
658 height = current_vp->height - y; 753 height = current_vp->height - y;
754
755 /* adjust for viewport */
756 x += current_vp->x;
757 y += current_vp->y;
758
759#if defined(HAVE_VIEWPORT_CLIP)
760 /********************* Viewport on screen clipping ********************/
761 /* nothing to draw? */
762 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
763 || (x + width <= 0) || (y + height <= 0))
764 return;
765
766 /* clip image in viewport in screen */
767 if (x < 0)
768 {
769 width += x;
770 src_x -= x;
771 x = 0;
772 }
773 if (y < 0)
774 {
775 height += y;
776 src_y -= y;
777 y = 0;
778 }
779 if (x + width > LCD_WIDTH)
780 width = LCD_WIDTH - x;
781 if (y + height > LCD_HEIGHT)
782 height = LCD_HEIGHT - y;
783#endif
659 784
660 src += stride * (src_y >> 3) + src_x; /* move starting point */ 785 src += stride * (src_y >> 3) + src_x; /* move starting point */
661 src_y &= 7; 786 src_y &= 7;
662 src_end = src + width; 787 src_end = src + width;
663 dst = LCDADDR(current_vp->x + x, current_vp->y + y); 788 dst = LCDADDR(x, y);
664 dst_end = dst + height * LCD_WIDTH; 789 dst_end = dst + height * LCD_WIDTH;
665 790
666 if (drmode & DRMODE_INVERSEVID) 791 if (drmode & DRMODE_INVERSEVID)
@@ -784,34 +909,62 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
784{ 909{
785 fb_data *dst; 910 fb_data *dst;
786 911
787 if (x + width > current_vp->width) 912 /******************** Image in viewport clipping **********************/
788 width = current_vp->width - x; /* Clip right */ 913 /* nothing to draw? */
789 914 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
790 if (x < 0) /* Clip left */ 915 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
916 return;
917
918 if (x < 0)
791 { 919 {
792 width += x; 920 width += x;
793 src_x -= x; 921 src_x -= x;
794 x = 0; 922 x = 0;
795 } 923 }
796 924 if (y < 0)
797 if (width <= 0) 925 {
798 return; /* nothing left to do */ 926 height += y;
799 927 src_y -= y;
928 y = 0;
929 }
930
931 if (x + width > current_vp->width)
932 width = current_vp->width - x;
800 if (y + height > current_vp->height) 933 if (y + height > current_vp->height)
801 height = current_vp->height - y; /* Clip bottom */ 934 height = current_vp->height - y;
802 935
803 if (y < 0) /* Clip top */ 936 /* adjust for viewport */
937 x += current_vp->x;
938 y += current_vp->y;
939
940#if defined(HAVE_VIEWPORT_CLIP)
941 /********************* Viewport on screen clipping ********************/
942 /* nothing to draw? */
943 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
944 || (x + width <= 0) || (y + height <= 0))
945 return;
946
947 /* clip image in viewport in screen */
948 if (x < 0)
949 {
950 width += x;
951 src_x -= x;
952 x = 0;
953 }
954 if (y < 0)
804 { 955 {
805 height += y; 956 height += y;
806 src_y -= y; 957 src_y -= y;
807 y = 0; 958 y = 0;
808 } 959 }
809 960 if (x + width > LCD_WIDTH)
810 if (height <= 0) 961 width = LCD_WIDTH - x;
811 return; /* nothing left to do */ 962 if (y + height > LCD_HEIGHT)
812 963 height = LCD_HEIGHT - y;
964#endif
965
813 src += stride * src_y + src_x; /* move starting point */ 966 src += stride * src_y + src_x; /* move starting point */
814 dst = LCDADDR(current_vp->x + x, current_vp->y + y); 967 dst = LCDADDR(x, y);
815 968
816 do 969 do
817 { 970 {
@@ -836,34 +989,62 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
836 fb_data *dst; 989 fb_data *dst;
837 unsigned fg = current_vp->fg_pattern; 990 unsigned fg = current_vp->fg_pattern;
838 991
839 if (x + width > current_vp->width) 992 /******************** Image in viewport clipping **********************/
840 width = current_vp->width - x; /* Clip right */ 993 /* nothing to draw? */
841 994 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
842 if (x < 0) /* Clip left */ 995 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
996 return;
997
998 if (x < 0)
843 { 999 {
844 width += x; 1000 width += x;
845 src_x -= x; 1001 src_x -= x;
846 x = 0; 1002 x = 0;
847 } 1003 }
848 1004 if (y < 0)
849 if (width <= 0) 1005 {
850 return; /* nothing left to do */ 1006 height += y;
851 1007 src_y -= y;
1008 y = 0;
1009 }
1010
1011 if (x + width > current_vp->width)
1012 width = current_vp->width - x;
852 if (y + height > current_vp->height) 1013 if (y + height > current_vp->height)
853 height = current_vp->height - y; /* Clip bottom */ 1014 height = current_vp->height - y;
854 1015
855 if (y < 0) /* Clip top */ 1016 /* adjust for viewport */
1017 x += current_vp->x;
1018 y += current_vp->y;
1019
1020#if defined(HAVE_VIEWPORT_CLIP)
1021 /********************* Viewport on screen clipping ********************/
1022 /* nothing to draw? */
1023 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
1024 || (x + width <= 0) || (y + height <= 0))
1025 return;
1026
1027 /* clip image in viewport in screen */
1028 if (x < 0)
1029 {
1030 width += x;
1031 src_x -= x;
1032 x = 0;
1033 }
1034 if (y < 0)
856 { 1035 {
857 height += y; 1036 height += y;
858 src_y -= y; 1037 src_y -= y;
859 y = 0; 1038 y = 0;
860 } 1039 }
861 1040 if (x + width > LCD_WIDTH)
862 if (height <= 0) 1041 width = LCD_WIDTH - x;
863 return; /* nothing left to do */ 1042 if (y + height > LCD_HEIGHT)
1043 height = LCD_HEIGHT - y;
1044#endif
864 1045
865 src += stride * src_y + src_x; /* move starting point */ 1046 src += stride * src_y + src_x; /* move starting point */
866 dst = LCDADDR(current_vp->x + x, current_vp->y + y); 1047 dst = LCDADDR(x, y);
867 1048
868#ifdef CPU_ARM 1049#ifdef CPU_ARM
869 { 1050 {