summaryrefslogtreecommitdiff
path: root/apps/plugins/rockpaint.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockpaint.c')
-rw-r--r--apps/plugins/rockpaint.c182
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 */
593static 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
615static 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
565static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, 739static 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;