summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-horz.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-09-26 08:37:00 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-10-09 22:07:44 +0100
commit4b8fe8acd1c079e75bb9229791170c549188fc08 (patch)
treee3f3a8ab80a6a603488781a933bb16ba90e8a68e /firmware/drivers/lcd-2bit-horz.c
parent70d5b2cd45b29e64ab17b04d995dce1080d7fca9 (diff)
downloadrockbox-4b8fe8acd1c079e75bb9229791170c549188fc08.tar.gz
rockbox-4b8fe8acd1c079e75bb9229791170c549188fc08.zip
lcd: Consolidate in-viewport clipping routines
In-viewport clipping code is duplicated across 8 files, making it a chore to change anything related to clipping; refactor the clipping logic into dedicated functions. Change-Id: I4ab20bb3c59b0406098d0c7d23833025f17a320a
Diffstat (limited to 'firmware/drivers/lcd-2bit-horz.c')
-rw-r--r--firmware/drivers/lcd-2bit-horz.c144
1 files changed, 17 insertions, 127 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 1bc489247c..37125679ad 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -89,6 +89,8 @@ static void *lcd_frameaddress_default(int x, int y)
89 return fb->fb_ptr + element;/*(element % fb->elems);*/ 89 return fb->fb_ptr + element;/*(element % fb->elems);*/
90} 90}
91 91
92#include "lcd-bitmap-common.c"
93
92/* LCD init */ 94/* LCD init */
93void lcd_init(void) 95void lcd_init(void)
94{ 96{
@@ -418,10 +420,8 @@ void lcd_clear_viewport(void)
418/* Set a single pixel */ 420/* Set a single pixel */
419void lcd_drawpixel(int x, int y) 421void lcd_drawpixel(int x, int y)
420{ 422{
421 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) 423 if (lcd_clip_viewport_pixel(&x, &y))
422 && ((unsigned)y < (unsigned)lcd_current_viewport->height) 424 lcd_pixelfuncs[lcd_current_viewport->drawmode](x, y);
423 )
424 lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y);
425} 425}
426 426
427/* Draw a line */ 427/* Draw a line */
@@ -433,6 +433,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
433 int d, dinc1, dinc2; 433 int d, dinc1, dinc2;
434 int x, xinc1, xinc2; 434 int x, xinc1, xinc2;
435 int y, yinc1, yinc2; 435 int y, yinc1, yinc2;
436 int x_vp, y_vp, w_vp, h_vp;
436 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode]; 437 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
437 438
438 deltay = abs(y2 - y1); 439 deltay = abs(y2 - y1);
@@ -487,12 +488,15 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
487 x = x1; 488 x = x1;
488 y = y1; 489 y = y1;
489 490
491 x_vp = lcd_current_viewport->x;
492 y_vp = lcd_current_viewport->y;
493 w_vp = lcd_current_viewport->width;
494 h_vp = lcd_current_viewport->height;
495
490 for (i = 0; i < numpixels; i++) 496 for (i = 0; i < numpixels; i++)
491 { 497 {
492 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) 498 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
493 && ((unsigned)y < (unsigned)lcd_current_viewport->height) 499 pfunc(x + x_vp, y + y_vp);
494 )
495 pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y);
496 500
497 if (d < 0) 501 if (d < 0)
498 { 502 {
@@ -517,30 +521,9 @@ void lcd_hline(int x1, int x2, int y)
517 unsigned mask, mask_right; 521 unsigned mask, mask_right;
518 lcd_blockfunc_type *bfunc; 522 lcd_blockfunc_type *bfunc;
519 523
520 /* direction flip */ 524 if (!lcd_clip_viewport_hline(&x1, &x2, &y))
521 if (x2 < x1)
522 {
523 nx = x1;
524 x1 = x2;
525 x2 = nx;
526 }
527
528 /******************** In viewport clipping **********************/
529 /* nothing to draw? */
530 if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width)
531 || (x2 < 0))
532 return; 525 return;
533 526
534 if (x1 < 0)
535 x1 = 0;
536 if (x2 >= lcd_current_viewport->width)
537 x2 = lcd_current_viewport->width-1;
538
539 /* adjust to viewport */
540 x1 += lcd_current_viewport->x;
541 x2 += lcd_current_viewport->x;
542 y += lcd_current_viewport->y;
543
544 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; 527 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
545 dst = FBADDR(x1>>2,y); 528 dst = FBADDR(x1>>2,y);
546 nx = x2 - (x1 & ~3); 529 nx = x2 - (x1 & ~3);
@@ -559,36 +542,14 @@ void lcd_hline(int x1, int x2, int y)
559/* Draw a vertical line (optimised) */ 542/* Draw a vertical line (optimised) */
560void lcd_vline(int x, int y1, int y2) 543void lcd_vline(int x, int y1, int y2)
561{ 544{
562 int y;
563 unsigned char *dst, *dst_end; 545 unsigned char *dst, *dst_end;
564 int stride_dst; 546 int stride_dst;
565 unsigned mask; 547 unsigned mask;
566 lcd_blockfunc_type *bfunc; 548 lcd_blockfunc_type *bfunc;
567 549
568 /* direction flip */ 550 if (!lcd_clip_viewport_vline(&x, &y1, &y2))
569 if (y2 < y1)
570 {
571 y = y1;
572 y1 = y2;
573 y2 = y;
574 }
575
576 /******************** In viewport clipping **********************/
577 /* nothing to draw? */
578 if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height)
579 || (y2 < 0))
580 return; 551 return;
581 552
582 if (y1 < 0)
583 y1 = 0;
584 if (y2 >= lcd_current_viewport->height)
585 y2 = lcd_current_viewport->height-1;
586
587 /* adjust for viewport */
588 y1 += lcd_current_viewport->y;
589 y2 += lcd_current_viewport->y;
590 x += lcd_current_viewport->x;
591
592 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; 553 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
593 dst = FBADDR(x>>2,y1); 554 dst = FBADDR(x>>2,y1);
594 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); 555 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
@@ -627,31 +588,9 @@ void lcd_fillrect(int x, int y, int width, int height)
627 unsigned mask, mask_right; 588 unsigned mask, mask_right;
628 lcd_blockfunc_type *bfunc; 589 lcd_blockfunc_type *bfunc;
629 590
630 /******************** In viewport clipping **********************/ 591 if (!lcd_clip_viewport_rect(&x, &y, &width, &height, NULL, NULL))
631 /* nothing to draw? */
632 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || (y >= lcd_current_viewport->height)
633 || (x + width <= 0) || (y + height <= 0))
634 return; 592 return;
635 593
636 if (x < 0)
637 {
638 width += x;
639 x = 0;
640 }
641 if (y < 0)
642 {
643 height += y;
644 y = 0;
645 }
646 if (x + width > lcd_current_viewport->width)
647 width = lcd_current_viewport->width - x;
648 if (y + height > lcd_current_viewport->height)
649 height = lcd_current_viewport->height - y;
650
651 /* adjust for viewport */
652 x += lcd_current_viewport->x;
653 y += lcd_current_viewport->y;
654
655 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode]; 594 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
656 dst = FBADDR(x>>2,y); 595 dst = FBADDR(x>>2,y);
657 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0); 596 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
@@ -706,32 +645,9 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
706 unsigned dst_mask; 645 unsigned dst_mask;
707 int drmode = lcd_current_viewport->drawmode; 646 int drmode = lcd_current_viewport->drawmode;
708 647
709 /******************** Image in viewport clipping **********************/ 648 if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y))
710 /* nothing to draw? */
711 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
712 (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
713 return; 649 return;
714 650
715 if (x < 0)
716 {
717 width += x;
718 src_x -= x;
719 x = 0;
720 }
721 if (y < 0)
722 {
723 height += y;
724 src_y -= y;
725 y = 0;
726 }
727 if (x + width > lcd_current_viewport->width)
728 width = lcd_current_viewport->width - x;
729 if (y + height > lcd_current_viewport->height)
730 height = lcd_current_viewport->height - y;
731
732 x += lcd_current_viewport->x; /* adjust for viewport */
733 y += lcd_current_viewport->y; /* adjust for viewport */
734
735 src += stride * (src_y >> 3) + src_x; /* move starting point */ 651 src += stride * (src_y >> 3) + src_x; /* move starting point */
736 src_y &= 7; 652 src_y &= 7;
737 src_end = src + width; 653 src_end = src + width;
@@ -894,33 +810,9 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
894 int stride_dst; 810 int stride_dst;
895 unsigned mask, mask_right; 811 unsigned mask, mask_right;
896 812
897 /******************** Image in viewport clipping **********************/ 813 if (!lcd_clip_viewport_rect(&x, &y, &width, &height, &src_x, &src_y))
898 /* nothing to draw? */
899 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
900 (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
901 return; 814 return;
902 815
903 if (x < 0)
904 {
905 width += x;
906 src_x -= x;
907 x = 0;
908 }
909 if (y < 0)
910 {
911 height += y;
912 src_y -= y;
913 y = 0;
914 }
915 if (x + width > lcd_current_viewport->width)
916 width = lcd_current_viewport->width - x;
917 if (y + height > lcd_current_viewport->height)
918 height = lcd_current_viewport->height - y;
919
920 /* adjust for viewport */
921 x += lcd_current_viewport->x;
922 y += lcd_current_viewport->y;
923
924 stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */ 816 stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */
925 817
926 src += stride * src_y + (src_x >> 2); /* move starting point */ 818 src += stride * src_y + (src_x >> 2); /* move starting point */
@@ -971,5 +863,3 @@ void lcd_bitmap(const unsigned char *src, int x, int y, int width, int height)
971{ 863{
972 lcd_bitmap_part(src, 0, 0, width, x, y, width, height); 864 lcd_bitmap_part(src, 0, 0, width, x, y, width, height);
973} 865}
974
975#include "lcd-bitmap-common.c"