?? lcd.c
字號:
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
void apd_LCDDrawHline(APD_LCD_POINT *sp,APD_LCD_POINT *ep)
{
APD_LCD_POINT p1, p2;
unsigned long *adrs, *xadrs, *yadrs;/* The address to write pixel data */
unsigned char hword, byte, bit; /* Half word, byte, bit offset */
unsigned char bit_mask;
short size;
APD_LCD_POINT vp1, vp2;
unsigned long y;
//#if (APD_LCD_BPP <= 8)
// unsigned char lp_bak = current_line_pat;
//#endif
/* Exchange the start point for the end point */
if (sp->x > ep->x) {
p1.x = ep->x;
p1.y = ep->y;
p2.x = sp->x;
p2.y = sp->y;
} else {
p1.x = sp->x;
p1.y = sp->y;
p2.x = ep->x;
p2.y = ep->y;
}
/* Check the area to draw */
/* Include the start point */
if (p1.y < 0 || p1.x >= APD_LCD_WIDTH || p1.y >= APD_LCD_HEIGHT ||
p2.x < 0)
return;
if (p1.x < 0)
p1.x = 0;
if (p2.x >= APD_LCD_WIDTH)
p2.x = APD_LCD_WIDTH - 1;
/* Set line type pattern */
bit_mask = LCD_PAT_MASK;
size = p2.x - p1.x + 1;
/* case of less than 1 line width */
if (current_gc.lw <= 1) {
vp1.y = p1.y;
vp2.y = vp1.y + 1;
} else {
/* Set vertical line for line width */
if (p1.y < (current_gc.lw >> 1))
vp1.y = 0;
else
vp1.y = p1.y - (current_gc.lw >> 1);
vp2.y = p1.y + (current_gc.lw >> 1) + (current_gc.lw & 0x01);
}
LCDGetXOffsetAdrs(p1.x, &xadrs, &hword, &byte, &bit);
for (y = vp1.y; y < vp2.y; y++) {
/* Get the address to write pixel data */
LCDGetYAdrs(y, &yadrs);
#if ((APD_LCD_WIDTH*APD_LCD_BPP % 32) != 0)
if (((unsigned long)yadrs % 4) != 0)
hword = (0 == hword) ? 1 : 0;
#endif
adrs = (unsigned long *)((unsigned long *)yadrs + (unsigned long)xadrs);
if (((current_gc.rop == APD_LCD_ROP_S) ||
(current_gc.rop == APD_LCD_ROP_nS)) &&
(current_gc.lt == APD_LCD_LINE_SOLID))
{
unsigned long color;
if (current_gc.rop == APD_LCD_ROP_nS)
color = ~current_gc.c;
else
color = current_gc.c;
LCDOverwriteHline(adrs, hword, byte, bit, size, color);
}
/* If raster operation is others */
else
{
LCDFillHline(adrs, hword, byte, bit, size);
}
}
return;
}
#if (APD_LCD_BPP <= 8)
/******************************************************************************
@@
@@ [Name] : LCDDrawHline
@@
@@ [Summary] : Draw horizontal line
@@
@@ [Argument] : adrs : Address of horizontal line
@@ hword : Half word offset of address
@@ byte : Byte offset of address
@@ bit : Bit offset of address
@@ size : Data size which fill
@@
@@ [Return] : None
@@
@@ [Desc] : Draw horizontal line according to current fill pattern
@@ at the time of 'fill rect'. When APD_LCD_BPP is less than
@@ 8, this function is used.
@@ Valid attribute : Color, Raster opertaion, Line pattern
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
static void LCDDrawHline
(
unsigned short *adrs,
unsigned char hword,
unsigned char byte,
unsigned char bit,
short size
)
{
#if (APD_LCD_BPP == 8)
unsigned long mask;
unsigned long pat = 0;
unsigned long l_color = (unsigned long)(((current_gc.c & 0xFF) << 24) |
((current_gc.c & 0xFF) << 16) |
((current_gc.c & 0xFF) << 8) |
(current_gc.c & 0xFF));
unsigned long bufsize;
unsigned long *xadrs;
bufsize = size;
/* Measures 32 bit boundary */
if (hword) {
adrs--;
bufsize += 2;
}
while (bufsize & 0x03)
bufsize++;
/* Copy the current data of the address to LineData buffer */
LCDMemcpyWord((unsigned long *)LineData, (unsigned long *)adrs,
(unsigned long)(bufsize >> 2));
/* Mask and raster operate each pixel */
xadrs = (unsigned long *)LineData;
if (hword || byte) {
unsigned char i = 4;
mask = LCD_HLINE_PAT[current_line_pat][pat];
pat ^= 1;
if (mask) {
if (hword) {
i -= 2;
#ifdef APD_LCD_LEBO
mask <<= 2 * BITS_PER_BYTE;
#else
mask >>= 2 * BITS_PER_BYTE;
#endif
}
if (byte) {
i -= 1;
#ifdef APD_LCD_LEBO
mask <<= BITS_PER_BYTE;
#else
mask >>= BITS_PER_BYTE;
#endif
}
if (size < i) {
unsigned long r_mask = 0xFFFFFFFF;
#ifdef APD_LCD_LEBO
r_mask >>= APD_LCD_BPP * (i - size);
#else
r_mask <<= APD_LCD_BPP * (i - size);
#endif
i = size;
mask &= r_mask;
}
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
}
xadrs++;
size -= i;
}
while (size >> 2) {
mask = LCD_HLINE_PAT[current_line_pat][pat];
pat ^= 1;
if (mask)
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
xadrs++;
size -= 4;
}
if (size) {
unsigned long r_mask = 0xFFFFFFFF;
mask = LCD_HLINE_PAT[current_line_pat][pat];
if (mask) {
#ifdef APD_LCD_LEBO
r_mask >>= (BITS_PER_BYTE * (4 - size));
#else
r_mask <<= (BITS_PER_BYTE * (4 - size));
#endif
mask &= r_mask;
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
}
}
/* Copy one horizontal line data on memory */
LCDMemcpyWord((unsigned long *)adrs, (unsigned long *)LineData,
(unsigned long)(bufsize >> 2));
#endif /* APD_LCD_BPP == 8 */
#if (APD_LCD_BPP < 8)
/*
If APD_LCD_BPP is less than 4BPP, access to memory by a byte unit.
So if byte endian and pixel endian of LCD controller is little endian,
the address to write pixel data isn't controlled.
But if ones of them is also big endian, the one is controlled in front and
behind.
*/
unsigned long *xadrs;
unsigned long bufsize;
unsigned long l_color;
unsigned char b_color;
unsigned long mask; /* Mask for raster operation */
#if (APD_LCD_BPP == 4)
b_color = (unsigned char)((current_gc.c << 4) | current_gc.c);
#endif /* APD_LCD_BPP == 4 */
#if (APD_LCD_BPP == 2)
b_color = (unsigned char)((current_gc.c << 6) | (current_gc.c << 4) |
(current_gc.c << 2) | current_gc.c);
#endif /* APD_LCD_BPP == 2 */
#if (APD_LCD_BPP == 1)
if (current_gc.c)
b_color = 0xFF;
else
b_color = 0;
#endif /* APD_LCD_BPP == 1 */
l_color = (unsigned long)((b_color << 24) | (b_color << 16) |
(b_color << 8) | b_color);
bufsize = size;
/* Measures 32 bit boundary */
if (bit)
bufsize += bit / APD_LCD_BPP;
if (byte)
bufsize += BITS_PER_BYTE / APD_LCD_BPP;
if (hword) {
adrs--;
bufsize += 2 * BITS_PER_BYTE / APD_LCD_BPP;
}
while ((bufsize * APD_LCD_BPP) % 32)
bufsize++;
/* Copy the current data of the address to LineData buffer */
LCDMemcpyWord((unsigned long *)LineData, (unsigned long *)adrs,
(unsigned long)(bufsize * APD_LCD_BPP) >> 5);
/* Mask and raster operate each pixel */
xadrs = (unsigned long *)LineData;
while ((hword || byte || bit) && size) {
unsigned long r_mask = LCD_BYTE_MASK;
mask = LCD_HLINE_PAT[current_line_pat];
#ifdef APD_LCD_LEBO
if (hword)
r_mask <<= 2 * BITS_PER_BYTE;
if (byte)
r_mask <<= BITS_PER_BYTE;
#else
if (!hword)
r_mask <<= 2 * BITS_PER_BYTE;
if (!byte)
r_mask <<= BITS_PER_BYTE;
#endif
#ifdef APD_LCD_LEPO
r_mask <<= bit;
#else
r_mask <<= (LCD_BYTE_MAX - bit);
#endif /* APD_LCD_LEPO */
mask &= r_mask;
if (mask)
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
size--;
bit += APD_LCD_BPP;
if (bit == BITS_PER_BYTE) {
if (byte) {
if (hword)
xadrs++;
hword ^= 1;
}
byte ^= 1;
bit = 0;
}
}
while ((size * APD_LCD_BPP) >> 5) {
mask = LCD_HLINE_PAT[current_line_pat];
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
xadrs++;
size -= BITS_PER_LONG / APD_LCD_BPP;
}
while (size) {
unsigned long r_mask = LCD_BYTE_MASK;
mask = LCD_HLINE_PAT[current_line_pat];
#ifdef APD_LCD_LEBO
if (hword)
r_mask <<= 2 * BITS_PER_BYTE;
if (byte)
r_mask <<= BITS_PER_BYTE;
#else
if (!hword)
r_mask <<= 2 * BITS_PER_BYTE;
if (!byte)
r_mask <<= BITS_PER_BYTE;
#endif /* APD_LCD_LEBO */
#ifdef APD_LCD_LEPO
r_mask <<= bit;
#else
r_mask <<= (LCD_BYTE_MAX - bit);
#endif /* APD_LCD_LEPO */
mask &= r_mask;
if (mask)
LCDSetPixelByWordWithMask(xadrs, l_color & mask, mask);
size--;
bit += APD_LCD_BPP;
if (bit == BITS_PER_BYTE) {
if (byte)
hword ^= 1;
byte ^= 1;
bit = 0;
}
}
LCDMemcpyWord((unsigned long *)adrs, (unsigned long *)LineData,
(unsigned long)(bufsize * APD_LCD_BPP) >> 5);
#endif /* APD_LCD_BPP < 8 */
}
#endif /* APD_LCD_BPP <= 8 */
/******************************************************************************
@@
@@ [Name] : LCDFillHline
@@
@@ [Summary] : The function to draw over horizontal line
@@
@@ [Argument] : adrs : Address of horizontal line
@@ hword : Half word offset of address
@@ byte : Byte offset of address
@@ bit : Bit offset of address
@@ size : Data size which fill
@@
@@ [Return] : None
@@
@@ [Desc] : Draw over the specific horizontal line according to
@@ the current attribute.
@@ Valid attribute : Color, Raster operation, Line pattern
@@
@@ [History] : Date Modifier Comment
@@
@@ [END]
******************************************************************************/
static void LCDFillHline( unsigned long *adrs, unsigned char hword, unsigned char byte, unsigned char bit, short size)
{
/*
If APD_LCD_BPP is 16BPP, access to memory by a half word unit.
So if LCD byte endian is little endian, the half word address
to write pixel data isn't controlled.
But if it is big endian, the one is controlled in front and behind.
*/
unsigned long *xadrs;
unsigned long bufsize;
unsigned char bit_mask;
unsigned long i;
unsigned long *padrs;
bufsize = size;
bit_mask = LCD_PAT_MASK;
/* Copy the current data of the address to LineData buffer */
/* Take measures of 32 bit boundary */
if (hword) {
adrs--;
bufsize++;
}
if (bufsize & 0x01)
bufsize++;
LCDMemcpyWord((unsigned long *)LineData, (unsigned long *)adrs,
(unsigned long)(bufsize >> 1));
/* Mask and raster operate each pixel */
xadrs = (unsigned long *)LineData;
if (hword)
xadrs++;
for (i = 0; i < size; i++) {
if (current_line_pat & bit_mask) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -