#include "mywin_inc.h" WIN_LcdStruct *WIN_CreatVirtualLcd (int x_size,int y_size) { WIN_LcdStruct *ret=mymalloc (sizeof (WIN_LcdStruct)); mymemset (ret,0,sizeof (WIN_LcdStruct)); ret->x_size=x_size; ret->y_size=y_size; ret->WindowSrcX=0; ret->WindowSrcY=0; ret->WindowDstX=ret->x_size-1; ret->WindowDstY=ret->y_size-1; ret->ScreenDis=1; ret->BackColor=0; ret->Color=0xffff; ret->DrawMode=1; ret->DrawAddr=mymalloc (ret->x_size*ret->y_size*2); return ret; } void WIN_DeleteVirtualLcd (WIN_LcdStruct *lcd) { if (lcd->DrawAddr) myfree (lcd->DrawAddr); myfree (lcd); } //设置屏幕显示方向 void WIN_LcdSetScreenDis (WIN_LcdStruct *lcd,int d) { if (d) lcd->ScreenDis=1; else lcd->ScreenDis=0; } //设置活动窗口 void WIN_LcdSetWindow (WIN_LcdStruct *lcd,int x_s,int y_s,int x_size,int y_size) { int dstx=0; int dsty=0; if (x_size<1) x_size=1; if (y_size<1) y_size=1; if (x_s>lcd->x_size-1) x_s=lcd->x_size-1; else if (x_s<0) x_s=0; if (y_s>lcd->y_size-1) y_s=lcd->y_size-1; else if (y_s<0) y_s=0; dstx=x_s+x_size-1; dsty=y_s+y_size-1; if (dstx>lcd->x_size-1) dstx=lcd->x_size-1; else if (dstx<0) dstx=0; if (dsty>lcd->y_size-1) dsty=lcd->y_size-1; else if (dsty<0) dsty=0; lcd->WindowSrcX=x_s; lcd->WindowSrcY=y_s; lcd->WindowDstX=dstx; lcd->WindowDstY=dsty; } int WIN_LcdGetWindowSizeX (WIN_LcdStruct *lcd) { return lcd->WindowDstX-lcd->WindowSrcX+1; } int WIN_LcdGetWindowSizeY (WIN_LcdStruct *lcd) { return lcd->WindowDstY-lcd->WindowSrcY+1; } int WIN_LcdGetLcdSizeX(WIN_LcdStruct *lcd) { return lcd->x_size; } int WIN_LcdGetLcdSizeY (WIN_LcdStruct *lcd) { return lcd->y_size; } u32 WIN_LcdSetLcdColor (WIN_LcdStruct *lcd,u32 color) { u32 ret=lcd->Color; //g_lcd_struct.Color=color; lcd->Color=COLOR888TO565(color); return ret; } u32 WIN_LcdSetLcdBkColor (WIN_LcdStruct *lcd,u32 color) { u32 ret=lcd->BackColor; //g_lcd_struct.BackColor=color; lcd->BackColor=COLOR888TO565(color); return ret; } u32 WIN_LcdSetLcdColor16 (WIN_LcdStruct *lcd,u32 color) { u32 ret=lcd->Color; lcd->Color=(color); return ret; } u32 WIN_LcdSetLcdBkColor16 (WIN_LcdStruct *lcd,u32 color) { u32 ret=lcd->BackColor; lcd->BackColor=(color); return ret; } u32 WIN_LcdGetLcdColor (WIN_LcdStruct *lcd) { u32 ret=lcd->Color; return COLOR565TO888(ret); } u32 WIN_LcdGetLcdBkColor (WIN_LcdStruct *lcd) { u32 ret=lcd->BackColor; return COLOR565TO888(ret); } u32 WIN_LcdGetLcdColor16 (WIN_LcdStruct *lcd) { u32 ret=lcd->Color; return ret; } u32 WIN_LcdGetLcdBkColor16 (WIN_LcdStruct *lcd) { u32 ret=lcd->BackColor; return ret; } //设置绘制模式,1,不绘制背景,0,绘制背景 void WIN_LcdSetLcdDrawMode (WIN_LcdStruct *lcd,int mode) { if (mode) { lcd->DrawMode=1;//此时调用画点函数时不绘制背景色 } else { lcd->DrawMode=0; } } //填充一条线,以窗口的起点为起点,最大填充到窗口的终点位置 static void WIN_LcdFillLine16 (WIN_LcdStruct *lcd,u16 *buff,int y,int xsize) { u16 *addr=lcd->DrawAddr; int xsizeMax=lcd->WindowDstX+1-lcd->WindowSrcX; if (xsize>xsizeMax) xsize=xsizeMax; if (lcd->ScreenDis) { addr=&addr[y*lcd->x_size+lcd->WindowSrcX]; for (int x=0;xx_size*lcd->y_size-1-(y*lcd->x_size+lcd->WindowSrcX)]; for (int x=0;xWindowDstY+1-lcd->WindowSrcY; if (ysize>ysizeMax) ysize=ysizeMax; for (int y=0;yWindowSrcY,xsize); buff+=xsize; } } //把图像偏移之后填充到屏幕的活动窗口中, //参数x_s,图像要显示的横向起始坐标 //参数y_s,图像要显示的纵向起始坐标 //参数xsize,图像的宽度 //参数ysize,图像的高度 static void WIN_LcdFillRectOff16 (WIN_LcdStruct *lcd,u16 *buff,int x_s,int y_s,int xsize,int ysize) { int offset=y_s*xsize+x_s; WIN_LcdFillRect16(lcd,buff+offset,xsize,ysize-y_s); } //在活动窗口的指定位置显示图片 //参数s_x,图像在绘图窗口中的坐标 //参数s_y,图像在绘图冲口中的坐标 //参数s_xsize,要绘制的部分图像大小 //参数s_ysize,要绘制的部分图像大小 //参数x_s,图像要显示的横向起始坐标 //参数y_s,图像要显示的纵向起始坐标 //参数xsize,图像的宽度 //参数ysize,图像的高度 void WIN_LcdFillRectOff16At (WIN_LcdStruct *lcd,int s_x,int s_y,int s_xsize,int s_ysize,u16 *buff,int x_s,int y_s,int xsize,int ysize) { //保存以前的窗口大小 int w_x=lcd->WindowSrcX; int w_y=lcd->WindowSrcY; int w_x_e=lcd->WindowDstX; int w_y_e=lcd->WindowDstY; //设置新的窗口大小 lcd->WindowSrcX=w_x+s_x; lcd->WindowSrcY=w_y+s_y; lcd->WindowDstX=lcd->WindowSrcX+s_xsize-1; lcd->WindowDstY=lcd->WindowSrcY+s_ysize-1; //限制新的绘图区不能在以前的窗口之外 if (lcd->WindowDstX>w_x_e) lcd->WindowDstX=w_x_e; if (lcd->WindowDstY>w_y_e) lcd->WindowDstY=w_y_e; //绘图 WIN_LcdFillRectOff16 (lcd,buff,x_s+s_x,y_s+s_y,xsize,ysize); //恢复以前的绘图区 lcd->WindowSrcX=w_x; lcd->WindowSrcY=w_y; lcd->WindowDstX=w_x_e; lcd->WindowDstY=w_y_e; } //安全画点,以屏幕窗口的坐标为原点,并且画点不会超出窗口范围 void WIN_LcdDrawPointSafe (WIN_LcdStruct *lcd,int x,int y,int mode) { x+=lcd->WindowSrcX; y+=lcd->WindowSrcY; //在窗口以外的不画 if (xWindowSrcX||x>lcd->WindowDstX) return; if (yWindowSrcY||y>lcd->WindowDstY) return; u16 *DrawAddr=lcd->DrawAddr; if (mode) { if (lcd->ScreenDis) DrawAddr[(y*lcd->x_size+x)]=lcd->Color; else DrawAddr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=lcd->Color; } else if (lcd->DrawMode==0) { if (lcd->ScreenDis) DrawAddr[(y*lcd->x_size+x)]=lcd->BackColor; else DrawAddr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=lcd->BackColor; } else//当g_lcd_struct.DrawMode==1时不绘制背景色 { } } //安全画点,以屏幕窗口的坐标为原点,并且画点不会超出窗口范围 //以指定颜色画点,而不是前景色 void WIN_LcdDrawPointSafeColor (WIN_LcdStruct *lcd,int x,int y,u16 color) { x+=lcd->WindowSrcX; y+=lcd->WindowSrcY; //在窗口以外的不画 if (xWindowSrcX||x>lcd->WindowDstX) return; if (yWindowSrcY||y>lcd->WindowDstY) return; u16 *DrawAddr=lcd->DrawAddr; if (1) { if (lcd->ScreenDis) DrawAddr[(y*lcd->x_size+x)]=color; else DrawAddr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=color; } } //快速ALPHA BLENDING算法. //src:源颜色 //dst:目标颜色 //alpha:透明程度(0~32) //返回值:混合后的颜色. static u16 alpha_blend565(u16 src,u16 dst,u8 alpha) { u32 src2; u32 dst2; //Convert to 32bit |-----GGGGGG-----RRRRR------BBBBB| src2=((src<<16)|src)&0x07E0F81F; dst2=((dst<<16)|dst)&0x07E0F81F; //Perform blending R:G:B with alpha in range 0..32 //Note that the reason that alpha may not exceed 32 is that there are only //5bits of space between each R:G:B value, any higher value will overflow //into the next component and deliver ugly result. dst2=((((dst2-src2)*alpha)>>5)+src2)&0x07E0F81F; return (dst2>>16)|dst2; } //以指定色透明度画点0~32,0,全透明,31,不透明 void WIN_LcdDrawPointSafeColorAlpha (WIN_LcdStruct *lcd,int x,int y,u16 color,u8 alpha) { x+=lcd->WindowSrcX; y+=lcd->WindowSrcY; //在窗口以外的不画 if (xWindowSrcX||x>lcd->WindowDstX) return; if (yWindowSrcY||y>lcd->WindowDstY) return; if (alpha>31 ) alpha=31; if (alpha==0) return; u16 *DrawAddr=lcd->DrawAddr; u16 color_old=0; if (1) { if (lcd->ScreenDis) { color_old=DrawAddr[(y*lcd->x_size+x)]; color=alpha_blend565 (color_old,color,alpha); DrawAddr[(y*lcd->x_size+x)]=color; } else { color_old=DrawAddr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]; color=alpha_blend565 (color_old,color,alpha); DrawAddr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=color; } } } //填充矩形,已窗口坐标为原点 void WIN_LcdFillRectByColor (WIN_LcdStruct *lcd,int x,int y,int x_size,int y_size) { for (int i=y;iColor,alpha); } } } //绘制图标,图标使用const数组编译在程序里,其本身已经附带了大小等参数 //此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数 void WIN_LcdDrawImag (WIN_LcdStruct *lcd,int x,int y,int xsize,int ysize,const u8 *buff) { if (buff==0) return ; u8 scan=buff[0]; u8 gray=buff[1]; u16 w=*((u16*)&buff[2]); u16 h=*((u16*)&buff[4]); u8 is565=buff[6]; u8 rgb=buff[7]; //必须所有参数都符合要求 if ((scan!=0x00)||(gray!=0x10)||(w>WIN_IMAGE_MAXSIZE)||(h>WIN_IMAGE_MAXSIZE)||(is565!=0x01)||(rgb!=0x1b)) return; u16 *imag=(u16 *)(buff+8); if (xsize>w) xsize=w; if (ysize>h) ysize=h; for (int j=y;jWIN_IMAGE_MAXSIZE)||(h>WIN_IMAGE_MAXSIZE)||(is565!=0x01)||(rgb!=0x1b)) return; u16 *imag=(u16 *)(buff+8); if (xsize>w) xsize=w; if (ysize>h) ysize=h; for (int j=y;jWIN_IMAGE_MAXSIZE)||(h>WIN_IMAGE_MAXSIZE)||(is565!=0x01)||(rgb!=0x1b)) return; u16 *imag=(u16 *)(buff+8); if (xsize>w) xsize=w; if (ysize>h) ysize=h; for (int j=y;jWIN_IMAGE_MAXSIZE)||(h>WIN_IMAGE_MAXSIZE)||(is565!=0x01)||(rgb!=0x1b)) return; u16 *imag=(u16 *)(buff+8); u8 r,g,b; u8 alpha=0; if (xsize>w) xsize=w; if (ysize>h) ysize=h; for (int j=y;jInvalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,i+x,j)) { //白色全透明不绘制,加快速度 if ((imag[i]!=0x0000)&&(imag[i]!=0xffff)) { WIN_LcdDrawPointSafeColorAlpha (lcd,i+x,j,color,31-(imag[i]>>11)); } else if (imag[i]==0x0000) { //不透明直接画原来的颜色 WIN_LcdDrawPointSafeColor (lcd,i+x,j,color); } } } imag+=w; } } //清除绘图窗口内的显示 void WIN_LcdClear (WIN_LcdStruct *lcd) { u16 *addr=lcd->DrawAddr; for (int y=lcd->WindowSrcY;y<=lcd->WindowDstY;y++) { if (lcd->ScreenDis) { for (int x=lcd->WindowSrcX;x<=lcd->WindowDstX;x++) { addr[(y*lcd->x_size+x)]=lcd->BackColor; } } else { for (int x=lcd->WindowSrcX;x<=lcd->WindowDstX;x++) { addr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=lcd->BackColor; } } } } //清除矩形内的显示 void WIN_LcdClearRect (WIN_LcdStruct *lcd,int x,int y,int x_size,int y_size) { u16 *addr=lcd->DrawAddr; x=x+lcd->WindowSrcX; y=y+lcd->WindowSrcY; int x_e=x+x_size-1; if (x_e>lcd->WindowDstX) x_e=lcd->WindowDstX; int y_e=y+y_size-1; if (y_e>lcd->WindowDstY) y_e=lcd->WindowDstY; int temp=x; for (;y<=y_e;y++) { if (lcd->ScreenDis) { for (x=temp;x<=x_e;x++) { addr[(y*lcd->x_size+x)]=lcd->BackColor; } } else { for (x=temp;x<=x_e;x++) { addr[lcd->x_size*lcd->y_size-1-(y*lcd->x_size+x)]=lcd->BackColor; } } } } //获取指定矩形空间的屏幕颜色,屏幕的绝对坐标 void WIN_LcdGetColors (WIN_LcdStruct *lcd,u16 *buff,int x_s,int y_s,int x_size,int y_size) { u16 *addr=lcd->DrawAddr; if (x_s<0) x_s=0; else if (x_s>lcd->x_size-1) x_s=lcd->x_size-1; if (y_s<0) y_s=0; else if (y_s>lcd->y_size-1) y_s=lcd->y_size-1; if (x_size>lcd->x_size-x_s) x_size= lcd->x_size-x_s; else if (x_size<0) x_size=0; if (y_size>lcd->y_size-y_s) y_size= lcd->y_size-y_s; else if (y_size<0) y_size=0; for (int y=y_s;yScreenDis) { for (int x=x_s;xx_size+x)]; *buff=temp; buff++; } } else { for (int x=x_s;xx_size*lcd->y_size-1-(y*lcd->x_size+x)]; *buff=temp; buff++; } } } }