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

📄 display.c

📁 在移植成功ucos核的基础上扩充了该操作系统的许多没有功能。如文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-----------------------------------------------------------------------------
    #说明: 绘图函数,包括与硬件无关的缓冲区绘图函数
    #接口函数
		#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 + -