📄 display.c
字号:
/*-----------------------------------------------------------------------------
#说明: 绘图函数,包括与硬件无关的缓冲区绘图函数
#接口函数
#define SetPixel(pdc, x, y, color) Buffer_SetPixel(pdc, x, y, color)
#define ClearScreen() Buffer_ClearScreen()
#define MoveTo( pdc, x, y) Buffer_MoveTo( pdc, x, y)
#define LineTo( pdc,x, y) Buffer_LineTo( pdc,x, y)
#define DrawSBresenham_Line( pdc, x1, y1, x2, y2) Buffer_DrawSBresenham_Line( pdc, x1, y1, x2, y2)
#define FillRect(pdc, left,top , right, bottom,DrawMode, color) Buffer_FillRect(pdc, left,top , right, bottom,DrawMode, color)
#define FillRect2( pdc, rect,DrawMode,color) Buffer_FillRect2( pdc, rect,DrawMode,color)
#define Circle( pdc,x0,y0, r) Buffer_Circle( pdc,x0,y0, r)
#define CharactorOut( pdc, x, y, ch, bunicode, fnt) Buffer_CharactorOut( pdc, x, y, ch, bunicode, fnt)
#define CharactorOutRect( pdc, x, y, prect, ch, bunicode, fnt) Buffer_CharactorOutRect( pdc, x, y, prect, ch, bunicode, fnt)
#define TextOut(pdc, x, y, ch, bunicode, fnt) Buffer_TextOut(pdc, x, y, ch, bunicode, fnt)
#define DrawRectFrame( pdc, left, top , right, bottom) Buffer_DrawRectFrame( pdc, left, top , right, bottom)
#define DrawRectFrame2(pdc, rect) Buffer_DrawRectFrame2(pdc, rect)
#define Draw3DRect( pdc, left, top, right,bottom,color1,color2) Buffer_Draw3DRect( pdc, left, top, right,bottom,color1,color2)
#define ArcTo1(pdc, x1, y1, R) Buffer_ArcTo1(pdc, x1, y1, R)
#define ArcTo2(pdc, x1, y1, R) Buffer_ArcTo2(pdc, x1, y1, R)
#define ArcTo(pdc, x1, y1, arctype, R) Buffer_ArcTo(pdc, x1, y1, arctype, R)
#define ShowBmp( pdc, filename, x, y) Buffer_ShowBmp( pdc, filename, x, y)
#依赖关系:
#include "../inc/drv/figure.h"
#include "..\ucos-ii\includes.h"
#include "..\inc\drv\lcd320.h"
#include "..\inc\drv\loadfile.h"
#include "..\inc\drv\display.h"
#include "..\inc\maro.h"
#include "..\inc\OSFile.h"
---------------------------------- Bug --------------------------------------
---------------------------------- TODO list --------------------------------------
----------------------------------修正--------------------------------------
2003-6-13 函数通过宏定义实现与底层绘图(是否使用Direct)分隔;
------------------------------------------------------------------------------
-----------------------------------------------------------------------------------*/
#include "..\ucos-ii\includes.h"
#include "..\inc\drv\lcd320.h"
#include "..\inc\drv\loadfile.h"
#include "..\inc\drv\display.h"
#include "..\inc\maro.h"
#include "..\inc\drv\OSFile.h"
#include <math.h>
extern U8 UFont12[256][12]; //半字宽12x12字符
extern U8 UCFont12[21312][24]; //全字宽12x12字符
extern U8 UFont16[256][16]; //半字宽16x16字符
extern U8 UCFont16[21312][32]; //全字宽16x16字符
extern U8 UFont24[256][48]; //半字宽24x24字符
extern U8 UCFont24[21312][72]; //全字宽24x24字符
extern U32 LCDBuffer[LCDHEIGHT][LCDWIDTH];
extern U32 sucloadedfile;
extern OS_EVENT *Lcd_Disp_Sem;
extern OS_EVENT *LCDFresh_MBox;
int OSFontSize[]={0,12,16,24};
#define DCMemPartBlk (sizeof(DC)+4)
OS_MEM *pDCMem;
INT8U DCMemPart[100][DCMemPartBlk];
void initOSDC()
{
INT8U err;
pDCMem=OSMemCreate(DCMemPart,100, DCMemPartBlk, &err);
if(pDCMem==NULL){
Uart_Printf("Failed to Create DC quote");
LCD_printf("Failed to Create DC quote");
}
}
PDC CreateDC()
{
INT8U err;
PDC pdc;
pdc=(PDC)OSMemGet(pDCMem,&err);
pdc->DrawPointx=pdc->DrawPointy=0;//绘图所使用的坐标点
pdc->PenWidth=1; //画笔宽度
pdc->PenMode=GRAPH_MODE_NORMAL; //画笔模式
pdc->PenColor=COLOR_BLACK; //画笔的颜色
pdc->DrawOrgx=0; //绘图的坐标原点位置
pdc->DrawOrgy=0;
pdc->WndOrgx=pdc->WndOrgy=0;
pdc->DrawRangex=LCDWIDTH; //绘图的区域范围
pdc->DrawRangey=LCDHEIGHT;
SetRect(&pdc->DrawRect, 0,0,LCDWIDTH-1,LCDHEIGHT-1);
pdc->bUpdataBuffer=TRUE; //是否更新后台缓冲区及显示
pdc->Fontcolor=COLOR_BLACK;
return pdc;
}
void DestoryDC(PDC pdc)
{
OSMemPut(pDCMem, pdc);
}
void Buffer_SetPixel(PDC pdc, int x, int y, COLORREF color)
{
static int oldx=0,oldy=0;
static U32 oldpenMode=0xffffffff;
x*=LCDWIDTH;
x/=pdc->DrawRangex;
y*=LCDHEIGHT;
y/=pdc->DrawRangey;
x+=pdc->DrawOrgx+pdc->WndOrgx;
y+=pdc->DrawOrgy+pdc->WndOrgy;
if(oldy==y && oldx==x && oldpenMode==pdc->PenMode)
return;
oldy=y;
oldx=x;
oldpenMode=pdc->PenMode;
if(IsInRect(&pdc->DrawRect, x, y)){
switch(pdc->PenMode){
case GRAPH_MODE_NORMAL:
LCDBuffer[y][x]=color;
break;
case GRAPH_MODE_OR:
LCDBuffer[y][x]|=color;
break;
case GRAPH_MODE_AND:
LCDBuffer[y][x]&=color;
break;
case GRAPH_MODE_XOR:
LCDBuffer[y][x]^=color;
break;
case GRAPH_MODE_NOR:
LCDBuffer[y][x]=~(LCDBuffer[y][x]|color);
break;
}
}
}
void SetPixelOR(PDC pdc,int x, int y, COLORREF color)
{
x*=LCDWIDTH;
x/=pdc->DrawRangex;
y*=LCDHEIGHT;
y/=pdc->DrawRangey;
x+=pdc->DrawOrgx+pdc->WndOrgx;
y+=pdc->DrawOrgy+pdc->WndOrgy;
if(IsInRect(&pdc->DrawRect, x, y))
LCDBuffer[y][x]|=color;
}
void SetPixelAND(PDC pdc,int x, int y, COLORREF color)
{
x*=LCDWIDTH;
x/=pdc->DrawRangex;
y*=LCDHEIGHT;
y/=pdc->DrawRangey;
x+=pdc->DrawOrgx+pdc->WndOrgx;
y+=pdc->DrawOrgy+pdc->WndOrgy;
if(IsInRect(&pdc->DrawRect, x, y))
LCDBuffer[y][x]&=color;
}
void SetPixelXOR(PDC pdc, int x, int y, COLORREF color)
{
x*=LCDWIDTH;
x/=pdc->DrawRangex;
y*=LCDHEIGHT;
y/=pdc->DrawRangey;
x+=pdc->DrawOrgx+pdc->WndOrgx;
y+=pdc->DrawOrgy+pdc->WndOrgy;
if(IsInRect(&pdc->DrawRect, x, y))
LCDBuffer[y][x]^=color;
}
int GetFontHeight(U8 fnt)
{
return OSFontSize[fnt&0x03];
}
int GetFontWidth(U16 ch, U8 fnt)
{
if(ch<=0xff)
return OSFontSize[fnt&0x03]/2;
return OSFontSize[fnt&0x03];
}
int GetUStrFontWidth(U16 str[], U8 fnt)
{
int length=0;
for(;(*str)!=0;str++){
length+=GetFontWidth(*str,fnt);
}
return length;
}
///////////获得指向字符首地址的指针////////////////
/////////////pChfont返回的指向字符首地址的指针
/////////////size字符的大小(点数)
/////////////ch字符编码
/////////////bunicode编码类型,是否是Unicode编码
////////////fnt 字体的大型号为FONTSIZE_SMALL FONTSIZE_MIDDLE FONTSIZE_BIG
void GetChPointer(U8** pChfont, structSIZE* size, U16 ch, U8 bunicode,U8 fnt)
{
if(bunicode){ //显示UNICODE字符集
if(ch<256){ //ASCII字符
size->cy=OSFontSize[fnt&0x03];
size->cx=size->cy/2;
switch(fnt&0x03){
case FONTSIZE_SMALL:
if(sucloadedfile|LOADU12FONT){
*pChfont=UFont12[ch];
}
return;
case FONTSIZE_MIDDLE:
if(sucloadedfile|LOADU16FONT){
*pChfont=UFont16[ch];
}
return;
case FONTSIZE_BIG:
if(sucloadedfile|LOADU24FONT){
*pChfont=UFont24[ch];
}
}
return;
}
//全宽度字符
if(ch<0x2680)//特殊字符1
ch-=0x2600;
else if(ch<0x27c0)//特殊字符2
ch-=0x2700-0x80;
else if(ch<0xa000)//汉字
ch-=0x4e00-0x80-0xc0;
else//未定义字符
ch=0x9fff-0x4e00+0x80+0xc0;
size->cx=size->cy=OSFontSize[fnt&0x03];
switch(fnt&0x03){
case FONTSIZE_SMALL:
if(sucloadedfile|LOADU12FONT){
*pChfont=UCFont12[ch];
}
return;
case FONTSIZE_MIDDLE:
if(sucloadedfile|LOADU16FONT){
*pChfont=UCFont16[ch];
}
return;
case FONTSIZE_BIG:
if(sucloadedfile|LOADU24FONT){
*pChfont=UCFont24[ch];
}
}
}
}
void Buffer_CharactorOut(PDC pdc, int* x, int* y, U16 ch, U8 bunicode, U8 fnt) //显示单个字符
{
U8 *pfont;
U8 nxbyte;//字符的水平占用的字节数
U32 i,j,k,fntclr;
INT8U err;
structSIZE size;
GetChPointer(&pfont, &size, ch, bunicode, fnt);
nxbyte=size.cx/8;
if(size.cx%8)
nxbyte++;
OSSemPend(Lcd_Disp_Sem,0, &err);
switch(fnt&0xc){
case FONT_TRANSPARENT: //透明背景
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if((pfont[i*nxbyte+j/8]>>k)&0x1)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixelOR(pdc, j+(*x),i+(*y),fntclr);
k--;
k&=0x7;
}
}
break;
case FONT_BLACKBK: //黑底白字
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if((~(pfont[i*nxbyte+j/8]>>k))&0x01)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixel(pdc,j+(*x),i+(*y),fntclr);
k--;
k&=0x7;
}
}
break;
default: //正常模式
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if((pfont[i*nxbyte+j/8]>>k)&0x01)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixel(pdc,j+(*x),i+(*y),fntclr);
k--;
k&=0x7;
}
}
}
OSSemPost(Lcd_Disp_Sem);
(*x)+=size.cx;
}
void Buffer_CharactorOutRect(PDC pdc, int* x, int* y, structRECT* prect ,U16 ch, U8 bunicode, U8 fnt) //在指定矩形的范围内显示单个字符
{
U8 *pfont;
U8 nxbyte;//字符的水平占用的字节数
U32 i,j,k,fntclr;
INT8U err;
structSIZE size;
GetChPointer(&pfont, &size, ch, bunicode, fnt);
nxbyte=size.cx/8;
if(size.cx%8)
nxbyte++;
OSSemPend(Lcd_Disp_Sem,0, &err);
switch(fnt&0xc){
case FONT_TRANSPARENT: //透明背景
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if(IsInRect(prect, j+(*x), i+(*y))){
if((pfont[i*nxbyte+j/8]>>k)&0x01)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixelOR(pdc,j+(*x),i+(*y),fntclr);
}
k--;
k&=0x7;
}
}
break;
case FONT_BLACKBK: //黑底白字
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if(IsInRect(prect, j+(*x), i+(*y))){
if((~(pfont[i*nxbyte+j/8]>>k))&0x01)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixel(pdc,j+(*x),i+(*y),fntclr);
}
k--;
k&=0x7;
}
}
break;
default: //正常模式
for(i=0;i<size.cy;i++){
k=7;
for(j=0;j<size.cx;j++){
if(IsInRect(prect, j+(*x), i+(*y))){
if((pfont[i*nxbyte+j/8]>>k)&0x01)
fntclr=pdc->Fontcolor;
else
fntclr=COLOR_WHITE;
SetPixel(pdc,j+(*x),i+(*y),fntclr);
}
k--;
k&=0x7;
}
}
}
OSSemPost(Lcd_Disp_Sem);
(*x)+=size.cx;
/* U8 *pfont, *plcdbuf=LCDBuffer+LCDWIDTH/8*(*y);
U8 nbit,//需要由移动的位数
nxbyte,//字符的水平占用的字节数
ncutxbyte, //剪切以后字符的水平占用的字节数
cutMask[]={0xff,0xff,0xff},//截取的运算掩码
tmpfont;
U32 i,j,*ptmp;
int nCutbit; //边缘截取字符的水平点数
INT8U err;
structSIZE size;
GetChPointer(&pfont, &size, ch, bunicode, fnt);
if((*x)>=prect->right){
(*x)+=size.cx;
return;
}
plcdbuf+=*x/8;
nbit=*x%8;
nxbyte=size.cx/8;
if(size.cx%8)
nxbyte++;
ncutxbyte=nxbyte;
nCutbit=(*x)+size.cx-prect->right;
if(nCutbit>0){ //字符在右边框以外
ptmp=(U32*)cutMask;
(*ptmp)>>=nCutbit+24-size.cx;
ncutxbyte=(size.cx-nCutbit)/8;
}
OSSemPend(Lcd_Disp_Sem,0, &err);
switch(fnt&0xc){
case FONT_TRANSPARENT: //透明背景
for(i=0;i<size.cy;i++){
for(j=0;j<ncutxbyte;j++){
tmpfont=pfont[i*nxbyte+j]&cutMask[j];
*plcdbuf|=(tmpfont>>nbit);
plcdbuf++;
*plcdbuf|=tmpfont&(~(0xff<<nbit));
}
plcdbuf+=LCDWIDTH/8-ncutxbyte;
}
break;
case FONT_BLACKBK: //黑底白字
for(i=0;i<size.cy;i++){
for(j=0;j<ncutxbyte;j++){
tmpfont=pfont[i*nxbyte+j]&cutMask[j];
*plcdbuf|=(0xff>>nbit);
*plcdbuf&=~(tmpfont>>nbit);
plcdbuf++;
*plcdbuf|=(0xff<<(8-nbit));
*plcdbuf&=~(tmpfont<<(8-nbit));
}
plcdbuf+=LCDWIDTH/8-ncutxbyte;
}
break;
default: //正常模式
for(i=0;i<size.cy;i++){
for(j=0;j<ncutxbyte;j++){
tmpfont=pfont[i*nxbyte+j]&cutMask[j];
*plcdbuf&=~(0xff>>nbit);
*plcdbuf|=(tmpfont>>nbit);
plcdbuf++;
*plcdbuf&=~(0xff<<(8-nbit));
*plcdbuf|=(tmpfont<<(8-nbit));
}
plcdbuf+=LCDWIDTH/8-ncutxbyte;
}
}
(*x)+=size.cx;
OSSemPost(Lcd_Disp_Sem);*/
}
void Buffer_TextOut(PDC pdc, int x, int y, U16* ch, U8 bunicode, U8 fnt) //显示文字
{
int i;
for(i=0;ch[i]!=0;i++){
CharactorOut(pdc, &x, &y, ch[i], bunicode, fnt);
}
if(pdc->bUpdataBuffer)
OSMboxPost(LCDFresh_MBox,(void*)1); //刷新LCD
}
void TextOutRect(PDC pdc, structRECT* prect, U16* ch, U8 bunicode, U8 fnt, U32 outMode) //在指定矩形的范围内显示文字
{
int i;
int x,y,tmp;
x=prect->left;
y=prect->top;
if(outMode&TEXTOUT_MID_Y){
tmp=(prect->bottom-prect->top-GetFontHeight(fnt))/2;
y+=tmp;
}
if(outMode&TEXTOUT_MID_X){
tmp=(prect->right-prect->left-GetUStrFontWidth(ch, fnt))/2;
x+=tmp;
}
for(i=0;ch[i]!=0;i++){
CharactorOutRect(pdc,&x, &y, prect, ch[i], bunicode, fnt);
}
if(pdc->bUpdataBuffer)
OSMboxPost(LCDFresh_MBox,(void*)1); //刷新LCD
}
void Buffer_DrawSBresenham_Line(PDC pdc, int x1, int y1,int x2, int y2)
{
int x, y,dx,dy;
int e,i;
dx=x2-x1;
dy=y2-y1;
x=x1; y=y1;
if ( ABS(dx) >= ABS(dy) ){
if ( dx >= 0 && dy>=0 ){
e = -dx;
for ( i = 0; i <= dx; i++ ) {
SetPixel(pdc,x++,y,pdc->PenColor);
e += 2 * dy;
if (e >= 0) {
y = y + 1;
e -= 2 * dx;
}
}
}
else if( dx < 0 && dy<0 ){
e = -dx;
for ( i = 0; i >= dx; i-- ){
SetPixel(pdc,x--,y,pdc->PenColor);
e += 2 * dy;
if (e <= 0) {
y = y - 1;
e -= 2 * dx;
}
}
}
else if(dx>=0 && dy<=0){
e = dx;
for ( i = 0; i <= dx; i++ ){
SetPixel(pdc,x++,y,pdc->PenColor);
e += 2 * dy;
if (e <= 0) {
y = y - 1;
e += 2 * dx;
}
}
}
else{ //dx<0 && dy>0
e = dx;
for ( i = 0; i >= dx; i-- ){
SetPixel(pdc,x--,y,pdc->PenColor);
e += 2 * dy;
if (e >= 0) {
y = y + 1;
e += 2 * dx;
}
}
}
}
else{
if ( dx >= 0 && dy>=0 ){
e = -dy;
for ( i = 0; i <= dy; i++ ) {
SetPixel(pdc,x,y++,pdc->PenColor);
e += 2 * dx;
if (e >= 0) {
x = x + 1;
e -= 2 * dy;
}
}
}
else if( dx < 0 && dy<0 ){
e = -dy;
for ( i = 0; i >= dy; i-- ){
SetPixel(pdc,x,y--,pdc->PenColor);
e += 2 * dx;
if (e <= 0) {
x = x - 1;
e -= 2 * dy;
}
}
}
else if(dx<=0 && dy>=0){
e = dy;
for ( i = 0; i <= dy; i++ ){
SetPixel(pdc,x,y++,pdc->PenColor);
e += 2 * dx;
if (e <= 0) {
x = x - 1;
e += 2 * dy;
}
}
}
else{ //dx>0 && dy<0
e = dy;
for ( i = 0; i >= dy; i-- ){
SetPixel(pdc,x,y--,pdc->PenColor);
e += 2 * dx;
if (e >= 0) {
x = x + 1;
e += 2 * dy;
}
}
}
}
}
void Buffer_LineTo(PDC pdc, int x, int y)
{
int i,j;
int x1,x2,y1,y2;
INT8U err;
OSSemPend(Lcd_Disp_Sem,0, &err);
if(pdc->DrawPointx==x){ //画垂直线
if(pdc->DrawPointy<y){
for(i=pdc->DrawPointy-(pdc->PenWidth-1)/2;i<=y+pdc->PenWidth/2;i++){
for(j=-(pdc->PenWidth-1)/2;j<=pdc->PenWidth/2;j++){
SetPixel(pdc,x+j,i,pdc->PenColor);
}
}
}
else{
for(i=pdc->DrawPointy+pdc->PenWidth/2;i>=y-(pdc->PenWidth-1)/2;i--){
for(j=-(pdc->PenWidth-1)/2;j<=pdc->PenWidth/2;j++){
SetPixel(pdc,x+j,i,pdc->PenColor);
}
}
}
pdc->DrawPointy=y;
if(pdc->bUpdataBuffer){
OSMboxPost(LCDFresh_MBox,(void*)1); //刷新LCD
}
OSSemPost(Lcd_Disp_Sem);
return;
}
if(pdc->DrawPointy==y){ //画水平线
if(pdc->DrawPointx<x){
for(i=pdc->DrawPointx-(pdc->PenWidth-1)/2;i<=x+pdc->PenWidth/2;i++){
for(j=-(pdc->PenWidth-1)/2;j<=pdc->PenWidth/2;j++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -