1
0
Fork 0
forked from len0rd/rockbox

Grayscale library ported to the grayscale iPods, first version. Added C reference versions of gray_update_rect() for both horizontal and vertical pixel packing. gray_update_rect() and gray_ub_gray_bitmap_part() not yet assembler optimised. Grayscale screendump doesn't work yet. * Fixed button assignments for iPod in grayscale.c

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10468 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2006-08-07 01:46:42 +00:00
parent 5375e26e51
commit c214e7bb0c
20 changed files with 1360 additions and 232 deletions

View file

@ -11,7 +11,8 @@
* Drawing functions
*
* This is a generic framework to display up to 33 shades of grey
* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins.
* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey, iPod 4-grey)
* within plugins.
*
* Copyright (C) 2004-2006 Jens Arnold
*
@ -72,8 +73,13 @@ void gray_drawpixel(int x, int y)
{
if (((unsigned)x < (unsigned)_gray_info.width)
&& ((unsigned)y < (unsigned)_gray_info.height))
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
_gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(y,
_gray_info.width) + x]);
#else
_gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(x,
_gray_info.height) + y]);
#endif
}
/* Draw a line */
@ -131,7 +137,11 @@ void gray_drawline(int x1, int y1, int x2, int y2)
{
if (((unsigned)x < (unsigned)_gray_info.width)
&& ((unsigned)y < (unsigned)_gray_info.height))
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
pfunc(&_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x]);
#else
pfunc(&_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]);
#endif
if (d < 0)
{
@ -148,6 +158,175 @@ void gray_drawline(int x1, int y1, int x2, int y2)
}
}
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
/* Draw a horizontal line (optimised) */
void gray_hline(int x1, int x2, int y)
{
int x;
int bits = 0;
unsigned char *dst;
bool fillopt = false;
void (*pfunc)(unsigned char *address);
/* direction flip */
if (x2 < x1)
{
x = x1;
x1 = x2;
x2 = x;
}
/* nothing to draw? */
if (((unsigned)y >= (unsigned)_gray_info.height)
|| (x1 >= _gray_info.width) || (x2 < 0))
return;
/* clipping */
if (x1 < 0)
x1 = 0;
if (x2 >= _gray_info.width)
x2 = _gray_info.width - 1;
if (_gray_info.drawmode & DRMODE_INVERSEVID)
{
if (_gray_info.drawmode & DRMODE_BG)
{
fillopt = true;
bits = _gray_info.bg_index;
}
}
else
{
if (_gray_info.drawmode & DRMODE_FG)
{
fillopt = true;
bits = _gray_info.fg_index;
}
}
pfunc = _gray_pixelfuncs[_gray_info.drawmode];
dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x1];
if (fillopt)
_gray_rb->memset(dst, bits, x2 - x1 + 1);
else
{
unsigned char *dst_end = dst + x2 - x1;
do
pfunc(dst++);
while (dst <= dst_end);
}
}
/* Draw a vertical line (optimised) */
void gray_vline(int x, int y1, int y2)
{
int y;
unsigned char *dst, *dst_end;
void (*pfunc)(unsigned char *address);
/* direction flip */
if (y2 < y1)
{
y = y1;
y1 = y2;
y2 = y;
}
/* nothing to draw? */
if (((unsigned)x >= (unsigned)_gray_info.width)
|| (y1 >= _gray_info.height) || (y2 < 0))
return;
/* clipping */
if (y1 < 0)
y1 = 0;
if (y2 >= _gray_info.height)
y2 = _gray_info.height - 1;
pfunc = _gray_pixelfuncs[_gray_info.drawmode];
dst = &_gray_info.cur_buffer[MULU16(y1, _gray_info.width) + x];
dst_end = dst + MULU16(y2 - y1, _gray_info.width);
do
{
pfunc(dst);
dst += _gray_info.width;
}
while (dst <= dst_end);
}
/* Draw a filled triangle */
void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
int x, y;
long fp_x1, fp_x2, fp_dx1, fp_dx2;
/* sort vertices by increasing y value */
if (y1 > y3)
{
if (y2 < y3) /* y2 < y3 < y1 */
{
x = x1; x1 = x2; x2 = x3; x3 = x;
y = y1; y1 = y2; y2 = y3; y3 = y;
}
else if (y2 > y1) /* y3 < y1 < y2 */
{
x = x1; x1 = x3; x3 = x2; x2 = x;
y = y1; y1 = y3; y3 = y2; y2 = y;
}
else /* y3 <= y2 <= y1 */
{
x = x1; x1 = x3; x3 = x;
y = y1; y1 = y3; y3 = y;
}
}
else
{
if (y2 < y1) /* y2 < y1 <= y3 */
{
x = x1; x1 = x2; x2 = x;
y = y1; y1 = y2; y2 = y;
}
else if (y2 > y3) /* y1 <= y3 < y2 */
{
x = x2; x2 = x3; x3 = x;
y = y2; y2 = y3; y3 = y;
}
/* else already sorted */
}
if (y1 < y3) /* draw */
{
fp_dx1 = ((x3 - x1) << 16) / (y3 - y1);
fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1);
if (y1 < y2) /* first part */
{
fp_dx2 = ((x2 - x1) << 16) / (y2 - y1);
fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1);
for (y = y1; y < y2; y++)
{
gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
fp_x1 += fp_dx1;
fp_x2 += fp_dx2;
}
}
if (y2 < y3) /* second part */
{
fp_dx2 = ((x3 - x2) << 16) / (y3 - y2);
fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1);
for (y = y2; y < y3; y++)
{
gray_hline(fp_x1 >> 16, fp_x2 >> 16, y);
fp_x1 += fp_dx1;
fp_x2 += fp_dx2;
}
}
}
}
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
/* Draw a horizontal line (optimised) */
void gray_hline(int x1, int x2, int y)
{
@ -244,88 +423,6 @@ void gray_vline(int x, int y1, int y2)
}
}
/* Draw a rectangular box */
void gray_drawrect(int x, int y, int width, int height)
{
if ((width <= 0) || (height <= 0))
return;
int x2 = x + width - 1;
int y2 = y + height - 1;
gray_vline(x, y, y2);
gray_vline(x2, y, y2);
gray_hline(x, x2, y);
gray_hline(x, x2, y2);
}
/* Fill a rectangular area */
void gray_fillrect(int x, int y, int width, int height)
{
int bits = 0;
unsigned char *dst, *dst_end;
bool fillopt = false;
void (*pfunc)(unsigned char *address);
/* nothing to draw? */
if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
|| (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
return;
/* clipping */
if (x < 0)
{
width += x;
x = 0;
}
if (y < 0)
{
height += y;
y = 0;
}
if (x + width > _gray_info.width)
width = _gray_info.width - x;
if (y + height > _gray_info.height)
height = _gray_info.height - y;
if (_gray_info.drawmode & DRMODE_INVERSEVID)
{
if (_gray_info.drawmode & DRMODE_BG)
{
fillopt = true;
bits = _gray_info.bg_index;
}
}
else
{
if (_gray_info.drawmode & DRMODE_FG)
{
fillopt = true;
bits = _gray_info.fg_index;
}
}
pfunc = _gray_pixelfuncs[_gray_info.drawmode];
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
dst_end = dst + MULU16(width, _gray_info.height);
do
{
if (fillopt)
_gray_rb->memset(dst, bits, height);
else
{
unsigned char *dst_col = dst;
unsigned char *col_end = dst_col + height;
do
pfunc(dst_col++);
while (dst_col < col_end);
}
dst += _gray_info.height;
}
while (dst < dst_end);
}
/* Draw a filled triangle */
void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
@ -395,6 +492,111 @@ void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
}
}
}
#endif /* LCD_PIXELFORMAT */
/* Draw a rectangular box */
void gray_drawrect(int x, int y, int width, int height)
{
if ((width <= 0) || (height <= 0))
return;
int x2 = x + width - 1;
int y2 = y + height - 1;
gray_vline(x, y, y2);
gray_vline(x2, y, y2);
gray_hline(x, x2, y);
gray_hline(x, x2, y2);
}
/* Fill a rectangular area */
void gray_fillrect(int x, int y, int width, int height)
{
int bits = 0;
unsigned char *dst, *dst_end;
bool fillopt = false;
void (*pfunc)(unsigned char *address);
/* nothing to draw? */
if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
|| (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
return;
/* clipping */
if (x < 0)
{
width += x;
x = 0;
}
if (y < 0)
{
height += y;
y = 0;
}
if (x + width > _gray_info.width)
width = _gray_info.width - x;
if (y + height > _gray_info.height)
height = _gray_info.height - y;
if (_gray_info.drawmode & DRMODE_INVERSEVID)
{
if (_gray_info.drawmode & DRMODE_BG)
{
fillopt = true;
bits = _gray_info.bg_index;
}
}
else
{
if (_gray_info.drawmode & DRMODE_FG)
{
fillopt = true;
bits = _gray_info.fg_index;
}
}
pfunc = _gray_pixelfuncs[_gray_info.drawmode];
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
dst_end = dst + MULU16(height, _gray_info.width);
do
{
if (fillopt)
_gray_rb->memset(dst, bits, width);
else
{
unsigned char *dst_row = dst;
unsigned char *row_end = dst_row + width;
do
pfunc(dst_row++);
while (dst_row < row_end);
}
dst += _gray_info.width;
}
while (dst < dst_end);
#else
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
dst_end = dst + MULU16(width, _gray_info.height);
do
{
if (fillopt)
_gray_rb->memset(dst, bits, height);
else
{
unsigned char *dst_col = dst;
unsigned char *col_end = dst_col + height;
do
pfunc(dst_col++);
while (dst_col < col_end);
}
dst += _gray_info.height;
}
while (dst < dst_end);
#endif
}
/* About Rockbox' internal monochrome bitmap format:
*
@ -403,9 +605,7 @@ void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
* vertically, LSB at top.
* The bytes are stored in row-major order, with byte 0 being top left,
* byte 1 2nd from left etc. The first row of bytes defines pixel rows
* 0..7, the second row defines pixel row 8..15 etc.
*
* This is similar to the internal lcd hw format. */
* 0..7, the second row defines pixel row 8..15 etc. */
/* Draw a partial monochrome bitmap */
void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
@ -443,9 +643,41 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
src_y &= 7;
src_end = src + width;
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
fgfunc = _gray_pixelfuncs[_gray_info.drawmode];
bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID];
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
do
{
const unsigned char *src_col = src++;
unsigned char *dst_col = dst++;
unsigned data = *src_col >> src_y;
int numbits = 8 - src_y;
dst_end = dst_col + MULU16(height, _gray_info.width);
do
{
if (data & 0x01)
fgfunc(dst_col);
else
bgfunc(dst_col);
dst_col += _gray_info.width;
data >>= 1;
if (--numbits == 0)
{
src_col += stride;
data = *src_col;
numbits = 8;
}
}
while (dst_col < dst_end);
}
while (src < src_end);
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
do
{
@ -475,6 +707,7 @@ void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
dst += _gray_info.height;
}
while (src < src_end);
#endif /* LCD_PIXELFORMAT */
}
/* Draw a full monochrome bitmap */
@ -487,7 +720,6 @@ void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, int hei
void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
const unsigned char *src_end;
unsigned char *dst, *dst_end;
/* nothing to draw? */
@ -514,25 +746,45 @@ void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
height = _gray_info.height - y;
src += MULU16(stride, src_y) + src_x; /* move starting point */
src_end = src + width;
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
dst = &_gray_info.cur_buffer[MULU16(y, _gray_info.width) + x];
dst_end = dst + MULU16(height, _gray_info.width);
do
{
const unsigned char *src_col = src++;
unsigned char *dst_col = dst;
const unsigned char *src_row = src;
unsigned char *dst_row = dst;
unsigned char *row_end = dst_row + width;
do
*dst_row++ = _gray_info.idxtable[*src_row++];
while (dst_row < row_end);
src += stride;
dst += _gray_info.width;
}
while (dst < dst_end);
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
dst_end = dst + height;
do
{
const unsigned char *src_row = src;
unsigned char *dst_row = dst++;
unsigned char *row_end = dst_row + MULU16(width, _gray_info.height);
dst_end = dst_col + height;
do
{
*dst_col++ = _gray_info.idxtable[*src_col];
src_col += stride;
*dst_row = _gray_info.idxtable[*src_row++];
dst_row += _gray_info.height;
}
while (dst_col < dst_end);
while (dst_row < row_end);
dst += _gray_info.height;
src += stride;
}
while (src < src_end);
while (dst < dst_end);
#endif /* LCD_PIXELFORMAT */
}
/* Draw a full greyscale bitmap, canonical format */
@ -612,6 +864,149 @@ void gray_ub_clear_display(void)
_gray_info.plane_size));
}
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
/* Write a pixel block, defined by their brightnesses in a greymap.
Address is the byte in the first bitplane, src is the greymap start address,
stride is the increment for the greymap to get to the next pixel, mask
determines which pixels of the destination block are changed. */
static void _writearray(unsigned char *address, const unsigned char *src,
unsigned mask)
{
unsigned long pat_stack[8];
unsigned long *pat_ptr = &pat_stack[8];
unsigned char *addr, *end;
#if 0 /* CPU specific asm versions will go here */
#else /* C version, for reference*/
unsigned test = 0x80;
int i;
/* precalculate the bit patterns with random shifts
* for all 8 pixels and put them on an extra "stack" */
for (i = 7; i >= 0; i--)
{
unsigned pat = 0;
if (mask & test)
{
int shift;
pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
/* shift pattern pseudo-random, simple & fast PRNG */
_gray_random_buffer = 75 * _gray_random_buffer + 74;
shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
if (shift >= _gray_info.depth)
shift -= _gray_info.depth;
pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
}
*(--pat_ptr) = pat;
src++;
test >>= 1;
}
addr = address;
end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
/* set the bits for all 8 pixels in all bytes according to the
* precalculated patterns on the pattern stack */
test = 1;
mask = (~mask & 0xff);
if (mask == 0)
{
do
{
unsigned data = 0;
for (i = 7; i >= 0; i--)
data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
*addr = data;
addr += _gray_info.plane_size;
test <<= 1;
}
while (addr < end);
}
else
{
do
{
unsigned data = 0;
for (i = 7; i >= 0; i--)
data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
*addr = (*addr & mask) | data;
addr += _gray_info.plane_size;
test <<= 1;
}
while (addr < end);
}
#endif
}
/* Draw a partial greyscale bitmap, canonical format */
void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
int shift, nx;
unsigned char *dst, *dst_end;
unsigned mask, mask_right;
/* nothing to draw? */
if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
|| (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
return;
/* clipping */
if (x < 0)
{
width += x;
src_x -= x;
x = 0;
}
if (y < 0)
{
height += y;
src_y -= y;
y = 0;
}
if (x + width > _gray_info.width)
width = _gray_info.width - x;
if (y + height > _gray_info.height)
height = _gray_info.height - y;
shift = x & 7;
src += MULU16(stride, src_y) + src_x - shift;
dst = _gray_info.plane_data + (x >> 3) + MULU16(_gray_info.bwidth, y);
nx = width - 1 + shift;
mask = 0xFFu >> shift;
mask_right = 0xFFu << (~nx & 7);
dst_end = dst + MULU16(_gray_info.bwidth, height);
do
{
const unsigned char *src_row = src;
unsigned char *dst_row = dst;
unsigned mask_row = mask;
for (x = nx; x >= 8; x -= 8)
{
_writearray(dst_row++, src_row, mask_row);
src_row += 8;
mask_row = 0xFFu;
}
_writearray(dst_row, src_row, mask_row & mask_right);
src += stride;
dst += _gray_info.bwidth;
}
while (dst < dst_end);
}
#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */
/* Write a pixel block, defined by their brightnesses in a greymap.
Address is the byte in the first bitplane, src is the greymap start address,
stride is the increment for the greymap to get to the next pixel, mask
@ -619,17 +1014,17 @@ void gray_ub_clear_display(void)
static void _writearray(unsigned char *address, const unsigned char *src,
int stride, unsigned mask)
{
#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
unsigned long pat_stack[8];
unsigned long *pat_ptr = &pat_stack[8];
unsigned char *addr, *end;
#if CONFIG_CPU == SH7034
const unsigned char *_src;
unsigned char *addr, *end;
unsigned _mask, trash;
_mask = mask;
_src = src;
/* precalculate the bit patterns with random shifts
/* precalculate the bit patterns with random shifts
for all 8 pixels and put them on an extra "stack" */
asm volatile (
"mov #8,r3 \n" /* loop count in r3: 8 pixels */
@ -784,11 +1179,8 @@ static void _writearray(unsigned char *address, const unsigned char *src,
: /* clobbers */
"r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
);
#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
unsigned long pat_stack[8];
unsigned long *pat_ptr = &pat_stack[8];
#elif defined(CPU_COLDFIRE)
const unsigned char *_src;
unsigned char *addr, *end;
unsigned _mask, trash;
_mask = mask;
@ -941,12 +1333,73 @@ static void _writearray(unsigned char *address, const unsigned char *src,
: /* clobbers */
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
);
#elif defined(CPU_ARM) && (LCD_DEPTH == 1)
/* TODO: implement for iFP */
(void)address;
(void)src;
(void)stride;
(void)mask;
#else /* C version, for reference*/
#warning C version of _writearray() used
unsigned test = 1;
int i;
/* precalculate the bit patterns with random shifts
* for all 8 pixels and put them on an extra "stack" */
for (i = 7; i >= 0; i--)
{
unsigned pat = 0;
if (mask & test)
{
int shift;
pat = _gray_info.bitpattern[_gray_info.idxtable[*src]];
/* shift pattern pseudo-random, simple & fast PRNG */
_gray_random_buffer = 75 * _gray_random_buffer + 74;
shift = (_gray_random_buffer >> 8) & _gray_info.randmask;
if (shift >= _gray_info.depth)
shift -= _gray_info.depth;
pat = (pat << shift) | (pat >> (_gray_info.depth - shift));
}
*(--pat_ptr) = pat;
src += stride;
test <<= 1;
}
addr = address;
end = addr + MULU16(_gray_info.depth, _gray_info.plane_size);
/* set the bits for all 8 pixels in all bytes according to the
* precalculated patterns on the pattern stack */
test = 1;
mask = (~mask & 0xff);
if (mask == 0)
{
do
{
unsigned data = 0;
for (i = 0; i < 8; i++)
data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
*addr = data;
addr += _gray_info.plane_size;
test <<= 1;
}
while (addr < end);
}
else
{
do
{
unsigned data = 0;
for (i = 0; i < 8; i++)
data = (data << 1) | ((pat_stack[i] & test) ? 1 : 0);
*addr = (*addr & mask) | data;
addr += _gray_info.plane_size;
test <<= 1;
}
while (addr < end);
}
#endif
}
@ -981,16 +1434,16 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
if (y + height > _gray_info.height)
height = _gray_info.height - y;
shift = y & (_PBLOCK-1);
shift = y & 7;
src += MULU16(stride, src_y) + src_x - MULU16(stride, shift);
dst = _gray_info.plane_data + x
+ MULU16(_gray_info.width, y >> _PBLOCK_EXP);
+ MULU16(_gray_info.width, y >> 3);
ny = height - 1 + shift;
mask = 0xFFu << shift;
mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1));
mask_bottom = 0xFFu >> (~ny & 7);
for (; ny >= _PBLOCK; ny -= _PBLOCK)
for (; ny >= 8; ny -= 8)
{
const unsigned char *src_row = src;
unsigned char *dst_row = dst;
@ -1000,7 +1453,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
_writearray(dst_row++, src_row++, stride, mask);
while (dst_row < dst_end);
src += stride << _PBLOCK_EXP;
src += stride << 3;
dst += _gray_info.width;
mask = 0xFFu;
}
@ -1010,6 +1463,7 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
_writearray(dst++, src++, stride, mask);
while (dst < dst_end);
}
#endif /* LCD_PIXELFORMAT */
#endif /* !SIMULATOR */
@ -1020,6 +1474,4 @@ void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
}
#endif /* HAVE_LCD_BITMAP */