1094 lines
24 KiB
C
1094 lines
24 KiB
C
#include "mywin_inc.h"
|
||
|
||
|
||
|
||
|
||
|
||
|
||
u32 WIN_SetLcdColor (u32 color)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
u32 co=ewin->lcd->getLcdColor();
|
||
u32 ret=COLOR565TO888(co);
|
||
ewin->lcd->setLcdColor(COLOR888TO565(color));
|
||
return ret;
|
||
}
|
||
|
||
u32 WIN_SetLcdBkColor (u32 color)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
u32 co=ewin->lcd->getLcdBkColor();
|
||
u32 ret=COLOR565TO888(co);
|
||
ewin->lcd->setLcdBkColor(COLOR888TO565(color));
|
||
return ret;
|
||
}
|
||
|
||
|
||
u16 WIN_GetLcdColor16 (void)
|
||
{
|
||
return WIN_GetWinStruct()->lcd->getLcdColor();
|
||
}
|
||
|
||
|
||
|
||
void WIN_DrawPointSafe (int x,int y,int mode)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (POS_InRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,x,y))
|
||
{
|
||
// if (mode)
|
||
// LCD_DrawPointSafe (x,y,1);
|
||
// else
|
||
// LCD_DrawPointSafe (x,y,0);
|
||
ewin->lcd->drawPoint(x,y,mode);
|
||
}
|
||
|
||
}
|
||
|
||
void WIN_DrawPointNormal (int x,int y,int mode)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
ewin->lcd->drawPoint(x,y,mode);
|
||
}
|
||
|
||
void WIN_DrawPointColorSafe (int x,int y,u32 color)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (POS_InRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,x,y))
|
||
{
|
||
ewin->lcd->drawPointColor(x,y,color);
|
||
}
|
||
|
||
}
|
||
|
||
void WIN_DrawPointColorNormal (int x,int y,u32 color)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
ewin->lcd->drawPointColor(x,y,color);
|
||
}
|
||
|
||
void WIN_DrawPointSafeColorAlpha (int x,int y,u16 color,u8 alpha)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (POS_InRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,x,y))
|
||
{
|
||
ewin->lcd->drawPointColorAlpha(x,y,color,alpha);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//绘制一个英文字符,内部调用
|
||
//返回字符的宽度
|
||
static u32 WIN_DrawCharAt (char c,int x,int y)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (ewin->font.drawChar) return ewin->font.drawChar(c,x,y);
|
||
else return 0;
|
||
}
|
||
|
||
//显示一个汉字,内部调用,返回汉字的宽度
|
||
static u32 WIN_DrawWordAt (char *c,int x,int y)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (ewin->font.drawWord) return ewin->font.drawWord(c,x,y);
|
||
else return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//在指定位置显示字符串
|
||
void WIN_DrawTxtAt (char *txt,int x,int y)
|
||
{
|
||
if (txt==0) return;
|
||
while (*txt)
|
||
{
|
||
if ((*txt&0x80)==0)
|
||
{
|
||
x+=WIN_DrawCharAt(*txt,x,y);
|
||
txt++;
|
||
}
|
||
else
|
||
{
|
||
x+=WIN_DrawWordAt(txt,x,y);
|
||
txt+=3;
|
||
}
|
||
}
|
||
}
|
||
|
||
//在指定矩形中显示字符串,支持换行符\n
|
||
void WIN_DrawTxtAtRect (char *txt,int x,int y,int x_size,int y_size)
|
||
{
|
||
int x_s=x;
|
||
int y_s=y;
|
||
if (txt==0) return;
|
||
while (*txt)
|
||
{
|
||
if ((*txt&0x80)==0)
|
||
{
|
||
if ((x_s-x>x_size-1-WIN_GetFontWidth()/2)||(*txt=='\n'))
|
||
{
|
||
x_s=x;y_s+=WIN_GetFontHight();
|
||
if (*txt=='\n') {txt++;continue;}
|
||
}
|
||
x_s+=WIN_DrawCharAt(*txt,x_s,y_s);
|
||
txt++;
|
||
}
|
||
else
|
||
{
|
||
if (x_s-x>x_size-1-WIN_GetFontWidth())
|
||
{
|
||
x_s=x;y_s+=WIN_GetFontHight();
|
||
}
|
||
x_s+=WIN_DrawWordAt(txt,x_s,y_s);
|
||
txt+=3;
|
||
}
|
||
if (y_s-y>y_size-1-WIN_GetFontHight()) return;
|
||
}
|
||
}
|
||
|
||
|
||
//在指定矩形居中显示字符串,支持换行符\n
|
||
void WIN_DrawTxtCenterAtRect (char *txt,int x,int y,int x_size,int y_size)
|
||
{
|
||
int line_max=y_size/WIN_GetFontHight();//计算可以显示多少行
|
||
int char_max=x_size/(WIN_GetFontWidth()/2);//计算每行可以显示多少个字符
|
||
int x_s=x;
|
||
int line_i=0;
|
||
char *txtbuff=mymalloc (line_max*(char_max+1));
|
||
char *txt_ptr=txtbuff;
|
||
while (*txt)
|
||
{
|
||
if (line_i>=line_max)
|
||
{line_i--;break;}
|
||
if ((*txt&0x80)==0)
|
||
{
|
||
if ((x_s-x>x_size-WIN_GetFontWidth()/2)||(*txt=='\n'))
|
||
{
|
||
*txt_ptr=0;
|
||
line_i++;
|
||
txt_ptr=txtbuff+(char_max+1)*line_i;
|
||
x_s=x;
|
||
if (*txt=='\n')
|
||
{ txt++; }
|
||
continue;
|
||
}
|
||
x_s+=WIN_GetFontWidth()/2;
|
||
*txt_ptr=*txt;
|
||
txt_ptr++;
|
||
txt++;
|
||
}
|
||
else
|
||
{
|
||
if (x_s-x>x_size-WIN_GetFontWidth())
|
||
{
|
||
*txt_ptr=0;
|
||
line_i++;
|
||
txt_ptr=txtbuff+(char_max+1)*line_i;
|
||
x_s=x;
|
||
continue;
|
||
}
|
||
x_s+=WIN_GetFontWidth();
|
||
*txt_ptr=*txt;
|
||
txt_ptr++;
|
||
txt++;
|
||
*txt_ptr=*txt;
|
||
txt_ptr++;
|
||
txt++;
|
||
}
|
||
}
|
||
*txt_ptr=0;//最后一个字符串添加结尾
|
||
int y_s=y+(y_size-(line_i+1)*WIN_GetFontHight())/2;//y方向上居中
|
||
txt_ptr=txtbuff;
|
||
for (int i=0;i<line_i+1;i++)
|
||
{
|
||
WIN_DrawTxtHCenterAt (txt_ptr,x+x_size/2,y_s);
|
||
y_s+=WIN_GetFontHight();
|
||
txt_ptr+=char_max+1;
|
||
}
|
||
myfree(txtbuff);
|
||
}
|
||
|
||
|
||
|
||
//在指定位置居中显示字符串
|
||
void WIN_DrawTxtHCenterAt (char *txt,int x,int y)
|
||
{
|
||
int str_len=strlen(txt);
|
||
int str_x_size=WIN_GetWinStruct()->font.TxtW/2*str_len;
|
||
WIN_DrawTxtAt (txt,x-str_x_size/2,y);
|
||
}
|
||
|
||
|
||
void WIN_DrawHLine (int x_s,int y,int x_e)
|
||
{
|
||
for (int i=x_s;i<=x_e;i++)
|
||
{
|
||
WIN_DrawPointSafe (i,y,1);
|
||
}
|
||
}
|
||
|
||
//有透明度的划线,dis=0,正方向,dis=1,反方向
|
||
void WIN_DrawHLineAlpha (int x_s,int y,int x_e,u16 color,u8 dis)
|
||
{
|
||
u8 step=(x_e-x_s+1);
|
||
if (dis)
|
||
{
|
||
for (int i=x_s;i<=x_e;i++)
|
||
{
|
||
WIN_DrawPointSafeColorAlpha (i,y,color,(i-x_s)*32/step);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i=x_s;i<=x_e;i++)
|
||
{
|
||
WIN_DrawPointSafeColorAlpha (i,y,color,(x_e-i)*32/step);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void WIN_DrawVLine (int x,int y_s,int y_e)
|
||
{
|
||
for (int i=y_s;i<=y_e;i++)
|
||
{
|
||
WIN_DrawPointSafe (x,i,1);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//画线 x1,y1:起点坐标 x2,y2:终点坐标
|
||
void WIN_DrawLine(int x1, int y1, int x2, int y2)
|
||
{
|
||
int t;
|
||
int xerr=0,yerr=0,delta_x,delta_y,distance;
|
||
int incx,incy,uRow,uCol;
|
||
delta_x=x2-x1; //计算坐标增量
|
||
delta_y=y2-y1;
|
||
uRow=x1;
|
||
uCol=y1;
|
||
if(delta_x>0)incx=1; //设置单步方向
|
||
else if(delta_x==0)incx=0;//垂直线
|
||
else {incx=-1;delta_x=-delta_x;}
|
||
if(delta_y>0)incy=1;
|
||
else if(delta_y==0)incy=0;//水平线
|
||
else{incy=-1;delta_y=-delta_y;}
|
||
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
|
||
else distance=delta_y;
|
||
for(t=0;t<=distance+1;t++ )//画线输出
|
||
{
|
||
//WIN_GetWinStruct()->drawPoint (uRow,uCol,1);
|
||
WIN_DrawPointSafe (uRow,uCol,1);
|
||
xerr+=delta_x ;
|
||
yerr+=delta_y ;
|
||
if(xerr>distance)
|
||
{
|
||
xerr-=distance;
|
||
uRow+=incx;
|
||
}
|
||
if(yerr>distance)
|
||
{
|
||
yerr-=distance;
|
||
uCol+=incy;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//在指定位置画一个指定大小的圆 (x,y):中心点 r :半径
|
||
void WIN_DrawCircle(int x0,int y0,int r)
|
||
{
|
||
int a,b;
|
||
int di;
|
||
int c_x=0;
|
||
int c_y=0;
|
||
a=0;b=r;
|
||
di=3-(r<<1); //判断下个点位置的标志
|
||
while(a<=b)
|
||
{
|
||
//只绘制无效窗口内的屏幕
|
||
c_x=x0+a;c_y=y0-b;
|
||
//WIN_GetWinStruct()->drawPoint (c_x,c_y,1);
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0+b;c_y=y0-a;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0+b;c_y=y0+a;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0+a;c_y=y0+b;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0-a;c_y=y0+b;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0-b;c_y=y0+a;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0-a;c_y=y0-b;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
c_x=x0-b;c_y=y0-a;
|
||
WIN_DrawPointSafe (c_x,c_y,1);
|
||
a++;
|
||
//使用Bresenham算法画圆
|
||
if(di<0)di +=4*a+6;
|
||
else
|
||
{
|
||
di+=10+4*(a-b);
|
||
b--;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//绘制连续线段
|
||
void WIN_DrawLines (POINT_Struct *Points, int PointCount)
|
||
{
|
||
for (int i=0;i<PointCount-1;i++)
|
||
{
|
||
WIN_DrawLine (Points[i].x,Points[i].y,Points[i+1].x,Points[i+1].y);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//绘制多边形
|
||
void WIN_DrawPolygon(POINT_Struct *Points, int PointCount)
|
||
{
|
||
int16_t X = 0, Y = 0;
|
||
|
||
if(PointCount < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
WIN_DrawLine (Points->x,Points->y,(Points+PointCount-1)->x,(Points+PointCount-1)->y);
|
||
while(--PointCount)
|
||
{
|
||
X = Points->x;
|
||
Y = Points->y;
|
||
Points++;
|
||
WIN_DrawLine (X,Y,Points->x,Points->y);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//绘制空心矩形
|
||
void WIN_DrawRect (int x,int y,int x_size,int y_size)
|
||
{
|
||
WIN_DrawHLine (x,y,x+x_size-1);
|
||
WIN_DrawHLine (x,y+y_size-1,x+x_size-1);
|
||
WIN_DrawVLine (x,y,y+y_size-1);
|
||
WIN_DrawVLine (x+x_size-1,y,y+y_size-1);
|
||
}
|
||
|
||
|
||
|
||
//创建一个抗锯齿绘图平面
|
||
WIN_PlaneAAStruct *WIN_CreatPlaneAA(int x,int y,int x_size,int y_size,int accuracy)
|
||
{
|
||
WIN_PlaneAAStruct *ret=mymalloc(sizeof(WIN_PlaneAAStruct)+x_size*y_size);
|
||
|
||
if(ret)
|
||
{
|
||
ret->x=x;
|
||
ret->y=y;
|
||
ret->x_size=x_size;
|
||
ret->y_size=y_size;
|
||
ret->accuracy=accuracy;
|
||
ret->avr=ret->accuracy*ret->accuracy;
|
||
mymemset(ret->alpha,0,x_size*y_size);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
//删除一个抗锯齿平面
|
||
void WIN_DeletePlaneAA(WIN_PlaneAAStruct *p)
|
||
{
|
||
if(p==0) return;
|
||
myfree(p);
|
||
}
|
||
|
||
|
||
//绘制一个抗锯齿绘图平面
|
||
void WIN_DrawPlaneAA (WIN_PlaneAAStruct *p)
|
||
{
|
||
if(p==0) return;
|
||
u16 color=WIN_GetLcdColor16();
|
||
u8 *alpha=0;
|
||
for(int y=0;y<p->y_size;y++)
|
||
{
|
||
alpha=&p->alpha[y*p->x_size];
|
||
for(int x=0;x<p->x_size;x++)
|
||
{
|
||
if(*alpha>0x7)
|
||
WIN_DrawPointSafeColorAlpha(x+p->x,y+p->y,color,*alpha>>3);
|
||
alpha++;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//在平面内绘制抗锯齿点
|
||
//这里的x,y是实际值乘以p->accuracy的值
|
||
void WIN_DrawPointAA(WIN_PlaneAAStruct *p,int x,int y)
|
||
{
|
||
if(p==0) return;
|
||
if(p->alpha==0) return;
|
||
int x_s=x/p->accuracy;int y_s=y/p->accuracy;
|
||
int x_e=x_s+1;int y_e=y_s+1;
|
||
if(x_s<p->x||x_s>p->x+p->x_size-1) return;
|
||
if(y_s<p->y||y_s>p->y+p->y_size-1) return;
|
||
|
||
//每个像素的细分程度,除以一个p->accuracy是这个虚拟像素在实际像素里的分量
|
||
//再除以一个p->accuracy是因为上层步进值
|
||
int accuracy=p->accuracy;//*p->accuracy;
|
||
int alpha_x=16-(x%p->accuracy)*16/p->accuracy;
|
||
int alpha_y=16-(y%p->accuracy)*16/p->accuracy;
|
||
|
||
u8 *point=0;
|
||
int point_=0;
|
||
|
||
|
||
point=&p->alpha[p->x_size*(y_s-p->y)+(x_s-p->x)];
|
||
point_=*point+alpha_x*alpha_y/accuracy;
|
||
if(point_>0xff) point_=0xff;
|
||
*point=point_;
|
||
|
||
if(x_e<p->x+p->x_size)
|
||
{
|
||
point=&p->alpha[p->x_size*(y_s-p->y)+(x_e-p->x)];
|
||
point_=*point+(16-alpha_x)*alpha_y/accuracy;
|
||
if(point_>0xff) point_=0xff;
|
||
*point=point_;
|
||
}
|
||
if((y_e<p->y+p->y_size)&&(x_e<p->x+p->x_size))
|
||
{
|
||
point=&p->alpha[p->x_size*(y_e-p->y)+(x_e-p->x)];
|
||
point_=*point+(16-alpha_x)*(16-alpha_y)/accuracy;
|
||
if(point_>0xff) point_=0xff;
|
||
*point=point_;
|
||
}
|
||
if(y_e<p->y+p->y_size)
|
||
{
|
||
point=&p->alpha[p->x_size*(y_e-p->y)+(x_s-p->x)];
|
||
point_=*point+alpha_x*(16-alpha_y)/accuracy;
|
||
if(point_>0xff) point_=0xff;
|
||
*point=point_;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//在平面内画线 x1,y1:起点坐标 x2,y2:终点坐标
|
||
static void WIN_PlaneDrawLine(WIN_PlaneAAStruct *p,int x1, int y1, int x2, int y2)
|
||
{
|
||
if(p==0) return;
|
||
|
||
|
||
int t;
|
||
int xerr=0,yerr=0,delta_x,delta_y,distance;
|
||
int incx,incy,uRow,uCol;
|
||
delta_x=x2-x1; //计算坐标增量
|
||
delta_y=y2-y1;
|
||
uRow=x1;
|
||
uCol=y1;
|
||
if(delta_x>0)incx=1; //设置单步方向
|
||
else if(delta_x==0)incx=0;//垂直线
|
||
else {incx=-1;delta_x=-delta_x;}
|
||
if(delta_y>0)incy=1;
|
||
else if(delta_y==0)incy=0;//水平线
|
||
else{incy=-1;delta_y=-delta_y;}
|
||
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
|
||
else distance=delta_y;
|
||
for(t=0;t<=distance+1;t++ )//画线输出
|
||
{
|
||
WIN_DrawPointAA(p,uRow,uCol);
|
||
xerr+=delta_x ;
|
||
yerr+=delta_y ;
|
||
if(xerr>distance)
|
||
{
|
||
xerr-=distance;
|
||
uRow+=incx;
|
||
}
|
||
if(yerr>distance)
|
||
{
|
||
yerr-=distance;
|
||
uCol+=incy;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
//抗锯齿画线
|
||
void WIN_DrawLineAA(int x1, int y1, int x2, int y2,int accuracy)
|
||
{
|
||
int x=x1;if(x>x2) x=x2;
|
||
int y=y1;if(y>y2) y=y2;
|
||
int x_size=x1-x2;if(x_size<0) x_size=-x_size;
|
||
int y_size=y1-y2;if(y_size<0) y_size=-y_size;
|
||
x_size++;y_size++;
|
||
WIN_PlaneAAStruct *p=WIN_CreatPlaneAA(x,y,x_size,y_size,4);
|
||
|
||
if(p)
|
||
{
|
||
x1*=p->accuracy;
|
||
y1*=p->accuracy;
|
||
x2*=p->accuracy;
|
||
y2*=p->accuracy;
|
||
WIN_PlaneDrawLine(p,x1,y1,x2,y2);
|
||
WIN_DrawPlaneAA(p);
|
||
WIN_DeletePlaneAA(p);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//用纯色填充矩形
|
||
void WIN_FillRectByColor (int x,int y,int x_size,int y_size)
|
||
{
|
||
RECT_Struct r1;
|
||
RECT_Struct r2;
|
||
RECT_Struct ret;
|
||
|
||
r1.x=x;r1.x_size=x_size;r1.y=y;r1.y_size=y_size;
|
||
r2.x=WIN_GetWinStruct()->Invalid_x;
|
||
r2.x_size=WIN_GetWinStruct()->Invalid_x_size;
|
||
r2.y=WIN_GetWinStruct()->Invalid_y;
|
||
r2.y_size=WIN_GetWinStruct()->Invalid_y_size;
|
||
|
||
//绘制新矩形
|
||
if (POS_RectIntersection(&ret,&r1,&r2))
|
||
{
|
||
//LCD_FillRectByColor (ret.x,ret.y,ret.x_size,ret.y_size);
|
||
WIN_GetWinStruct()->lcd->fillRectByColor (ret.x,ret.y,ret.x_size,ret.y_size);
|
||
}
|
||
}
|
||
|
||
|
||
//用纯色和透明度填充矩形
|
||
void WIN_FillRectByColorAlpha (int x,int y,int x_size,int y_size,u8 alpha)
|
||
{
|
||
RECT_Struct r1;
|
||
RECT_Struct r2;
|
||
RECT_Struct ret;
|
||
|
||
r1.x=x;r1.x_size=x_size;r1.y=y;r1.y_size=y_size;
|
||
r2.x=WIN_GetWinStruct()->Invalid_x;
|
||
r2.x_size=WIN_GetWinStruct()->Invalid_x_size;
|
||
r2.y=WIN_GetWinStruct()->Invalid_y;
|
||
r2.y_size=WIN_GetWinStruct()->Invalid_y_size;
|
||
|
||
//绘制新矩形
|
||
if (POS_RectIntersection(&ret,&r1,&r2))
|
||
{
|
||
//LCD_FillRectByColorAlpha (ret.x,ret.y,ret.x_size,ret.y_size,alpha);
|
||
WIN_GetWinStruct()->lcd->fillRectByColorAlpha (ret.x,ret.y,ret.x_size,ret.y_size,alpha);
|
||
}
|
||
}
|
||
|
||
|
||
//用背景图片填充矩形
|
||
void WIN_FillRect (int x,int y,int x_size,int y_size,u16 *buff,u16 pic_x,u16 pic_y,u16 pic_xsize,u16 pic_ysize)
|
||
{
|
||
RECT_Struct r1;
|
||
RECT_Struct r2;
|
||
RECT_Struct ret;
|
||
|
||
r1.x=x;r1.x_size=x_size;r1.y=y;r1.y_size=y_size;
|
||
|
||
r2.x=WIN_GetWinStruct()->Invalid_x;
|
||
r2.x_size=WIN_GetWinStruct()->Invalid_x_size;
|
||
r2.y=WIN_GetWinStruct()->Invalid_y;
|
||
r2.y_size=WIN_GetWinStruct()->Invalid_y_size;
|
||
|
||
//绘制新矩形
|
||
if (POS_RectIntersection(&ret,&r1,&r2))
|
||
{
|
||
//把图片偏移到绘制区
|
||
pic_x+=ret.x-x;
|
||
pic_y+=ret.y-y;
|
||
WIN_GetWinStruct()->lcd->fillRectOffAt (ret.x,ret.y,ret.x_size,ret.y_size,buff,pic_x,pic_y,pic_xsize,pic_ysize);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//用带透明度的图片填充矩形
|
||
void WIN_FillRectAlpha (int x,int y,int x_size,int y_size,void *buff,u16 pic_x,u16 pic_y,u16 pic_xsize,u16 pic_ysize)
|
||
{
|
||
RECT_Struct r1;
|
||
RECT_Struct r2;
|
||
RECT_Struct ret;
|
||
|
||
r1.x=x;r1.x_size=x_size;r1.y=y;r1.y_size=y_size;
|
||
|
||
r2.x=WIN_GetWinStruct()->Invalid_x;
|
||
r2.x_size=WIN_GetWinStruct()->Invalid_x_size;
|
||
r2.y=WIN_GetWinStruct()->Invalid_y;
|
||
r2.y_size=WIN_GetWinStruct()->Invalid_y_size;
|
||
|
||
//绘制新矩形
|
||
if (POS_RectIntersection(&ret,&r1,&r2))
|
||
{
|
||
//把图片偏移到绘制区
|
||
pic_x+=ret.x-x;
|
||
pic_y+=ret.y-y;
|
||
WIN_GetWinStruct()->lcd->fillRectOffAtAlpha (ret.x,ret.y,ret.x_size,ret.y_size,buff,pic_x,pic_y,pic_xsize,pic_ysize);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//填充三角形
|
||
#define ABS(X) ((X) > 0 ? (X) : -(X))
|
||
void WIN_FillTriangle(int x1, int x2, int x3, int y1, int y2, int y3)
|
||
{
|
||
int deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
|
||
yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
|
||
curpixel = 0;
|
||
|
||
deltax = ABS(x2 - x1); /* The difference between the x's */
|
||
deltay = ABS(y2 - y1); /* The difference between the y's */
|
||
x = x1; /* Start x off at the first pixel */
|
||
y = y1; /* Start y off at the first pixel */
|
||
|
||
if (x2 >= x1) /* The x-values are increasing */
|
||
{
|
||
xinc1 = 1;
|
||
xinc2 = 1;
|
||
}
|
||
else /* The x-values are decreasing */
|
||
{
|
||
xinc1 = -1;
|
||
xinc2 = -1;
|
||
}
|
||
|
||
if (y2 >= y1) /* The y-values are increasing */
|
||
{
|
||
yinc1 = 1;
|
||
yinc2 = 1;
|
||
}
|
||
else /* The y-values are decreasing */
|
||
{
|
||
yinc1 = -1;
|
||
yinc2 = -1;
|
||
}
|
||
|
||
if (deltax >= deltay) /* There is at least one x-value for every y-value */
|
||
{
|
||
xinc1 = 0; /* Don't change the x when numerator >= denominator */
|
||
yinc2 = 0; /* Don't change the y for every iteration */
|
||
den = deltax;
|
||
num = deltax / 2;
|
||
numadd = deltay;
|
||
numpixels = deltax; /* There are more x-values than y-values */
|
||
}
|
||
else /* There is at least one y-value for every x-value */
|
||
{
|
||
xinc2 = 0; /* Don't change the x for every iteration */
|
||
yinc1 = 0; /* Don't change the y when numerator >= denominator */
|
||
den = deltay;
|
||
num = deltay / 2;
|
||
numadd = deltax;
|
||
numpixels = deltay; /* There are more y-values than x-values */
|
||
}
|
||
|
||
for (curpixel = 0; curpixel <= numpixels; curpixel++)
|
||
{
|
||
WIN_DrawLine(x, y, x3, y3);
|
||
|
||
num += numadd; /* Increase the numerator by the top of the fraction */
|
||
if (num >= den) /* Check if numerator >= denominator */
|
||
{
|
||
num -= den; /* Calculate the new numerator value */
|
||
x += xinc1; /* Change the x as appropriate */
|
||
y += yinc1; /* Change the y as appropriate */
|
||
}
|
||
x += xinc2; /* Change the x as appropriate */
|
||
y += yinc2; /* Change the y as appropriate */
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//填充多边形
|
||
#define POLY_X(Z) ((int32_t)((Points + (Z))->x))
|
||
#define POLY_Y(Z) ((int32_t)((Points + (Z))->y))
|
||
void WIN_FillPolygon(POINT_Struct *Points, int PointCount)
|
||
{
|
||
int X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0;
|
||
int IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;
|
||
|
||
IMAGE_LEFT = IMAGE_RIGHT = Points->x;
|
||
IMAGE_TOP= IMAGE_BOTTOM = Points->y;
|
||
|
||
for(counter = 1; counter < PointCount; counter++)
|
||
{
|
||
pixelX = POLY_X(counter);
|
||
if(pixelX < IMAGE_LEFT)
|
||
{
|
||
IMAGE_LEFT = pixelX;
|
||
}
|
||
if(pixelX > IMAGE_RIGHT)
|
||
{
|
||
IMAGE_RIGHT = pixelX;
|
||
}
|
||
|
||
pixelY = POLY_Y(counter);
|
||
if(pixelY < IMAGE_TOP)
|
||
{
|
||
IMAGE_TOP = pixelY;
|
||
}
|
||
if(pixelY > IMAGE_BOTTOM)
|
||
{
|
||
IMAGE_BOTTOM = pixelY;
|
||
}
|
||
}
|
||
|
||
if(PointCount < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
|
||
Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
|
||
|
||
X_first = Points->x;
|
||
Y_first = Points->y;
|
||
|
||
while(--PointCount)
|
||
{
|
||
X = Points->x;
|
||
Y = Points->y;
|
||
Points++;
|
||
X2 = Points->x;
|
||
Y2 = Points->y;
|
||
|
||
WIN_FillTriangle(X, X2, X_center, Y, Y2, Y_center);
|
||
WIN_FillTriangle(X, X_center, X2, Y, Y_center, Y2);
|
||
WIN_FillTriangle(X_center, X2, X, Y_center, Y2, Y);
|
||
}
|
||
|
||
WIN_FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center);
|
||
WIN_FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2);
|
||
WIN_FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first);
|
||
}
|
||
|
||
|
||
|
||
|
||
//绘制图标,图标使用const数组编译在程序里,其本身已经附带了大小等参数
|
||
//此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
|
||
void WIN_DrawImag (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;j<y+ysize;j++)
|
||
{
|
||
for (int i=0;i<xsize;i++)
|
||
{
|
||
//WIN_GetWinStruct()->drawPointColor(i+x,j,imag[i]);
|
||
WIN_DrawPointColorSafe (i+x,j,imag[i]);
|
||
}
|
||
imag+=w;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//绘制图标,但是不绘制指定颜色
|
||
void WIN_DrawImagButColor (int x,int y,int xsize,int ysize,const u8 *buff,u16 color)
|
||
{
|
||
|
||
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;j<y+ysize;j++)
|
||
{
|
||
for (int i=0;i<xsize;i++)
|
||
{
|
||
if (imag[i]!=color)
|
||
//WIN_GetWinStruct()->drawPointColor (i+x,j,imag[i]);
|
||
WIN_DrawPointColorSafe (i+x,j,imag[i]);
|
||
|
||
}
|
||
imag+=w;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//绘制图标,把图像的有效部分绘制为指定颜色
|
||
//此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
|
||
void WIN_DrawImagByColor (int x,int y,int xsize,int ysize,const u8 *buff,u16 color)
|
||
{
|
||
|
||
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;j<y+ysize;j++)
|
||
{
|
||
for (int i=0;i<xsize;i++)
|
||
{
|
||
if ((imag[i]!=0x0000)&&(imag[i]!=0xffff))
|
||
//WIN_GetWinStruct()->drawPointColor (i+x,j,color);
|
||
WIN_DrawPointColorSafe (i+x,j,color);
|
||
}
|
||
imag+=w;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//绘制图标,把原图像转化为透明度,用指定颜色来绘制
|
||
//此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
|
||
void WIN_DrawImagByAlpha (int x,int y,int xsize,int ysize,const u8 *buff,u16 color)
|
||
{
|
||
|
||
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);
|
||
u8 r,g,b;
|
||
u8 alpha=0;
|
||
if (xsize>w) xsize=w;
|
||
if (ysize>h) ysize=h;
|
||
for (int j=y;j<y+ysize;j++)
|
||
{
|
||
for (int i=0;i<xsize;i++)
|
||
{
|
||
//只绘制无效窗口内的屏幕
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (POS_InRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,i+x,j))
|
||
{
|
||
//白色全透明不绘制,加快速度
|
||
if ((imag[i]!=0x0000)&&(imag[i]!=0xffff))
|
||
{
|
||
//WIN_GetWinStruct()->drawPointColorAlpha (i+x,j,color,31-(imag[i]>>11));
|
||
WIN_DrawPointSafeColorAlpha(i+x,j,color,31-(imag[i]>>11));
|
||
}
|
||
else if (imag[i]==0x0000)
|
||
{
|
||
//不透明直接画原来的颜色
|
||
//WIN_GetWinStruct()->drawPointColor (i+x,j,color);
|
||
WIN_DrawPointColorSafe(i+x,j,color);
|
||
}
|
||
}
|
||
}
|
||
imag+=w;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//绘制图标,把原图像转化为透明度,用指定颜色来绘制
|
||
//此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
|
||
void WIN_DrawImagByAlphaAnti (int x,int y,int xsize,int ysize,const u8 *buff,u16 color)
|
||
{
|
||
|
||
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);
|
||
u8 r,g,b;
|
||
u8 alpha=0;
|
||
if (xsize>w) xsize=w;
|
||
if (ysize>h) ysize=h;
|
||
for (int j=y;j<y+ysize;j++)
|
||
{
|
||
for (int i=0;i<xsize;i++)
|
||
{
|
||
//只绘制无效窗口内的屏幕
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
if (POS_InRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,i+x,j))
|
||
{
|
||
//白色全透明不绘制,加快速度
|
||
if ((imag[i]!=0x0000)&&(imag[i]!=0xffff))
|
||
{
|
||
//WIN_GetWinStruct()->drawPointColorAlpha (i+x,j,color,31-(imag[i]>>11));
|
||
WIN_DrawPointSafeColorAlpha(i+x,j,color,(imag[i]>>11));
|
||
}
|
||
else if (imag[i]==0xffff)
|
||
{
|
||
//不透明直接画原来的颜色
|
||
//WIN_GetWinStruct()->drawPointColor (i+x,j,color);
|
||
WIN_DrawPointColorSafe(i+x,j,color);
|
||
}
|
||
}
|
||
}
|
||
imag+=w;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//清空显示
|
||
void WIN_Clear (void)
|
||
{
|
||
WIN_Struct *ewin=WIN_GetWinStruct();
|
||
//LCD_ClearRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size);
|
||
ewin->lcd->clearRect (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//获得文字的矩形大小
|
||
void WIN_GetTxtRectSize (char *txt,int *x_size,int *y_size)
|
||
{
|
||
int font_h=WIN_GetFontHight();
|
||
int font_w=WIN_GetFontWidth()/2;
|
||
int max_num=0;
|
||
int now_num=0;
|
||
int line=1;
|
||
//这里没有定义i=0;程序在优化之后产生总线错误 2020.2.26
|
||
for (int i=0;txt[i];i++)
|
||
{
|
||
if (txt[i]!='\n')
|
||
{
|
||
now_num++;
|
||
}
|
||
else
|
||
{
|
||
if (now_num>max_num)
|
||
{
|
||
max_num=now_num;
|
||
now_num=0;
|
||
}
|
||
line++;
|
||
}
|
||
}
|
||
if (max_num<now_num+1) max_num=now_num+1;//最后一行
|
||
*x_size=max_num*font_w;
|
||
*y_size=line*font_h;
|
||
}
|
||
|
||
|
||
|
||
|
||
//获得图像数据的尺寸,返回0,成功,非0,失败
|
||
int WIN_GetImageSize (u8 *buff,int *xsize,int *ysize)
|
||
{
|
||
|
||
if (buff==0) return -1;
|
||
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)||(is565!=0x01)||(rgb!=0x1b))
|
||
return -1;
|
||
|
||
*xsize=w;
|
||
*ysize=h;
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|