Android: Partly revert r29569 and only call the new getJavaEnvironment() when needed.
[maemo-rb.git] / firmware / drivers / lcd-16bit.c
blob28c3285a9cd05aad0a825c04d1145bedf4725d09
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Dave Chapman
12 * Copyright (C) 2009 by Karl Kurbjun
14 * Rockbox driver for 16-bit colour LCDs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
24 ****************************************************************************/
26 #include "config.h"
28 #include "cpu.h"
29 #include "lcd.h"
30 #include "kernel.h"
31 #include "thread.h"
32 #include <stdlib.h>
33 #include "string-extra.h" /* mem*() */
34 #include "file.h"
35 #include "debug.h"
36 #include "system.h"
37 #include "font.h"
38 #include "rbunicode.h"
39 #include "bidi.h"
40 #include "scroll_engine.h"
42 enum fill_opt {
43 OPT_NONE = 0,
44 OPT_SET,
45 OPT_COPY
48 /*** globals ***/
49 fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
50 IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
53 static fb_data* lcd_backdrop = NULL;
54 static long lcd_backdrop_offset IDATA_ATTR = 0;
56 static struct viewport default_vp =
58 .x = 0,
59 .y = 0,
60 .width = LCD_WIDTH,
61 .height = LCD_HEIGHT,
62 .font = FONT_SYSFIXED,
63 .drawmode = DRMODE_SOLID,
64 .fg_pattern = LCD_DEFAULT_FG,
65 .bg_pattern = LCD_DEFAULT_BG,
66 .lss_pattern = LCD_DEFAULT_BG,
67 .lse_pattern = LCD_DEFAULT_BG,
68 .lst_pattern = LCD_DEFAULT_BG,
71 static struct viewport* current_vp IDATA_ATTR = &default_vp;
73 /* LCD init */
74 void lcd_init(void)
76 lcd_clear_display();
78 /* Call device specific init */
79 lcd_init_device();
80 scroll_init();
82 /*** Viewports ***/
84 void lcd_set_viewport(struct viewport* vp)
86 if (vp == NULL)
87 current_vp = &default_vp;
88 else
89 current_vp = vp;
91 #if defined(SIMULATOR)
92 /* Force the viewport to be within bounds. If this happens it should
93 * be considered an error - the viewport will not draw as it might be
94 * expected.
96 if((unsigned) current_vp->x > (unsigned) LCD_WIDTH
97 || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT
98 || current_vp->x + current_vp->width > LCD_WIDTH
99 || current_vp->y + current_vp->height > LCD_HEIGHT)
101 #if !defined(HAVE_VIEWPORT_CLIP)
102 DEBUGF("ERROR: "
103 #else
104 DEBUGF("NOTE: "
105 #endif
106 "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n",
107 current_vp->x, current_vp->y,
108 current_vp->width, current_vp->height);
111 #endif
114 void lcd_update_viewport(void)
116 lcd_update_rect(current_vp->x, current_vp->y,
117 current_vp->width, current_vp->height);
120 void lcd_update_viewport_rect(int x, int y, int width, int height)
122 lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
125 /*** parameter handling ***/
127 void lcd_set_drawmode(int mode)
129 current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
132 int lcd_get_drawmode(void)
134 return current_vp->drawmode;
137 void lcd_set_foreground(unsigned color)
139 current_vp->fg_pattern = color;
142 unsigned lcd_get_foreground(void)
144 return current_vp->fg_pattern;
147 void lcd_set_background(unsigned color)
149 current_vp->bg_pattern = color;
152 unsigned lcd_get_background(void)
154 return current_vp->bg_pattern;
157 void lcd_set_selector_start(unsigned color)
159 current_vp->lss_pattern = color;
162 void lcd_set_selector_end(unsigned color)
164 current_vp->lse_pattern = color;
167 void lcd_set_selector_text(unsigned color)
169 current_vp->lst_pattern = color;
172 void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color)
174 lcd_set_drawmode(mode);
175 current_vp->fg_pattern = fg_color;
176 current_vp->bg_pattern = bg_color;
179 int lcd_getwidth(void)
181 return current_vp->width;
184 int lcd_getheight(void)
186 return current_vp->height;
189 void lcd_setfont(int newfont)
191 current_vp->font = newfont;
194 int lcd_getfont(void)
196 return current_vp->font;
199 int lcd_getstringsize(const unsigned char *str, int *w, int *h)
201 return font_getstringsize(str, w, h, current_vp->font);
204 /*** low-level drawing functions ***/
206 #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
208 static void ICODE_ATTR setpixel(fb_data *address)
210 *address = current_vp->fg_pattern;
213 static void ICODE_ATTR clearpixel(fb_data *address)
215 *address = current_vp->bg_pattern;
218 static void ICODE_ATTR clearimgpixel(fb_data *address)
220 *address = *(fb_data *)((long)address + lcd_backdrop_offset);
223 static void ICODE_ATTR flippixel(fb_data *address)
225 *address = ~(*address);
228 static void ICODE_ATTR nopixel(fb_data *address)
230 (void)address;
233 lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_bgcolor[8] = {
234 flippixel, nopixel, setpixel, setpixel,
235 nopixel, clearpixel, nopixel, clearpixel
238 lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[8] = {
239 flippixel, nopixel, setpixel, setpixel,
240 nopixel, clearimgpixel, nopixel, clearimgpixel
243 lcd_fastpixelfunc_type* const * lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor;
245 void lcd_set_backdrop(fb_data* backdrop)
247 lcd_backdrop = backdrop;
248 if (backdrop)
250 lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0];
251 lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop;
253 else
255 lcd_backdrop_offset = 0;
256 lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor;
260 fb_data* lcd_get_backdrop(void)
262 return lcd_backdrop;
265 /*** drawing functions ***/
267 /* Clear the current viewport */
268 void lcd_clear_viewport(void)
270 fb_data *dst, *dst_end;
272 dst = LCDADDR(current_vp->x, current_vp->y);
273 dst_end = dst + current_vp->height * LCD_WIDTH;
275 if (current_vp->drawmode & DRMODE_INVERSEVID)
279 memset16(dst, current_vp->fg_pattern, current_vp->width);
280 dst += LCD_WIDTH;
282 while (dst < dst_end);
284 else
286 if (!lcd_backdrop)
290 memset16(dst, current_vp->bg_pattern, current_vp->width);
291 dst += LCD_WIDTH;
293 while (dst < dst_end);
295 else
299 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
300 current_vp->width * sizeof(fb_data));
301 dst += LCD_WIDTH;
303 while (dst < dst_end);
307 if (current_vp == &default_vp)
309 lcd_scroll_info.lines = 0;
311 else
313 lcd_scroll_stop(current_vp);
317 /* Clear the whole display */
318 void lcd_clear_display(void)
320 struct viewport* old_vp = current_vp;
322 current_vp = &default_vp;
324 lcd_clear_viewport();
326 current_vp = old_vp;
329 /* Set a single pixel */
330 void lcd_drawpixel(int x, int y)
332 if ( ((unsigned)x < (unsigned)current_vp->width)
333 && ((unsigned)y < (unsigned)current_vp->height)
334 #if defined(HAVE_VIEWPORT_CLIP)
335 && ((unsigned)x < (unsigned)LCD_WIDTH)
336 && ((unsigned)y < (unsigned)LCD_HEIGHT)
337 #endif
339 lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y));
342 /* Draw a line */
343 void lcd_drawline(int x1, int y1, int x2, int y2)
345 int numpixels;
346 int i;
347 int deltax, deltay;
348 int d, dinc1, dinc2;
349 int x, xinc1, xinc2;
350 int y, yinc1, yinc2;
351 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
353 deltay = abs(y2 - y1);
354 if (deltay == 0)
356 /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */
357 lcd_hline(x1, x2, y1);
358 return;
360 deltax = abs(x2 - x1);
361 if (deltax == 0)
363 /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */
364 lcd_vline(x1, y1, y2);
365 return;
367 xinc2 = 1;
368 yinc2 = 1;
370 if (deltax >= deltay)
372 numpixels = deltax;
373 d = 2 * deltay - deltax;
374 dinc1 = deltay * 2;
375 dinc2 = (deltay - deltax) * 2;
376 xinc1 = 1;
377 yinc1 = 0;
379 else
381 numpixels = deltay;
382 d = 2 * deltax - deltay;
383 dinc1 = deltax * 2;
384 dinc2 = (deltax - deltay) * 2;
385 xinc1 = 0;
386 yinc1 = 1;
388 numpixels++; /* include endpoints */
390 if (x1 > x2)
392 xinc1 = -xinc1;
393 xinc2 = -xinc2;
396 if (y1 > y2)
398 yinc1 = -yinc1;
399 yinc2 = -yinc2;
402 x = x1;
403 y = y1;
405 for (i = 0; i < numpixels; i++)
407 if ( ((unsigned)x < (unsigned)current_vp->width)
408 && ((unsigned)y < (unsigned)current_vp->height)
409 #if defined(HAVE_VIEWPORT_CLIP)
410 && ((unsigned)x < (unsigned)LCD_WIDTH)
411 && ((unsigned)y < (unsigned)LCD_HEIGHT)
412 #endif
414 pfunc(LCDADDR(x + current_vp->x, y + current_vp->y));
416 if (d < 0)
418 d += dinc1;
419 x += xinc1;
420 y += yinc1;
422 else
424 d += dinc2;
425 x += xinc2;
426 y += yinc2;
431 /* Draw a horizontal line (optimised) */
432 void lcd_hline(int x1, int x2, int y)
434 int x, width;
435 unsigned bits = 0;
436 enum fill_opt fillopt = OPT_NONE;
437 fb_data *dst, *dst_end;
439 /* direction flip */
440 if (x2 < x1)
442 x = x1;
443 x1 = x2;
444 x2 = x;
447 /******************** In viewport clipping **********************/
448 /* nothing to draw? */
449 if (((unsigned)y >= (unsigned)current_vp->height) ||
450 (x1 >= current_vp->width) ||
451 (x2 < 0))
452 return;
454 if (x1 < 0)
455 x1 = 0;
456 if (x2 >= current_vp->width)
457 x2 = current_vp->width-1;
459 /* Adjust x1 and y to viewport */
460 x1 += current_vp->x;
461 x2 += current_vp->x;
462 y += current_vp->y;
464 #if defined(HAVE_VIEWPORT_CLIP)
465 /********************* Viewport on screen clipping ********************/
466 /* nothing to draw? */
467 if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH)
468 || (x2 < 0))
469 return;
471 /* clipping */
472 if (x1 < 0)
473 x1 = 0;
474 if (x2 >= LCD_WIDTH)
475 x2 = LCD_WIDTH-1;
476 #endif
478 width = x2 - x1 + 1;
480 /* drawmode and optimisation */
481 if (current_vp->drawmode & DRMODE_INVERSEVID)
483 if (current_vp->drawmode & DRMODE_BG)
485 if (!lcd_backdrop)
487 fillopt = OPT_SET;
488 bits = current_vp->bg_pattern;
490 else
491 fillopt = OPT_COPY;
494 else
496 if (current_vp->drawmode & DRMODE_FG)
498 fillopt = OPT_SET;
499 bits = current_vp->fg_pattern;
502 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
503 return;
505 dst = LCDADDR(x1, y);
507 switch (fillopt)
509 case OPT_SET:
510 memset16(dst, bits, width);
511 break;
513 case OPT_COPY:
514 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
515 width * sizeof(fb_data));
516 break;
518 case OPT_NONE: /* DRMODE_COMPLEMENT */
519 dst_end = dst + width;
521 *dst = ~(*dst);
522 while (++dst < dst_end);
523 break;
527 /* Draw a vertical line (optimised) */
528 void lcd_vline(int x, int y1, int y2)
530 int y;
531 fb_data *dst, *dst_end;
532 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
534 /* direction flip */
535 if (y2 < y1)
537 y = y1;
538 y1 = y2;
539 y2 = y;
542 /******************** In viewport clipping **********************/
543 /* nothing to draw? */
544 if (((unsigned)x >= (unsigned)current_vp->width) ||
545 (y1 >= current_vp->height) ||
546 (y2 < 0))
547 return;
549 if (y1 < 0)
550 y1 = 0;
551 if (y2 >= current_vp->height)
552 y2 = current_vp->height-1;
554 /* adjust for viewport */
555 x += current_vp->x;
556 y1 += current_vp->y;
557 y2 += current_vp->y;
559 #if defined(HAVE_VIEWPORT_CLIP)
560 /********************* Viewport on screen clipping ********************/
561 /* nothing to draw? */
562 if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT)
563 || (y2 < 0))
564 return;
566 /* clipping */
567 if (y1 < 0)
568 y1 = 0;
569 if (y2 >= LCD_HEIGHT)
570 y2 = LCD_HEIGHT-1;
571 #endif
573 dst = LCDADDR(x , y1);
574 dst_end = dst + (y2 - y1) * LCD_WIDTH;
578 pfunc(dst);
579 dst += LCD_WIDTH;
581 while (dst <= dst_end);
584 /* Draw a rectangular box */
585 void lcd_drawrect(int x, int y, int width, int height)
587 if ((width <= 0) || (height <= 0))
588 return;
590 int x2 = x + width - 1;
591 int y2 = y + height - 1;
593 lcd_vline(x, y, y2);
594 lcd_vline(x2, y, y2);
595 lcd_hline(x, x2, y);
596 lcd_hline(x, x2, y2);
599 /* Fill a rectangular area */
600 void lcd_fillrect(int x, int y, int width, int height)
602 unsigned bits = 0;
603 enum fill_opt fillopt = OPT_NONE;
604 fb_data *dst, *dst_end;
606 /******************** In viewport clipping **********************/
607 /* nothing to draw? */
608 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
609 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
610 return;
612 if (x < 0)
614 width += x;
615 x = 0;
617 if (y < 0)
619 height += y;
620 y = 0;
622 if (x + width > current_vp->width)
623 width = current_vp->width - x;
624 if (y + height > current_vp->height)
625 height = current_vp->height - y;
627 /* adjust for viewport */
628 x += current_vp->x;
629 y += current_vp->y;
631 #if defined(HAVE_VIEWPORT_CLIP)
632 /********************* Viewport on screen clipping ********************/
633 /* nothing to draw? */
634 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
635 || (x + width <= 0) || (y + height <= 0))
636 return;
638 /* clip image in viewport in screen */
639 if (x < 0)
641 width += x;
642 x = 0;
644 if (y < 0)
646 height += y;
647 y = 0;
649 if (x + width > LCD_WIDTH)
650 width = LCD_WIDTH - x;
651 if (y + height > LCD_HEIGHT)
652 height = LCD_HEIGHT - y;
653 #endif
655 /* drawmode and optimisation */
656 if (current_vp->drawmode & DRMODE_INVERSEVID)
658 if (current_vp->drawmode & DRMODE_BG)
660 if (!lcd_backdrop)
662 fillopt = OPT_SET;
663 bits = current_vp->bg_pattern;
665 else
666 fillopt = OPT_COPY;
669 else
671 if (current_vp->drawmode & DRMODE_FG)
673 fillopt = OPT_SET;
674 bits = current_vp->fg_pattern;
677 if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT)
678 return;
680 dst = LCDADDR(x, y);
681 dst_end = dst + height * LCD_WIDTH;
685 fb_data *dst_row, *row_end;
687 switch (fillopt)
689 case OPT_SET:
690 memset16(dst, bits, width);
691 break;
693 case OPT_COPY:
694 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
695 width * sizeof(fb_data));
696 break;
698 case OPT_NONE: /* DRMODE_COMPLEMENT */
699 dst_row = dst;
700 row_end = dst_row + width;
702 *dst_row = ~(*dst_row);
703 while (++dst_row < row_end);
704 break;
706 dst += LCD_WIDTH;
708 while (dst < dst_end);
711 /* Draw a partial native bitmap */
712 void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
713 int stride, int x, int y, int width,
714 int height)
716 fb_data *dst;
718 /******************** Image in viewport clipping **********************/
719 /* nothing to draw? */
720 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
721 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
722 return;
724 if (x < 0)
726 width += x;
727 src_x -= x;
728 x = 0;
730 if (y < 0)
732 height += y;
733 src_y -= y;
734 y = 0;
737 if (x + width > current_vp->width)
738 width = current_vp->width - x;
739 if (y + height > current_vp->height)
740 height = current_vp->height - y;
742 /* adjust for viewport */
743 x += current_vp->x;
744 y += current_vp->y;
746 #if defined(HAVE_VIEWPORT_CLIP)
747 /********************* Viewport on screen clipping ********************/
748 /* nothing to draw? */
749 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
750 || (x + width <= 0) || (y + height <= 0))
751 return;
753 /* clip image in viewport in screen */
754 if (x < 0)
756 width += x;
757 src_x -= x;
758 x = 0;
760 if (y < 0)
762 height += y;
763 src_y -= y;
764 y = 0;
766 if (x + width > LCD_WIDTH)
767 width = LCD_WIDTH - x;
768 if (y + height > LCD_HEIGHT)
769 height = LCD_HEIGHT - y;
770 #endif
772 src += stride * src_y + src_x; /* move starting point */
773 dst = LCDADDR(x, y);
777 memcpy(dst, src, width * sizeof(fb_data));
778 src += stride;
779 dst += LCD_WIDTH;
781 while (--height > 0);
784 /* Draw a full native bitmap */
785 void lcd_bitmap(const fb_data *src, int x, int y, int width, int height)
787 lcd_bitmap_part(src, 0, 0, width, x, y, width, height);
790 /* Draw a partial native bitmap with transparency and foreground colors */
791 void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x,
792 int src_y, int stride, int x,
793 int y, int width, int height)
795 fb_data *dst;
796 unsigned fg = current_vp->fg_pattern;
798 /******************** Image in viewport clipping **********************/
799 /* nothing to draw? */
800 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
801 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
802 return;
804 if (x < 0)
806 width += x;
807 src_x -= x;
808 x = 0;
810 if (y < 0)
812 height += y;
813 src_y -= y;
814 y = 0;
817 if (x + width > current_vp->width)
818 width = current_vp->width - x;
819 if (y + height > current_vp->height)
820 height = current_vp->height - y;
822 /* adjust for viewport */
823 x += current_vp->x;
824 y += current_vp->y;
826 #if defined(HAVE_VIEWPORT_CLIP)
827 /********************* Viewport on screen clipping ********************/
828 /* nothing to draw? */
829 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
830 || (x + width <= 0) || (y + height <= 0))
831 return;
833 /* clip image in viewport in screen */
834 if (x < 0)
836 width += x;
837 src_x -= x;
838 x = 0;
840 if (y < 0)
842 height += y;
843 src_y -= y;
844 y = 0;
846 if (x + width > LCD_WIDTH)
847 width = LCD_WIDTH - x;
848 if (y + height > LCD_HEIGHT)
849 height = LCD_HEIGHT - y;
850 #endif
852 src += stride * src_y + src_x; /* move starting point */
853 dst = LCDADDR(x, y);
855 #ifdef CPU_ARM
857 int w, px;
858 asm volatile (
859 ".rowstart: \n"
860 "mov %[w], %[width] \n" /* Load width for inner loop */
861 ".nextpixel: \n"
862 "ldrh %[px], [%[s]], #2 \n" /* Load src pixel */
863 "add %[d], %[d], #2 \n" /* Uncoditionally increment dst */
864 /* done here for better pipelining */
865 "cmp %[px], %[fgcolor] \n" /* Compare to foreground color */
866 "streqh %[fgpat], [%[d], #-2] \n" /* Store foregroud if match */
867 "cmpne %[px], %[transcolor] \n" /* Compare to transparent color */
868 "strneh %[px], [%[d], #-2] \n" /* Store dst if not transparent */
869 "subs %[w], %[w], #1 \n" /* Width counter has run down? */
870 "bgt .nextpixel \n" /* More in this row? */
871 "add %[s], %[s], %[sstp], lsl #1 \n" /* Skip over to start of next line */
872 "add %[d], %[d], %[dstp], lsl #1 \n"
873 "subs %[h], %[h], #1 \n" /* Height counter has run down? */
874 "bgt .rowstart \n" /* More rows? */
875 : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px),
876 [s]"+&r"(src), [d]"+&r"(dst)
877 : [width]"r"(width),
878 [sstp]"r"(stride - width),
879 [dstp]"r"(LCD_WIDTH - width),
880 [transcolor]"r"(TRANSPARENT_COLOR),
881 [fgcolor]"r"(REPLACEWITHFG_COLOR),
882 [fgpat]"r"(fg)
885 #else /* optimized C version */
888 const fb_data *src_row = src;
889 fb_data *dst_row = dst;
890 fb_data *row_end = dst_row + width;
893 unsigned data = *src_row++;
894 if (data != TRANSPARENT_COLOR)
896 if (data == REPLACEWITHFG_COLOR)
897 data = fg;
898 *dst_row = data;
901 while (++dst_row < row_end);
902 src += stride;
903 dst += LCD_WIDTH;
905 while (--height > 0);
906 #endif
909 /* Draw a full native bitmap with transparent and foreground colors */
910 void lcd_bitmap_transparent(const fb_data *src, int x, int y,
911 int width, int height)
913 lcd_bitmap_transparent_part(src, 0, 0, width, x, y, width, height);
916 #define ROW_INC LCD_WIDTH
917 #define COL_INC 1
919 #include "lcd-16bit-common.c"
921 #include "lcd-bitmap-common.c"