📄 dc.cpp
字号:
////////////////////////////////////////////
// 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 + -