summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit-vert.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-16bit-vert.c')
-rw-r--r--firmware/drivers/lcd-16bit-vert.c283
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
97void lcd_update_viewport(void) 119void lcd_update_viewport(void)
@@ -312,8 +334,13 @@ void lcd_clear_display(void)
312/* Set a single pixel */ 334/* Set a single pixel */
313void lcd_drawpixel(int x, int y) 335void 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