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

📄 dc.cpp

📁 一个完全的4级灰度的嵌入式CDC显示类。支持DC的全部操作。对于嵌入式开发是一个非常好的工具。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////
//    2001/12/06  hqf 修改HwPutString()    
//
//	byw, 2001/12/23
//		修改 CDC::DrawText() 函数
//
//////////////////////////////////////////// 
#include "dc.h"
#include "lzw.h"
#include "datadrv.h"
 
    /////////////////////////////////////////////////////////////////////
    //                                                                 //
    //           第一部分,底层做图函数                                //
    //                                                                 //
    //                                                                 //
    /////////////////////////////////////////////////////////////////////
  
 
/////////////////////////////////////////////////////////////////////
//
//  下面的底层函数需要用到的宏定义
//

#ifndef ISCC
#define  ISCC(ch)    ((ch)> 0xa0)
#endif

#ifndef SWAP
#define  SWAP(a, b)  {(a) = (a)^(b), (b)=(b)^(a), (a)=(a)^(b);}
#endif
 
//
#ifdef CIRCUMGYRATE
	//旋转情况下定义
	#define LCD_PHYWIDTH  LCD_HEIGHT
	#define LCD_PHYHEIGHT LCD_WIDTH

	#define ASC_PHY_WIDTH   16                //ASC字符的显示宽度
	#define ASC_PHY_HEIGHT  8

#else

	#define LCD_PHYWIDTH  LCD_WIDTH
	#define LCD_PHYHEIGHT LCD_HEIGHT

	#define ASC_PHY_WIDTH   8                //ASC字符的显示宽度
	#define ASC_PHY_HEIGHT  16

#endif 

void LTOP(INT16 &x, INT16 &y)
{
#ifdef CIRCUMGYRATE
  //逆时针旋转270度
  INT16 tmp = x;
  x = y;
  y = LCD_WIDTH - tmp -1;

  //逆时针旋转90度
  // tmp = x;
  // x = LCD_HEIGHT - y -1;
  // y = tmp;
  
#endif
}

void LTOP(INT16 &x0, INT16 &y0, INT16 &x1, INT16 &y1)
{ 
#ifdef CIRCUMGYRATE
	//逆时针旋转270度
	INT16 tmp =x0;
	x0 = y0;  
	y0 = LCD_WIDTH - tmp -1;
   
	tmp = x1;
	x1 = y1;
	y1 = LCD_WIDTH - tmp -1;

#endif
}
/////////////////////////////////////////////////////////////////////
//
//  下面的底层函数需要用到的全局量
// 
static UINT8  * g_pLcdBuf[LCD_HEIGHT];
const  UINT16   g_Pen16[]={0xFFFF, 0xAAAA, 0x5555, 0x0000};
const  UINT32   g_Pen32[]={0xFFFFFFFF, 0xAAAAAAAA, 0x55555555, 0x0000};
const  UINT8    g_Pen8[] = {0x0, 0x55, 0xAA, 0xFF};
const  UINT8    HeadMask[4] = {0x00, 0xC0, 0xF0, 0xFC};
const  UINT8    TailMask[4] = {0x3F, 0x0F, 0x03, 0x00};

//static UINT8    g_pVirtualScreenBuf[LCD_HEIGHT*LCD_WIDTH/4];

extern const  UINT8 g_iTwoBit2OneBitHeight[256];
extern const  UINT8 g_iTwoBit2OneBitLow[256];
extern const  UINT16 g_iOneBit2TwoBitMap[256];


/////////////////////////////////////////////////////////////////////
//
//下面所有的绘图函数中除注明入口为物理坐标系统的外其余全部为逻辑坐标系统
//
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//  void *  pSrcAddr;               // 源地址
//  UINT16  iSrcFrmWidthBytes;      // 源框架宽度(字节单位)
//  UINT16  x0;                     // 源位图横坐标(象素单位)
//  UINT16  y0;                     // 源位图纵坐标(象素单位)
//  UINT16  iWidth;                 // 位图宽度(象素单位)
//  UINT16  iHeight;                // 位图高度(象素单位)
    
