diff options
Diffstat (limited to 'apps/plugins/rockpaint.c')
-rw-r--r-- | apps/plugins/rockpaint.c | 182 |
1 files changed, 180 insertions, 2 deletions
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 0acbe41aaf..1fef0e9f5f 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c | |||
@@ -562,6 +562,180 @@ static void buffer_mono_bitmap_part( | |||
562 | } while( src < src_end ); | 562 | } while( src < src_end ); |
563 | } | 563 | } |
564 | 564 | ||
565 | /* draw alpha bitmap for anti-alias font */ | ||
566 | #define ALPHA_COLOR_FONT_DEPTH 2 | ||
567 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) | ||
568 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) | ||
569 | #define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH) | ||
570 | #define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH) | ||
571 | #ifdef CPU_ARM | ||
572 | #define BLEND_INIT do {} while (0) | ||
573 | #define BLEND_START(acc, color, alpha) \ | ||
574 | asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha)) | ||
575 | #define BLEND_CONT(acc, color, alpha) \ | ||
576 | asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha)) | ||
577 | #define BLEND_OUT(acc) do {} while (0) | ||
578 | #elif defined(CPU_COLDFIRE) | ||
579 | #define ALPHA_BITMAP_READ_WORDS | ||
580 | #define BLEND_INIT coldfire_set_macsr(EMAC_UNSIGNED) | ||
581 | #define BLEND_START(acc, color, alpha) \ | ||
582 | asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha)) | ||
583 | #define BLEND_CONT BLEND_START | ||
584 | #define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc)) | ||
585 | #else | ||
586 | #define BLEND_INIT do {} while (0) | ||
587 | #define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha)) | ||
588 | #define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha)) | ||
589 | #define BLEND_OUT(acc) do {} while (0) | ||
590 | #endif | ||
591 | |||
592 | /* Blend the given two colors */ | ||
593 | static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) | ||
594 | { | ||
595 | a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1); | ||
596 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | ||
597 | c1 = swap16(c1); | ||
598 | c2 = swap16(c2); | ||
599 | #endif | ||
600 | unsigned c1l = (c1 | (c1 << 16)) & 0x07e0f81f; | ||
601 | unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f; | ||
602 | unsigned p; | ||
603 | BLEND_START(p, c1l, a); | ||
604 | BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a); | ||
605 | BLEND_OUT(p); | ||
606 | p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f; | ||
607 | p |= (p >> 16); | ||
608 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | ||
609 | return swap16(p); | ||
610 | #else | ||
611 | return p; | ||
612 | #endif | ||
613 | } | ||
614 | |||
615 | static void buffer_alpha_bitmap_part( | ||
616 | fb_data *buf, int buf_width, int buf_height, | ||
617 | const unsigned char *src, int src_x, int src_y, | ||
618 | int stride, int x, int y, int width, int height ) | ||
619 | { | ||
620 | fb_data *dst; | ||
621 | unsigned fg_pattern = rb->lcd_get_foreground(); | ||
622 | |||
623 | /* nothing to draw? */ | ||
624 | if ((width <= 0) || (height <= 0) || (x >= buf_width) || | ||
625 | (y >= buf_height) || (x + width <= 0) || (y + height <= 0)) | ||
626 | return; | ||
627 | |||
628 | /* initialize blending */ | ||
629 | BLEND_INIT; | ||
630 | |||
631 | /* clipping */ | ||
632 | if (x < 0) | ||
633 | { | ||
634 | width += x; | ||
635 | src_x -= x; | ||
636 | x = 0; | ||
637 | } | ||
638 | if (y < 0) | ||
639 | { | ||
640 | height += y; | ||
641 | src_y -= y; | ||
642 | y = 0; | ||
643 | } | ||
644 | if (x + width > buf_width) | ||
645 | width = buf_width - x; | ||
646 | if (y + height > buf_height) | ||
647 | height = buf_height - y; | ||
648 | |||
649 | dst = buf + y*buf_width + x; | ||
650 | |||
651 | int col, row = height; | ||
652 | unsigned data, pixels; | ||
653 | unsigned skip_end = (stride - width); | ||
654 | unsigned skip_start = src_y * stride + src_x; | ||
655 | |||
656 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
657 | uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); | ||
658 | skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3); | ||
659 | src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD; | ||
660 | data = letoh32(*src_w++); | ||
661 | #else | ||
662 | src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE; | ||
663 | data = *src; | ||
664 | #endif | ||
665 | pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD; | ||
666 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | ||
667 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
668 | pixels = 8 - pixels; | ||
669 | #endif | ||
670 | |||
671 | do | ||
672 | { | ||
673 | col = width; | ||
674 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
675 | #define UPDATE_SRC_ALPHA do { \ | ||
676 | if (--pixels) \ | ||
677 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
678 | else \ | ||
679 | { \ | ||
680 | data = letoh32(*src_w++); \ | ||
681 | pixels = ALPHA_COLOR_PIXEL_PER_WORD; \ | ||
682 | } \ | ||
683 | } while (0) | ||
684 | #elif ALPHA_COLOR_PIXEL_PER_BYTE == 2 | ||
685 | #define UPDATE_SRC_ALPHA do { \ | ||
686 | if (pixels ^= 1) \ | ||
687 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
688 | else \ | ||
689 | data = *(++src); \ | ||
690 | } while (0) | ||
691 | #else | ||
692 | #define UPDATE_SRC_ALPHA do { \ | ||
693 | if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \ | ||
694 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
695 | else \ | ||
696 | data = *(++src); \ | ||
697 | } while (0) | ||
698 | #endif | ||
699 | |||
700 | do | ||
701 | { | ||
702 | *dst=blend_two_colors(*dst, fg_pattern, | ||
703 | data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
704 | dst++; | ||
705 | UPDATE_SRC_ALPHA; | ||
706 | } | ||
707 | while (--col); | ||
708 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
709 | if (skip_end < pixels) | ||
710 | { | ||
711 | pixels -= skip_end; | ||
712 | data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; | ||
713 | } else { | ||
714 | pixels = skip_end - pixels; | ||
715 | src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD; | ||
716 | pixels %= ALPHA_COLOR_PIXEL_PER_WORD; | ||
717 | data = letoh32(*src_w++); | ||
718 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | ||
719 | pixels = 8 - pixels; | ||
720 | } | ||
721 | #else | ||
722 | if (skip_end) | ||
723 | { | ||
724 | pixels += skip_end; | ||
725 | if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE) | ||
726 | { | ||
727 | src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE; | ||
728 | pixels %= ALPHA_COLOR_PIXEL_PER_BYTE; | ||
729 | data = *src; | ||
730 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | ||
731 | } else | ||
732 | data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; | ||
733 | } | ||
734 | #endif | ||
735 | dst += LCD_WIDTH - width; | ||
736 | } while (--row); | ||
737 | } | ||
738 | |||
565 | static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, | 739 | static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, |
566 | int x, int y, int ofs, const unsigned char *str ) | 740 | int x, int y, int ofs, const unsigned char *str ) |
567 | { | 741 | { |
@@ -589,8 +763,12 @@ static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, | |||
589 | 763 | ||
590 | bits = rb->font_get_bits( pf, ch ); | 764 | bits = rb->font_get_bits( pf, ch ); |
591 | 765 | ||
592 | buffer_mono_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0, | 766 | if (pf->depth) |
593 | width, x, y, width - ofs, pf->height); | 767 | buffer_alpha_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0, |
768 | width, x, y, width - ofs, pf->height); | ||
769 | else | ||
770 | buffer_mono_bitmap_part( buf, buf_width, buf_height, bits, ofs, 0, | ||
771 | width, x, y, width - ofs, pf->height); | ||
594 | 772 | ||
595 | x += width - ofs; | 773 | x += width - ofs; |
596 | ofs = 0; | 774 | ofs = 0; |