diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-09-26 08:37:00 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-10-09 22:07:44 +0100 |
commit | 4b8fe8acd1c079e75bb9229791170c549188fc08 (patch) | |
tree | e3f3a8ab80a6a603488781a933bb16ba90e8a68e /firmware/drivers/lcd-2bit-horz.c | |
parent | 70d5b2cd45b29e64ab17b04d995dce1080d7fca9 (diff) | |
download | rockbox-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.c | 144 |
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 */ |
93 | void lcd_init(void) | 95 | void lcd_init(void) |
94 | { | 96 | { |
@@ -418,10 +420,8 @@ void lcd_clear_viewport(void) | |||
418 | /* Set a single pixel */ | 420 | /* Set a single pixel */ |
419 | void lcd_drawpixel(int x, int y) | 421 | void 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) */ |
560 | void lcd_vline(int x, int y1, int y2) | 543 | void 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" | ||