//  void *  pDesAddr;               // 目的地址
//  UINT16  iDesFrmWidthBytes;      // 目的框架宽度(字节单位)
//  UINT16  x1;                     // 目的位图横坐标(象素单位)
//  UINT16  y1;                     // 目的位图纵坐标(象素单位)
//  UINT8   iDraw                   // 写数据的模式
//入口参数坐标系统为物理坐标系统
//  已知BUG:   当宽度小于4时会有问题
extern "C" void HwBitBlt(void * pSrcAddr, UINT16 iSrcFrmWidthBytes, UINT16 x0, UINT16 y0, UINT16 iWidth, UINT16 iHeight,\
                 void * pDesAddr, UINT16 iDesFrmWidthBytes, UINT16 x1, UINT16 y1, UINT8 iDrawMode)
{
        
    UINT8 * from = (UINT8*)(pSrcAddr + (iSrcFrmWidthBytes * y0) + (x0 >> 2));
    UINT8 * to = (UINT8*)(pDesAddr + (iDesFrmWidthBytes * y1) + (x1 >> 2));
    UINT8   bit0 = x0&3, bit1 = x1&3;
    UINT16  bw1  = ((x1 + iWidth - 1) >> 2) - (x1 >> 2) + 1;
    UINT8   hmask0 = HeadMask[bit1];
    UINT8   hmask1 = ~hmask0;
    UINT8   tmask0 = TailMask[(x1 + iWidth - 1) &3];
    UINT8   tmask1 = ~tmask0;
    INT8    dir = bit0 - bit1;                          // 移位方向,0 不移,> 0 左移,< 0 右移
    UINT8   shift0 = (((dir >= 0) ? dir : dir+4) << 1); // 移位次数
    UINT8   shift1 = 8 - shift0;                        // 反向移位次数
   switch(iDrawMode)
   {
   case DRAWMODE_REP:
    while(iHeight--)
    {
        UINT8 *from1 = from;
        UINT8 *to1 = to;
        UINT8 *to2 = to + bw1 - 1;
        UINT8 head = *to1;
        UINT8 tail = *to2;
        if (!dir)
        {
            memcpy(to1, from1, bw1);
        }
        else
        {
            UINT8 op0 = *from1;
            if (dir > 0)
                from1 ++;
            for(UINT16 i = 0; i < bw1; i ++)
            {
                UINT8 op1 = *from1;
                *to1 = (op0 << shift0) | (op1 >> shift1);
                op0 = op1;
                from1 ++;
                to1 ++;
            }
        }
        *to = (head & hmask0) | (*to & hmask1);
        *to2 = (tail & tmask0) | (*to2 & tmask1);
        from += iSrcFrmWidthBytes;
        to += iDesFrmWidthBytes;
    } // end while(iHeight--)
    break;
   case DRAWMODE_AND:
        while(iHeight--)
    {
        UINT8 *from1 = from;
        UINT8 *to1 = to;
        UINT8 *to2 = to + bw1 - 1;
        UINT8 head = *to1;
        UINT8 tail = *to2;
        if (!dir)
        {
            for(INT16 i=0; i<bw1; i++, to1++, from1++)
                *to1 &= *from1;
        }
        else
        {
            UINT8 op0 = *from1;
            if (dir > 0)
                from1 ++;
            for(UINT16 i = 0; i < bw1; i ++, from1++, to1++)
            {
                UINT8 op1 = *from1;
                *to1 &= ((op0 << shift0) | (op1 >> shift1));
                op0 = op1;
            }
        }
        *to  = head & (*to|hmask0); 
        *to2 = tail & (*to2|tmask0);
        from += iSrcFrmWidthBytes;
        to += iDesFrmWidthBytes;
    } // end while(iHeight--)
       break;
   case DRAWMODE_OR:
        while(iHeight--)
        {
            UINT8 *from1 = from;
            UINT8 *to1 = to;
            UINT8 *to2 = to + bw1 - 1;
            UINT8 head = *to1;
            UINT8 tail = *to2;
            if (!dir)
            {
                for(INT16 i=0; i<bw1; i++, to1++, from1++)
                    *to1 |= *from1;
            }
            else
            {
                UINT8 op0 = *from1;
                if (dir > 0)
                    from1 ++;
                for(UINT16 i = 0; i < bw1; i ++, from1++, to1++)
                {
                    UINT8 op1 = *from1;
                    *to1 |= ((op0 << shift0) | (op1 >> shift1));
                    op0 = op1;
                }
            }
            *to  = head | (*to&hmask1); 
            *to2 = tail | (*to2&tmask1);
            from += iSrcFrmWidthBytes;
            to += iDesFrmWidthBytes;
        } // end while(iHeight--)
       break;
   case DRAWMODE_XOR:
       while(iHeight--)
        {
            UINT8 *from1 = from;
            UINT8 *to1 = to;
            UINT8 *to2 = to + bw1 - 1;
            UINT8 head = *to1;
            UINT8 tail = *to2;
            if (!dir)
            {
                for(INT16 i=0; i<bw1; i++, to1++, from1++)
                    *to1 ^= *from1;
            }
            else
            {
                UINT8 op0 = *from1;
                if (dir > 0)
                    from1 ++;
                for(UINT16 i = 0; i < bw1; i ++, from1++, to1++)
                {
                    UINT8 op1 = *from1;
                    *to1 |= ((op0 << shift0) | (op1 >> shift1));
                    op0 = op1;
                }
            }
            *to  = ((head^*to) &hmask1)  | (*to&hmask0); 
            *to2 = ((tail^*to2)&tmask1) | (*to2&tmask0);
            from += iSrcFrmWidthBytes;
            to += iDesFrmWidthBytes;
        }
       break;
   }
}   
    


