1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Dave Chapman
12 * Rockbox driver for 16-bit colour LCDs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
36 #include "rbunicode.h"
38 #include "scroll_engine.h"
47 fb_data lcd_framebuffer
[LCD_FBHEIGHT
][LCD_FBWIDTH
]
48 IRAM_LCDFRAMEBUFFER
CACHEALIGN_AT_LEAST_ATTR(16);
51 static fb_data
* lcd_backdrop
= NULL
;
52 static long lcd_backdrop_offset IDATA_ATTR
= 0;
54 static struct viewport default_vp
=
60 .font
= FONT_SYSFIXED
,
61 .drawmode
= DRMODE_SOLID
,
62 .fg_pattern
= LCD_DEFAULT_FG
,
63 .bg_pattern
= LCD_DEFAULT_BG
,
64 .lss_pattern
= LCD_DEFAULT_BG
,
65 .lse_pattern
= LCD_DEFAULT_BG
,
66 .lst_pattern
= LCD_DEFAULT_BG
,
69 /* The Gigabeat target build requires access to the current fg_pattern
71 #if (!defined(TOSHIBA_GIGABEAT_F)&& !defined(TOSHIBA_GIGABEAT_S)) || defined(SIMULATOR)
72 static struct viewport
* current_vp IDATA_ATTR
= &default_vp
;
74 struct viewport
* current_vp IDATA_ATTR
= &default_vp
;
78 /*** Helpers - consolidate optional code ***/
79 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
80 static void (*lcd_activation_hook
)(void) = NULL
;
82 void lcd_activation_set_hook(void (*func
)(void))
84 lcd_activation_hook
= func
;
87 /* To be called by target driver after enabling display and refreshing it */
88 void lcd_activation_call_hook(void)
90 void (*func
)(void) = lcd_activation_hook
;
103 /* Call device specific init */
109 void lcd_set_viewport(struct viewport
* vp
)
112 current_vp
= &default_vp
;
117 void lcd_update_viewport(void)
119 lcd_update_rect(current_vp
->x
, current_vp
->y
,
120 current_vp
->width
, current_vp
->height
);
123 void lcd_update_viewport_rect(int x
, int y
, int width
, int height
)
125 lcd_update_rect(current_vp
->x
+ x
, current_vp
->y
+ y
, width
, height
);
128 /*** parameter handling ***/
130 void lcd_set_drawmode(int mode
)
132 current_vp
->drawmode
= mode
& (DRMODE_SOLID
|DRMODE_INVERSEVID
);
135 int lcd_get_drawmode(void)
137 return current_vp
->drawmode
;
140 void lcd_set_foreground(unsigned color
)
142 current_vp
->fg_pattern
= color
;
145 unsigned lcd_get_foreground(void)
147 return current_vp
->fg_pattern
;
150 void lcd_set_background(unsigned color
)
152 current_vp
->bg_pattern
= color
;
155 unsigned lcd_get_background(void)
157 return current_vp
->bg_pattern
;
160 void lcd_set_selector_start(unsigned color
)
162 current_vp
->lss_pattern
= color
;
165 void lcd_set_selector_end(unsigned color
)
167 current_vp
->lse_pattern
= color
;
170 void lcd_set_selector_text(unsigned color
)
172 current_vp
->lst_pattern
= color
;
175 void lcd_set_drawinfo(int mode
, unsigned fg_color
, unsigned bg_color
)
177 lcd_set_drawmode(mode
);
178 current_vp
->fg_pattern
= fg_color
;
179 current_vp
->bg_pattern
= bg_color
;
182 int lcd_getwidth(void)
184 return current_vp
->width
;
187 int lcd_getheight(void)
189 return current_vp
->height
;
192 void lcd_setfont(int newfont
)
194 current_vp
->font
= newfont
;
197 int lcd_getfont(void)
199 return current_vp
->font
;
202 int lcd_getstringsize(const unsigned char *str
, int *w
, int *h
)
204 return font_getstringsize(str
, w
, h
, current_vp
->font
);
207 /*** low-level drawing functions ***/
209 #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
211 static void ICODE_ATTR
setpixel(fb_data
*address
)
213 *address
= current_vp
->fg_pattern
;
216 static void ICODE_ATTR
clearpixel(fb_data
*address
)
218 *address
= current_vp
->bg_pattern
;
221 static void ICODE_ATTR
clearimgpixel(fb_data
*address
)
223 *address
= *(fb_data
*)((long)address
+ lcd_backdrop_offset
);
226 static void ICODE_ATTR
flippixel(fb_data
*address
)
228 *address
= ~(*address
);
231 static void ICODE_ATTR
nopixel(fb_data
*address
)
236 lcd_fastpixelfunc_type
* const lcd_fastpixelfuncs_bgcolor
[8] = {
237 flippixel
, nopixel
, setpixel
, setpixel
,
238 nopixel
, clearpixel
, nopixel
, clearpixel
241 lcd_fastpixelfunc_type
* const lcd_fastpixelfuncs_backdrop
[8] = {
242 flippixel
, nopixel
, setpixel
, setpixel
,
243 nopixel
, clearimgpixel
, nopixel
, clearimgpixel
246 lcd_fastpixelfunc_type
* const * lcd_fastpixelfuncs
= lcd_fastpixelfuncs_bgcolor
;
248 void lcd_set_backdrop(fb_data
* backdrop
)
250 lcd_backdrop
= backdrop
;
253 lcd_backdrop_offset
= (long)backdrop
- (long)&lcd_framebuffer
[0][0];
254 lcd_fastpixelfuncs
= lcd_fastpixelfuncs_backdrop
;
258 lcd_backdrop_offset
= 0;
259 lcd_fastpixelfuncs
= lcd_fastpixelfuncs_bgcolor
;
263 fb_data
* lcd_get_backdrop(void)
268 /*** drawing functions ***/
270 /* Clear the current viewport */
271 void lcd_clear_viewport(void)
273 fb_data
*dst
, *dst_end
;
275 dst
= LCDADDR(current_vp
->x
, current_vp
->y
);
276 dst_end
= dst
+ current_vp
->height
* LCD_WIDTH
;
278 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
282 memset16(dst
, current_vp
->fg_pattern
, current_vp
->width
);
285 while (dst
< dst_end
);
293 memset16(dst
, current_vp
->bg_pattern
, current_vp
->width
);
296 while (dst
< dst_end
);
302 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
303 current_vp
->width
* sizeof(fb_data
));
306 while (dst
< dst_end
);
310 if (current_vp
== &default_vp
)
312 lcd_scroll_info
.lines
= 0;
316 lcd_scroll_stop(current_vp
);
320 /* Clear the whole display */
321 void lcd_clear_display(void)
323 struct viewport
* old_vp
= current_vp
;
325 current_vp
= &default_vp
;
327 lcd_clear_viewport();
332 /* Set a single pixel */
333 void lcd_drawpixel(int x
, int y
)
335 if (((unsigned)x
< (unsigned)current_vp
->width
) &&
336 ((unsigned)y
< (unsigned)current_vp
->height
))
337 lcd_fastpixelfuncs
[current_vp
->drawmode
](LCDADDR(current_vp
->x
+x
, current_vp
->y
+y
));
341 void lcd_drawline(int x1
, int y1
, int x2
, int y2
)
349 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
351 deltay
= abs(y2
- y1
);
354 DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n");
355 lcd_hline(x1
, x2
, y1
);
358 deltax
= abs(x2
- x1
);
361 DEBUGF("lcd_drawline() called for vertical line - optimisation.\n");
362 lcd_vline(x1
, y1
, y2
);
368 if (deltax
>= deltay
)
371 d
= 2 * deltay
- deltax
;
373 dinc2
= (deltay
- deltax
) * 2;
380 d
= 2 * deltax
- deltay
;
382 dinc2
= (deltax
- deltay
) * 2;
386 numpixels
++; /* include endpoints */
403 for (i
= 0; i
< numpixels
; i
++)
405 if (((unsigned)x
< (unsigned)current_vp
->width
) && ((unsigned)y
< (unsigned)current_vp
->height
))
406 pfunc(LCDADDR(x
+ current_vp
->x
, y
+ current_vp
->y
));
423 /* Draw a horizontal line (optimised) */
424 void lcd_hline(int x1
, int x2
, int y
)
428 enum fill_opt fillopt
= OPT_NONE
;
429 fb_data
*dst
, *dst_end
;
439 /* nothing to draw? */
440 if (((unsigned)y
>= (unsigned)current_vp
->height
) ||
441 (x1
>= current_vp
->width
) ||
445 /* drawmode and optimisation */
446 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
448 if (current_vp
->drawmode
& DRMODE_BG
)
453 bits
= current_vp
->bg_pattern
;
461 if (current_vp
->drawmode
& DRMODE_FG
)
464 bits
= current_vp
->fg_pattern
;
467 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
473 if (x2
>= current_vp
->width
)
474 x2
= current_vp
->width
-1;
478 /* Adjust x1 and y to viewport */
482 dst
= LCDADDR(x1
, y
);
487 memset16(dst
, bits
, width
);
491 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
492 width
* sizeof(fb_data
));
495 case OPT_NONE
: /* DRMODE_COMPLEMENT */
496 dst_end
= dst
+ width
;
499 while (++dst
< dst_end
);
504 /* Draw a vertical line (optimised) */
505 void lcd_vline(int x
, int y1
, int y2
)
508 fb_data
*dst
, *dst_end
;
509 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
519 /* nothing to draw? */
520 if (((unsigned)x
>= (unsigned)current_vp
->width
) ||
521 (y1
>= current_vp
->height
) ||
528 if (y2
>= current_vp
->height
)
529 y2
= current_vp
->height
-1;
531 dst
= LCDADDR(x
+ current_vp
->x
, y1
+ current_vp
->y
);
532 dst_end
= dst
+ (y2
- y1
) * LCD_WIDTH
;
539 while (dst
<= dst_end
);
542 /* Draw a rectangular box */
543 void lcd_drawrect(int x
, int y
, int width
, int height
)
545 if ((width
<= 0) || (height
<= 0))
548 int x2
= x
+ width
- 1;
549 int y2
= y
+ height
- 1;
552 lcd_vline(x2
, y
, y2
);
554 lcd_hline(x
, x2
, y2
);
557 /* Fill a rectangular area */
558 void lcd_fillrect(int x
, int y
, int width
, int height
)
561 enum fill_opt fillopt
= OPT_NONE
;
562 fb_data
*dst
, *dst_end
;
564 /* nothing to draw? */
565 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
566 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
569 /* drawmode and optimisation */
570 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
572 if (current_vp
->drawmode
& DRMODE_BG
)
577 bits
= current_vp
->bg_pattern
;
585 if (current_vp
->drawmode
& DRMODE_FG
)
588 bits
= current_vp
->fg_pattern
;
591 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
605 if (x
+ width
> current_vp
->width
)
606 width
= current_vp
->width
- x
;
607 if (y
+ height
> current_vp
->height
)
608 height
= current_vp
->height
- y
;
610 dst
= LCDADDR(current_vp
->x
+ x
, current_vp
->y
+ y
);
611 dst_end
= dst
+ height
* LCD_WIDTH
;
615 fb_data
*dst_row
, *row_end
;
620 memset16(dst
, bits
, width
);
624 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
625 width
* sizeof(fb_data
));
628 case OPT_NONE
: /* DRMODE_COMPLEMENT */
630 row_end
= dst_row
+ width
;
632 *dst_row
= ~(*dst_row
);
633 while (++dst_row
< row_end
);
638 while (dst
< dst_end
);
641 /* About Rockbox' internal monochrome bitmap format:
643 * A bitmap contains one bit for every pixel that defines if that pixel is
644 * black (1) or white (0). Bits within a byte are arranged vertically, LSB
646 * The bytes are stored in row-major order, with byte 0 being top left,
647 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
648 * 0..7, the second row defines pixel row 8..15 etc.
650 * This is the mono bitmap format used on all other targets so far; the
651 * pixel packing doesn't really matter on a 8bit+ target. */
653 /* Draw a partial monochrome bitmap */
655 void ICODE_ATTR
lcd_mono_bitmap_part(const unsigned char *src
, int src_x
,
656 int src_y
, int stride
, int x
, int y
,
657 int width
, int height
)
659 const unsigned char *src_end
;
660 fb_data
*dst
, *dst_end
;
661 unsigned dmask
= 0x100; /* bit 8 == sentinel */
662 int drmode
= current_vp
->drawmode
;
664 /* nothing to draw? */
665 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
666 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
682 if (x
+ width
> current_vp
->width
)
683 width
= current_vp
->width
- x
;
684 if (y
+ height
> current_vp
->height
)
685 height
= current_vp
->height
- y
;
687 src
+= stride
* (src_y
>> 3) + src_x
; /* move starting point */
689 src_end
= src
+ width
;
690 dst
= LCDADDR(current_vp
->x
+ x
, current_vp
->y
+ y
);
691 dst_end
= dst
+ height
* LCD_WIDTH
;
693 if (drmode
& DRMODE_INVERSEVID
)
695 dmask
= 0x1ff; /* bit 8 == sentinel */
696 drmode
&= DRMODE_SOLID
; /* mask out inversevid */
701 const unsigned char *src_col
= src
++;
702 unsigned data
= (*src_col
^ dmask
) >> src_y
;
703 fb_data
*dst_col
= dst
++;
707 #define UPDATE_SRC do { \
709 if (data == 0x001) { \
711 data = *src_col ^ dmask; \
717 case DRMODE_COMPLEMENT
:
721 *dst_col
= ~(*dst_col
);
723 dst_col
+= LCD_WIDTH
;
726 while (dst_col
< dst_end
);
732 bo
= lcd_backdrop_offset
;
736 *dst_col
= *(fb_data
*)((long)dst_col
+ bo
);
738 dst_col
+= LCD_WIDTH
;
741 while (dst_col
< dst_end
);
745 bg
= current_vp
->bg_pattern
;
751 dst_col
+= LCD_WIDTH
;
754 while (dst_col
< dst_end
);
759 fg
= current_vp
->fg_pattern
;
765 dst_col
+= LCD_WIDTH
;
768 while (dst_col
< dst_end
);
772 fg
= current_vp
->fg_pattern
;
775 bo
= lcd_backdrop_offset
;
778 *dst_col
= (data
& 0x01) ? fg
779 : *(fb_data
*)((long)dst_col
+ bo
);
780 dst_col
+= LCD_WIDTH
;
783 while (dst_col
< dst_end
);
787 bg
= current_vp
->bg_pattern
;
790 *dst_col
= (data
& 0x01) ? fg
: bg
;
791 dst_col
+= LCD_WIDTH
;
794 while (dst_col
< dst_end
);
799 while (src
< src_end
);
801 /* Draw a full monochrome bitmap */
802 void lcd_mono_bitmap(const unsigned char *src
, int x
, int y
, int width
, int height
)
804 lcd_mono_bitmap_part(src
, 0, 0, width
, x
, y
, width
, height
);
807 /* draw alpha bitmap for anti-alias font */
808 #define ALPHA_COLOR_FONT_DEPTH 2
809 #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH)
810 #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1)
811 #define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH)
812 #define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH)
814 #define BLEND_INIT do {} while (0)
815 #define BLEND_START(acc, color, alpha) \
816 asm volatile("mul %0, %1, %2" : "=&r" (acc) : "r" (color), "r" (alpha))
817 #define BLEND_CONT(acc, color, alpha) \
818 asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha))
819 #define BLEND_OUT(acc) do {} while (0)
820 #elif defined(CPU_COLDFIRE)
821 #define ALPHA_BITMAP_READ_WORDS
822 #define BLEND_INIT coldfire_set_macsr(EMAC_UNSIGNED)
823 #define BLEND_START(acc, color, alpha) \
824 asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha))
825 #define BLEND_CONT BLEND_START
826 #define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc))
828 #define BLEND_INIT do {} while (0)
829 #define BLEND_START(acc, color, alpha) ((acc) = (color) * (alpha))
830 #define BLEND_CONT(acc, color, alpha) ((acc) += (color) * (alpha))
831 #define BLEND_OUT(acc) do {} while (0)
834 /* Blend the given two colors */
835 static inline unsigned blend_two_colors(unsigned c1
, unsigned c2
, unsigned a
)
837 a
+= a
>> (ALPHA_COLOR_LOOKUP_SHIFT
- 1);
838 #if (LCD_PIXELFORMAT == RGB565SWAPPED)
842 unsigned c1l
= (c1
| (c1
<< 16)) & 0x07e0f81f;
843 unsigned c2l
= (c2
| (c2
<< 16)) & 0x07e0f81f;
845 BLEND_START(p
, c1l
, a
);
846 BLEND_CONT(p
, c2l
, ALPHA_COLOR_LOOKUP_SIZE
+ 1 - a
);
848 p
= (p
>> ALPHA_COLOR_LOOKUP_SHIFT
) & 0x07e0f81f;
850 #if (LCD_PIXELFORMAT == RGB565SWAPPED)
857 /* Blend the given color with the value from the alpha_color_lookup table */
858 static inline unsigned blend_color(unsigned c
, unsigned a
)
860 return blend_two_colors(c
, current_vp
->fg_pattern
, a
);
863 void ICODE_ATTR
lcd_alpha_bitmap_part(const unsigned char *src
, int src_x
,
864 int src_y
, int stride
, int x
, int y
,
865 int width
, int height
)
867 fb_data
*dst
, *backdrop
;
868 unsigned dmask
= 0x00000000;
869 int drmode
= current_vp
->drawmode
;
870 /* nothing to draw? */
871 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
872 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
875 /* initialize blending */
891 if (x
+ width
> current_vp
->width
)
892 width
= current_vp
->width
- x
;
893 if (y
+ height
> current_vp
->height
)
894 height
= current_vp
->height
- y
;
896 if (drmode
& DRMODE_INVERSEVID
)
899 drmode
&= DRMODE_SOLID
; /* mask out inversevid */
901 if (drmode
== DRMODE_BG
)
906 dst
= LCDADDR(current_vp
->x
+ x
, current_vp
->y
+ y
);
908 int col
, row
= height
;
909 unsigned data
, pixels
;
910 unsigned skip_end
= (stride
- width
);
911 unsigned skip_start
= src_y
* stride
+ src_x
;
913 #ifdef ALPHA_BITMAP_READ_WORDS
914 uint32_t *src_w
= (uint32_t *)((uintptr_t)src
& ~3);
915 skip_start
+= ALPHA_COLOR_PIXEL_PER_BYTE
* ((uintptr_t)src
& 3);
916 src_w
+= skip_start
/ ALPHA_COLOR_PIXEL_PER_WORD
;
917 data
= letoh32(*src_w
++) ^ dmask
;
919 src
+= skip_start
/ ALPHA_COLOR_PIXEL_PER_BYTE
;
922 pixels
= skip_start
% ALPHA_COLOR_PIXEL_PER_WORD
;
923 data
>>= pixels
* ALPHA_COLOR_LOOKUP_SHIFT
;
924 #ifdef ALPHA_BITMAP_READ_WORDS
931 #ifdef ALPHA_BITMAP_READ_WORDS
932 #define UPDATE_SRC_ALPHA do { \
934 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
937 data = letoh32(*src_w++) ^ dmask; \
938 pixels = ALPHA_COLOR_PIXEL_PER_WORD; \
941 #elif ALPHA_COLOR_PIXEL_PER_BYTE == 2
942 #define UPDATE_SRC_ALPHA do { \
944 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
946 data = *(++src) ^ dmask; \
949 #define UPDATE_SRC_ALPHA do { \
950 if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \
951 data >>= ALPHA_COLOR_LOOKUP_SHIFT; \
953 data = *(++src) ^ dmask; \
956 /* we don't want to have this in our inner
957 * loop and the codesize increase is minimal */
960 case DRMODE_COMPLEMENT
:
963 *dst
=blend_two_colors(*dst
, ~(*dst
),
964 data
& ALPHA_COLOR_LOOKUP_SIZE
);
973 backdrop
= (fb_data
*)((long)dst
+lcd_backdrop_offset
);
976 *dst
=blend_two_colors(*dst
, *(backdrop
++),
977 data
& ALPHA_COLOR_LOOKUP_SIZE
);
987 *dst
=blend_two_colors(*dst
, current_vp
->bg_pattern
,
988 data
& ALPHA_COLOR_LOOKUP_SIZE
);
998 *dst
=blend_color(*dst
, data
& ALPHA_COLOR_LOOKUP_SIZE
);
1007 backdrop
= (fb_data
*)((long)dst
+lcd_backdrop_offset
);
1010 *(dst
++)=blend_color(*(backdrop
++),
1011 data
& ALPHA_COLOR_LOOKUP_SIZE
);
1020 *(dst
++)=blend_color(current_vp
->bg_pattern
,
1021 data
& ALPHA_COLOR_LOOKUP_SIZE
);
1028 #ifdef ALPHA_BITMAP_READ_WORDS
1029 if (skip_end
< pixels
)
1032 data
>>= skip_end
* ALPHA_COLOR_LOOKUP_SHIFT
;
1034 pixels
= skip_end
- pixels
;
1035 src_w
+= pixels
/ ALPHA_COLOR_PIXEL_PER_WORD
;
1036 pixels
%= ALPHA_COLOR_PIXEL_PER_WORD
;
1037 data
= letoh32(*src_w
++) ^ dmask
;
1038 data
>>= pixels
* ALPHA_COLOR_LOOKUP_SHIFT
;
1039 pixels
= 8 - pixels
;
1045 if (pixels
>= ALPHA_COLOR_PIXEL_PER_BYTE
)
1047 src
+= pixels
/ ALPHA_COLOR_PIXEL_PER_BYTE
;
1048 pixels
%= ALPHA_COLOR_PIXEL_PER_BYTE
;
1049 data
= *src
^ dmask
;
1050 data
>>= pixels
* ALPHA_COLOR_LOOKUP_SHIFT
;
1052 data
>>= skip_end
* ALPHA_COLOR_LOOKUP_SHIFT
;
1055 dst
+= LCD_WIDTH
- width
;
1059 /* Draw a partial native bitmap */
1060 void ICODE_ATTR
lcd_bitmap_part(const fb_data
*src
, int src_x
, int src_y
,
1061 int stride
, int x
, int y
, int width
,
1064 fb_data
*dst
, *dst_end
;
1066 /* nothing to draw? */
1067 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
1068 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
1084 if (x
+ width
> current_vp
->width
)
1085 width
= current_vp
->width
- x
;
1086 if (y
+ height
> current_vp
->height
)
1087 height
= current_vp
->height
- y
;
1089 src
+= stride
* src_y
+ src_x
; /* move starting point */
1090 dst
= LCDADDR(current_vp
->x
+ x
, current_vp
->y
+ y
);
1091 dst_end
= dst
+ height
* LCD_WIDTH
;
1095 memcpy(dst
, src
, width
* sizeof(fb_data
));
1099 while (dst
< dst_end
);
1102 /* Draw a full native bitmap */
1103 void lcd_bitmap(const fb_data
*src
, int x
, int y
, int width
, int height
)
1105 lcd_bitmap_part(src
, 0, 0, width
, x
, y
, width
, height
);
1108 #if !defined(TOSHIBA_GIGABEAT_F) && !defined(TOSHIBA_GIGABEAT_S) \
1109 || defined(SIMULATOR)
1110 /* Draw a partial native bitmap */
1111 void ICODE_ATTR
lcd_bitmap_transparent_part(const fb_data
*src
, int src_x
,
1112 int src_y
, int stride
, int x
,
1113 int y
, int width
, int height
)
1115 fb_data
*dst
, *dst_end
;
1117 /* nothing to draw? */
1118 if ((width
<= 0) || (height
<= 0) || (x
>= current_vp
->width
) ||
1119 (y
>= current_vp
->height
) || (x
+ width
<= 0) || (y
+ height
<= 0))
1135 if (x
+ width
> current_vp
->width
)
1136 width
= current_vp
->width
- x
;
1137 if (y
+ height
> current_vp
->height
)
1138 height
= current_vp
->height
- y
;
1140 src
+= stride
* src_y
+ src_x
; /* move starting point */
1141 dst
= LCDADDR(current_vp
->x
+ x
, current_vp
->y
+ y
);
1142 dst_end
= dst
+ height
* LCD_WIDTH
;
1147 for(i
= 0;i
< width
;i
++)
1149 if (src
[i
] == REPLACEWITHFG_COLOR
)
1150 dst
[i
] = current_vp
->fg_pattern
;
1151 else if(src
[i
] != TRANSPARENT_COLOR
)
1157 while (dst
< dst_end
);
1159 #endif /* !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR) */
1161 /* Draw a full native bitmap with a transparent color */
1162 void lcd_bitmap_transparent(const fb_data
*src
, int x
, int y
,
1163 int width
, int height
)
1165 lcd_bitmap_transparent_part(src
, 0, 0, width
, x
, y
, width
, height
);
1168 #include "lcd-bitmap-common.c"