⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 嵌入式系统
💻 C
📖 第 1 页 / 共 5 页
字号:
@@
@@ [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 + -