//清除屏幕
extern "C" void HwClearDevice(UINT8 iColor)
{
   memset(g_pLcdBuf[0], g_Pen8[iColor&3], LCD_WIDTH/4*LCD_HEIGHT);
}
 
//初始化图形系统
extern "C" void HwInitGraphicsSystem()
{
   *(UINT32 *)0xFFFFFA00 = LCD_SCREEN_BUF_ADDR;
   *(UINT8 *)0xFFFFFA05 = LCD_WIDTH/8;
   *(UINT16 *)0xFFFFFA08 = LCD_WIDTH;
   *(UINT16 *)0xFFFFFA0A = LCD_HEIGHT-1;
   *((UINT16 *)0xFFFFFA18) = 0x8000;
   *((UINT16 *)0xFFFFFA1A) = 0x0000;
   *(UINT8 *)0xFFFFFA20  = 9;
   *(UINT8 *)0xFFFFFA21  = 1;
   *(UINT8 *)0xFFFFFA23  = 0;
   *(UINT8 *)0xFFFFFA25 |= 0x0A;
   *(UINT8 *)0xFFFFFA29 = 0x14;
   UINT8 * addr = (UINT8 *)(*((UINT32 *)0xFFFFFA00)); 
   for(INT16 i=0; i< LCD_HEIGHT; i++, addr += LCD_WIDTH/4)
        g_pLcdBuf[i] = addr;
   HwClearDevice(WHITE);
}

extern "C" INT8 HwGetPixel(INT16 x, INT16 y)
{
	LTOP(x, y);
    if(x<0 || y<0 || x>=LCD_WIDTH || y>=LCD_HEIGHT)
        return -1;
    UINT8 bit = 6-((x&3)<<1);
    INT8 byte = *((INT8 *)g_pLcdBuf[y] + (x>>2));
    return (byte>>bit)&3;
}

