1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
33 #include "string-extra.h" /* mem*() */
38 #include "rbunicode.h"
40 #include "scroll_engine.h"
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
=
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
;
78 /* Call device specific init */
84 void lcd_set_viewport(struct viewport
* vp
)
87 current_vp
= &default_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
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)
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
);
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
)
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
;
250 lcd_backdrop_offset
= (long)backdrop
- (long)&lcd_framebuffer
[0][0];
251 lcd_fastpixelfuncs
= lcd_fastpixelfuncs_backdrop
;
255 lcd_backdrop_offset
= 0;
256 lcd_fastpixelfuncs
= lcd_fastpixelfuncs_bgcolor
;
260 fb_data
* lcd_get_backdrop(void)
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
);
282 while (dst
< dst_end
);
290 memset16(dst
, current_vp
->bg_pattern
, current_vp
->width
);
293 while (dst
< dst_end
);
299 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
300 current_vp
->width
* sizeof(fb_data
));
303 while (dst
< dst_end
);
307 if (current_vp
== &default_vp
)
309 lcd_scroll_info
.lines
= 0;
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();
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
)
339 lcd_fastpixelfuncs
[current_vp
->drawmode
](LCDADDR(current_vp
->x
+x
, current_vp
->y
+y
));
343 void lcd_drawline(int x1
, int y1
, int x2
, int y2
)
351 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
353 deltay
= abs(y2
- y1
);
356 /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */
357 lcd_hline(x1
, x2
, y1
);
360 deltax
= abs(x2
- x1
);
363 /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */
364 lcd_vline(x1
, y1
, y2
);
370 if (deltax
>= deltay
)
373 d
= 2 * deltay
- deltax
;
375 dinc2
= (deltay
- deltax
) * 2;
382 d
= 2 * deltax
- deltay
;
384 dinc2
= (deltax
- deltay
) * 2;
388 numpixels
++; /* include endpoints */
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
)
414 pfunc(LCDADDR(x
+ current_vp
->x
, y
+ current_vp
->y
));
431 /* Draw a horizontal line (optimised) */
432 void lcd_hline(int x1
, int x2
, int y
)
436 enum fill_opt fillopt
= OPT_NONE
;
437 fb_data
*dst
, *dst_end
;
447 /******************** In viewport clipping **********************/
448 /* nothing to draw? */
449 if (((unsigned)y
>= (unsigned)current_vp
->height
) ||
450 (x1
>= current_vp
->width
) ||
456 if (x2
>= current_vp
->width
)
457 x2
= current_vp
->width
-1;
459 /* Adjust x1 and y to viewport */
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
)
480 /* drawmode and optimisation */
481 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
483 if (current_vp
->drawmode
& DRMODE_BG
)
488 bits
= current_vp
->bg_pattern
;
496 if (current_vp
->drawmode
& DRMODE_FG
)
499 bits
= current_vp
->fg_pattern
;
502 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
505 dst
= LCDADDR(x1
, y
);
510 memset16(dst
, bits
, width
);
514 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
515 width
* sizeof(fb_data
));
518 case OPT_NONE
: /* DRMODE_COMPLEMENT */
519 dst_end
= dst
+ width
;
522 while (++dst
< dst_end
);
527 /* Draw a vertical line (optimised) */
528 void lcd_vline(int x
, int y1
, int y2
)
531 fb_data
*dst
, *dst_end
;
532 lcd_fastpixelfunc_type
*pfunc
= lcd_fastpixelfuncs
[current_vp
->drawmode
];
542 /******************** In viewport clipping **********************/
543 /* nothing to draw? */
544 if (((unsigned)x
>= (unsigned)current_vp
->width
) ||
545 (y1
>= current_vp
->height
) ||
551 if (y2
>= current_vp
->height
)
552 y2
= current_vp
->height
-1;
554 /* adjust for viewport */
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
)
569 if (y2
>= LCD_HEIGHT
)
573 dst
= LCDADDR(x
, y1
);
574 dst_end
= dst
+ (y2
- y1
) * 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))
590 int x2
= x
+ width
- 1;
591 int y2
= y
+ height
- 1;
594 lcd_vline(x2
, y
, y2
);
596 lcd_hline(x
, x2
, y2
);
599 /* Fill a rectangular area */
600 void lcd_fillrect(int x
, int y
, int width
, int height
)
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))
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 */
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))
638 /* clip image in viewport in screen */
649 if (x
+ width
> LCD_WIDTH
)
650 width
= LCD_WIDTH
- x
;
651 if (y
+ height
> LCD_HEIGHT
)
652 height
= LCD_HEIGHT
- y
;
655 /* drawmode and optimisation */
656 if (current_vp
->drawmode
& DRMODE_INVERSEVID
)
658 if (current_vp
->drawmode
& DRMODE_BG
)
663 bits
= current_vp
->bg_pattern
;
671 if (current_vp
->drawmode
& DRMODE_FG
)
674 bits
= current_vp
->fg_pattern
;
677 if (fillopt
== OPT_NONE
&& current_vp
->drawmode
!= DRMODE_COMPLEMENT
)
681 dst_end
= dst
+ height
* LCD_WIDTH
;
685 fb_data
*dst_row
, *row_end
;
690 memset16(dst
, bits
, width
);
694 memcpy(dst
, (void *)((long)dst
+ lcd_backdrop_offset
),
695 width
* sizeof(fb_data
));
698 case OPT_NONE
: /* DRMODE_COMPLEMENT */
700 row_end
= dst_row
+ width
;
702 *dst_row
= ~(*dst_row
);
703 while (++dst_row
< row_end
);
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
,
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))
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 */
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))
753 /* clip image in viewport in screen */
766 if (x
+ width
> LCD_WIDTH
)
767 width
= LCD_WIDTH
- x
;
768 if (y
+ height
> LCD_HEIGHT
)
769 height
= LCD_HEIGHT
- y
;
772 src
+= stride
* src_y
+ src_x
; /* move starting point */
777 memcpy(dst
, src
, width
* sizeof(fb_data
));
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
)
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))
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 */
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))
833 /* clip image in viewport in screen */
846 if (x
+ width
> LCD_WIDTH
)
847 width
= LCD_WIDTH
- x
;
848 if (y
+ height
> LCD_HEIGHT
)
849 height
= LCD_HEIGHT
- y
;
852 src
+= stride
* src_y
+ src_x
; /* move starting point */
860 "mov %[w], %[width] \n" /* Load width for inner loop */
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
)
878 [sstp
]"r"(stride
- width
),
879 [dstp
]"r"(LCD_WIDTH
- width
),
880 [transcolor
]"r"(TRANSPARENT_COLOR
),
881 [fgcolor
]"r"(REPLACEWITHFG_COLOR
),
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
)
901 while (++dst_row
< row_end
);
905 while (--height
> 0);
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
);
917 * |R| |1.000000 -0.000001 1.402000| |Y'|
918 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
919 * |B| |1.000000 1.772000 0.000000| |Pr|
920 * Scaled, normalized, rounded and tweaked to yield RGB 565:
921 * |R| |74 0 101| |Y' - 16| >> 9
922 * |G| = |74 -24 -51| |Cb - 128| >> 8
923 * |B| |74 128 0| |Cr - 128| >> 9
931 static inline int clamp(int val
, int min
, int max
)
940 __attribute__((weak
)) void lcd_yuv_set_options(unsigned options
)
945 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
948 __attribute__((weak
)) void lcd_blit_yuv(unsigned char * const src
[3],
949 int src_x
, int src_y
, int stride
,
950 int x
, int y
, int width
, int height
)
952 const unsigned char *ysrc
, *usrc
, *vsrc
;
954 fb_data
*dst
, *row_end
;
957 /* width and height must be >= 2 and an even number */
959 linecounter
= height
>> 1;
961 #if LCD_WIDTH >= LCD_HEIGHT
962 dst
= &lcd_framebuffer
[y
][x
];
963 row_end
= dst
+ width
;
965 dst
= &lcd_framebuffer
[x
][LCD_WIDTH
- y
- 1];
966 row_end
= dst
+ LCD_WIDTH
* width
;
970 ysrc
= src
[0] + z
+ src_x
;
971 usrc
= src
[1] + (z
>> 2) + (src_x
>> 1);
972 vsrc
= src
[2] + (usrc
- src
[1]);
974 /* stride => amount to jump from end of last row to start of next */
977 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
983 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
985 y
= YFAC
*(*ysrc
++ - 16);
990 guv
= GUFAC
*cb
+ GVFAC
*cr
;
997 if ((unsigned)(r
| g
| b
) > 64*256-1)
999 r
= clamp(r
, 0, 64*256-1);
1000 g
= clamp(g
, 0, 64*256-1);
1001 b
= clamp(b
, 0, 64*256-1);
1004 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
1006 #if LCD_WIDTH >= LCD_HEIGHT
1012 y
= YFAC
*(*ysrc
++ - 16);
1017 if ((unsigned)(r
| g
| b
) > 64*256-1)
1019 r
= clamp(r
, 0, 64*256-1);
1020 g
= clamp(g
, 0, 64*256-1);
1021 b
= clamp(b
, 0, 64*256-1);
1024 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
1026 #if LCD_WIDTH >= LCD_HEIGHT
1032 while (dst
< row_end
);
1038 #if LCD_WIDTH >= LCD_HEIGHT
1039 row_end
+= LCD_WIDTH
;
1040 dst
+= LCD_WIDTH
- width
;
1043 dst
-= LCD_WIDTH
*width
+ 1;
1048 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
1050 y
= YFAC
*(*ysrc
++ - 16);
1055 guv
= GUFAC
*cb
+ GVFAC
*cr
;
1062 if ((unsigned)(r
| g
| b
) > 64*256-1)
1064 r
= clamp(r
, 0, 64*256-1);
1065 g
= clamp(g
, 0, 64*256-1);
1066 b
= clamp(b
, 0, 64*256-1);
1069 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
1071 #if LCD_WIDTH >= LCD_HEIGHT
1077 y
= YFAC
*(*ysrc
++ - 16);
1082 if ((unsigned)(r
| g
| b
) > 64*256-1)
1084 r
= clamp(r
, 0, 64*256-1);
1085 g
= clamp(g
, 0, 64*256-1);
1086 b
= clamp(b
, 0, 64*256-1);
1089 *dst
= LCD_RGBPACK_LCD(r
>> 9, g
>> 8, b
>> 9);
1091 #if LCD_WIDTH >= LCD_HEIGHT
1097 while (dst
< row_end
);
1100 usrc
+= stride
>> 1;
1101 vsrc
+= stride
>> 1;
1103 #if LCD_WIDTH >= LCD_HEIGHT
1104 row_end
+= LCD_WIDTH
;
1105 dst
+= LCD_WIDTH
- width
;
1108 dst
-= LCD_WIDTH
*width
+ 1;
1111 while (--linecounter
> 0);
1113 #if LCD_WIDTH >= LCD_HEIGHT
1114 lcd_update_rect(x
, y
, width
, height
);
1116 lcd_update_rect(LCD_WIDTH
- y
- height
, x
, height
, width
);
1120 #define ROW_INC LCD_WIDTH
1123 #include "lcd-16bit-common.c"
1125 #include "lcd-bitmap-common.c"