//在指定位置用指定颜色、宽度、作图模式、写一个点
extern "C" void HwSetPixel(INT16 iX, INT16 iY, UINT8 iColor, UINT8 iDrawMode, UINT8 iSize)
{
	LTOP(iX, iY);
    if(iX+iSize >LCD_WIDTH || iY+iSize >LCD_HEIGHT || iX <0 || iY < 0)
        return;
    UINT8 mask[]={0x3F, 0xCF, 0xF3, 0xFC};
    INT8 off = iX>>2;
    INT8 bit1= iX&3;
    UINT8 * addr = g_pLcdBuf[iY] + off;
    switch(iDrawMode)
    {
        
        case DRAWMODE_REP: 
             for(UINT8 i=0; i< iSize; i++,iY++)
              {
                 UINT8 * addr = g_pLcdBuf[iY] + off;
                 UINT8   bit = bit1;
                 for(UINT8 j=0; j<iSize; j++)
                 {
                  *addr = (*addr & mask[bit]) | (iColor<<(6-(bit<<1)));
                  if(++bit>3)
                     addr++, bit=0;
                 }
             } 
            break;
        case DRAWMODE_AND:
              for(UINT8 i=0; i< iSize; i++,iY++)
              {
                 UINT8 * addr = g_pLcdBuf[iY] + off;
                 UINT8   bit = bit1;
                 for(UINT8 j=0; j<iSize; j++)
                 {
                  *addr &= ((iColor<<(6-(bit<<1))) | mask[bit]);
                  if(++bit>3)
                     addr++, bit=0;
                 }
              }
             break;
        case DRAWMODE_OR:
             for(UINT8 i=0; i< iSize; i++,iY++)
              {
                 UINT8 * addr = g_pLcdBuf[iY] + off;
                 UINT8   bit = bit1;
                 for(UINT8 j=0; j<iSize; j++)
                 {
                  *addr |= (iColor<<(6-(bit<<1)));
                  if(++bit>3)
                     addr++, bit=0;
                 }
              }
            break;

       case DRAWMODE_XOR:
            for(UINT8 i=0; i< iSize; i++,iY++)
              {
                 UINT8 * addr = g_pLcdBuf[iY] + off;
                 UINT8   bit = bit1;
                 for(UINT8 j=0; j<iSize; j++)
                 {
                  *addr ^= (iColor<<(6-(bit<<1)));
                  if(++bit>3)
                     addr++, bit=0;
                 }
              }
            break;

    }
}

//从x0,y0到x1,y1画一条直线,颜色、模式、宽度由iColor,iAttrib,iSize决定
extern "C" void HwLine(INT16 x0, INT16 y0, INT16 x1, INT16 y1, 
                      UINT8 iColor, UINT8 iAttrib, UINT8 iSize, UINT8 iLineStyle)
{
    
    INT16  dx = ABS(x1-x0), dy = ABS(y1-y0);
    INT16  x=x0, y=y0;
    INT16  e= (dx>=dy) ? -dx : -dy;
    INT16  stepx = (x1>x0)?1:-1, stepy = (y1>y0)?1:-1;
    UINT16 dot = 0;
    UINT16 swidth = iLineStyle + iSize;
    if(dx>=dy)
      for(INT16 i=0; i<=dx; i++)
      {
         if(!iLineStyle)
            HwSetPixel(x, y, iColor, iAttrib, iSize);
         else if(dot++ < iLineStyle)
            HwSetPixel(x, y, iColor, iAttrib, iSize);
         else if(dot++ > swidth) 
             dot =0;

         x += stepx;
         e=e+(dy<<1); 
         if(e>=0)
         {
             y += stepy;
             e=e-(dx<<1);
         }  
      }
    else
      for(INT16 i=0; i<=dy; i++)
      {
         if(!iLineStyle)
            HwSetPixel(x, y, iColor, iAttrib, iSize);
         else if(dot++ < iLineStyle)
            HwSetPixel(x, y, iColor, iAttrib, iSize);
         else if(dot++ > swidth) 
             dot =0;

         y += stepy;
         e=e+(dx<<1); 
         if(e>=0)
         {
           x += stepx;
           e=e-(dy<<1);
         } 
      }
    
}

//画一个椭圆
extern "C" void HwEllipse(INT16 left, INT16 top, INT16 right, INT16 bottom, UINT8 iColor, UINT8 iDrawMode, UINT8 iPenWidth)
{
    INT16 x0 = (right+left)>>1;
    INT16 y0 = (bottom+top)>>1;
    INT16 x1 = ABS(right-left)>>1;
    INT16 y1 = ABS(bottom-top)>>1;

    INT16 x=0, y =y1;

    INT32 a2 = (x1)*(x1);
    INT32 b2 = y1*y1;

    INT32 _2a2 = a2<<1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -