|
发表于 2011-1-18 08:54:30
|
显示全部楼层
/*--------------File Info-------------------------------------------------------
** 文 件 名: GUI.c
** 最后修改日期: 2009.05.16
** 版 本: V1.0
** 描 述:
**------------------------------------------------------------------------------
** 创 建 者: JJX
** 日 期: 2009.05.16
*******************************************************************************/
#include "config.h"
#include "GUI.h"
#include "GBK.h"
INT8U GUIEnglishFont = En_8x16; //默认字体
INT8U Char_XSIZE= 8; //英文字体X宽度 不能大于8
INT8U Char_YSIZE= 16; //英文字体Y宽度 不能大于16
INT8U GUIChineseFont= Chinese_16x16;//默认字体
INT8U Chinese_XSIZE= 16;//中文字体x宽度
INT8U Chinese_YSIZE= 16;//中文字体y宽度
INT8U GUI_XWORD=LCD_XSIZE/16;
INT8U GUI_YWORD=LCD_YSIZE/16;
void GUI_Init(void)
{
GUI_Clear();
GUIEnglishFont = En_8x16;
Char_XSIZE = En_8x16_XSIZE;
Char_YSIZE = En_8x16_YSIZE;
GUIChineseFont=Chinese_16x16;
Chinese_XSIZE=Chinese_16x16_XSIZE;//中文字体x宽度
Chinese_YSIZE=Chinese_16x16_YSIZE;//中文字体y宽度
}
void GUI_Clear(void)
{
INT8U i,module;
for(module=0;module<OutMODULE_NUM;module++)
for(i=0;i<32;i++)
{
//Outdoor
Module_RedBuffer[module]=0x00;
Module_GreenBuffer[module]=0x00;
GUI_RedBuffer[module]=0x00;
GUI_GreenBuffer[module]=0x00;
}
for(module=0;module<InMODULE_NUM;module++)
for(i=0;i<32;i++)
{
//Indoor
Module_Red1Buffer[module]=0x00;
Module_Red2Buffer[module]=0x00;
Module_Green1Buffer[module]=0x00;
Module_Green2Buffer[module]=0x00;
}
}
/**************************************************************************************
* 名 称: GUI_Point()
* 功 能:在指定位置上画点。
* 参 数:x 指定点所在列的位置
* y 指定点所在行的位置
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 返 回 值:返回值为1时表示操作成功,为0时表示操作失败。
**************************************************************************************/
void GUI_Point(INT16S x0, INT16S y0, INT8U color)
{
Outdoor_DrawPoint(x0,y0,color);
Indoor_DrawPoint(x0,y0,color);
}
/**************************************************************************************
* 名 称: GUI_HLine()
* 功 能:画水平线。
* 参 数: x0 水平线起点所在列的位置
* y0 水平线起点所在行的位置
* x1 水平线终点所在列的位置
* color 显示颜色
* 返 回 值:
**************************************************************************************/
void GUI_HLine(INT16S x0, INT16S y0, INT16S x1, INT8U color)
{
INT16S i;
// 对x0、x1大小进行排列,以便画图
if(x0>x1)
{
i = x1;
x1 = x0;
x0 = i;
}
for(i=0;i<x1-x0;i++)
{
GUI_Point(x0+i,y0,color);
}
}
/**************************************************************************************
* 名 称:GUI_RLine()
* 功 能:画竖直线 根据硬件特点,实现加速。
* 参 数:x0 垂直线起点所在列的位置
* y0 垂直线起点所在行的位置
* y1 垂直线终点所在行的位置
* color 显示颜色
* 返 回 值:
**************************************************************************************/
void GUI_RLine(INT16S x0, INT16S y0, INT16S y1, INT8U color)
{
INT16S i;
// 对y0、y1大小进行排列,以便画图
if(y0>y1)
{
i = y1;
y1 = y0;
y0 = i;
}
for(i=0;i<y1-y0;i++)
{
GUI_Point(x0,y0+i,color);
}
}
/****************************************************************************
* 名称:GUI_Rectangle()
* 功能:画矩形。
* 入口参数: x0 矩形左上角的x坐标值
* y0 矩形左上角的y坐标值
* x1 矩形右下角的x坐标值
* y1 矩形右下角的y坐标值
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Rectangle(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color)
{
GUI_HLine(x0, y0, x1, color);
GUI_HLine(x0, y1, x1, color);
GUI_RLine(x0, y0, y1, color);
GUI_RLine(x1, y0, y1, color);
}
/****************************************************************************
* 名称:GUI_Circle()
* 功能:指定圆心位置及半径,画圆。
* 入口参数: x0 圆心的x坐标值
* y0 圆心的y坐标值
* r 圆的半径
* color 显示颜色
* 出口参数: 无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Circle(INT16S x0, INT16S y0, INT16S r, INT8U color)
{
INT16S draw_x0, draw_y0; // 刽图点坐标变量
INT16S draw_x1, draw_y1;
INT16S draw_x2, draw_y2;
INT16S draw_x3, draw_y3;
INT16S draw_x4, draw_y4;
INT16S draw_x5, draw_y5;
INT16S draw_x6, draw_y6;
INT16S draw_x7, draw_y7;
INT16S xx, yy; // 画圆控制变量
INT16S di; // 决策变量
/* 参数过滤 */
if(0==r) return;
/* 计算出8个特殊点(0、45、90、135、180、225、270度),进行显示 */
draw_x0 = draw_x1 = x0;
draw_y0 = draw_y1 = y0 + r;
GUI_Point(draw_x0, draw_y0, color); // 90度
draw_x2 = draw_x3 = x0;
draw_y2 = draw_y3 = y0 - r;
if(draw_y2>=0) GUI_Point(draw_x2, draw_y2, color); // 270度
draw_x4 = draw_x6 = x0 + r;
draw_y4 = draw_y6 = y0;
GUI_Point(draw_x4, draw_y4, color); // 0度
draw_x5 = draw_x7 = x0 - r;
draw_y5 = draw_y7 = y0;
if(draw_x5>=0) GUI_Point(draw_x5, draw_y5, color); // 180度
if(1==r) return; // 若半径为1,则已圆画完
/* 使用Bresenham法进行画圆 */
di = 3 - 2*r; // 初始化决策变量
xx = 0;
yy = r;
while(xx<yy)
{
if(di<0)
{
di += 4*xx + 6;
}
else
{
di += 4*(xx - yy) + 10;
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
draw_x4--;
draw_x5++;
draw_x6--;
draw_x7++;
}
xx++;
draw_x0++;
draw_x1--;
draw_x2++;
draw_x3--;
draw_y4++;
draw_y5++;
draw_y6--;
draw_y7--;
/* 要判断当前点是否在有效范围内 */
if( draw_y0>=0 )
{
GUI_Point(draw_x0, draw_y0, color);
}
if( (draw_x1>=0)&&(draw_y1>=0) )
{
GUI_Point(draw_x1, draw_y1, color);
}
GUI_Point(draw_x2, draw_y2, color);
if( draw_x3>=0)
{
GUI_Point(draw_x3, draw_y3, color);
}
if( draw_y4>=0 )
{
GUI_Point(draw_x4, draw_y4, color);
}
if( (draw_x5>=0)&&(draw_y5>=0) )
{
GUI_Point(draw_x5, draw_y5, color);
}
GUI_Point(draw_x6, draw_y6, color);
if( draw_x7>=0 )
{
GUI_Point(draw_x7, draw_y7, color);
}
}
}
/****************************************************************************
* 名称:GUI_Ellipse()
* 功能:画正椭圆。给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点
* 的y轴坐标为y0、y1。
* 入口参数:x0 最左点的x坐标值
* x1 最右点的x坐标值
* y0 最上点的y坐标值
* y1 最下点的y坐标值
* color 显示颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_Ellipse(INT16S x0,INT16S x1,INT16S y0,INT16S y1,INT8S color)
{
INT16S draw_x0,draw_y0 ;
// 刽图点坐标变量
INT16S draw_x1,draw_y1 ;
INT16S draw_x2,draw_y2 ;
INT16S draw_x3,draw_y3 ;
INT16S xx,yy ;
// 画图控制变量
INT16S center_x,center_y ;
// 椭圆中心点坐标变量
INT16S radius_x,radius_y ;
// 椭圆的半径,x轴半径和y轴半径
INT16S radius_xx,radius_yy ;
// 半径乘平方值
INT16S radius_xx2,radius_yy2 ;
// 半径乘平方值的两倍
INT16S di ;
// 定义决策变量
/* 参数过滤 */
if((x0==x1)||(y0==y1))return ;
/* 计算出椭圆中心点坐标 */
center_x=(x0+x1)>>1 ;
center_y=(y0+y1)>>1 ;
/* 计算出椭圆的半径,x轴半径和y轴半径 */
if(x0>x1)
{
radius_x=(x0-x1)>>1 ;
}
else
{
radius_x=(x1-x0)>>1 ;
}
if(y0>y1)
{
radius_y=(y0-y1)>>1 ;
}
else
{
radius_y=(y1-y0)>>1 ;
}
/* 计算半径平方值 */
radius_xx=radius_x*radius_x ;
radius_yy=radius_y*radius_y ;
/* 计算半径平方值乘2值 */
radius_xx2=radius_xx<<1 ;
radius_yy2=radius_yy<<1 ;
/* 初始化画图变量 */
xx=0 ;
yy=radius_y ;
di=radius_yy2+radius_xx-radius_xx2*radius_y ;
// 初始化决策变量
/* 计算出椭圆y轴上的两个端点坐标,作为作图起点 */
draw_x0=draw_x1=draw_x2=draw_x3=center_x ;
draw_y0=draw_y1=center_y+radius_y ;
draw_y2=draw_y3=center_y-radius_y ;
GUI_Point(draw_x0,draw_y0,color);
// 画y轴上的两个端点
GUI_Point(draw_x2,draw_y2,color);
while((radius_yy*xx)<(radius_xx*yy))
{
if(di<0)
{
di+=radius_yy2*(2*xx+3);
}
else
{
di+=radius_yy2*(2*xx+3)+4*radius_xx-4*radius_xx*yy ;
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
}
xx++;
// x轴加1
draw_x0++;
draw_x1--;
draw_x2++;
draw_x3--;
GUI_Point(draw_x0,draw_y0,color);
GUI_Point(draw_x1,draw_y1,color);
GUI_Point(draw_x2,draw_y2,color);
GUI_Point(draw_x3,draw_y3,color);
}
di=radius_xx2*(yy-1)*(yy-1)+radius_yy2*xx*xx+radius_yy+radius_yy2*xx-radius_xx2*radius_yy ;
while(yy>=0)
{
if(di<0)
{
di+=radius_xx2*3+4*radius_yy*xx+4*radius_yy-2*radius_xx2*yy ;
xx++;
// x轴加1
draw_x0++;
draw_x1--;
draw_x2++;
draw_x3--;
}
else
{
di+=radius_xx2*3-2*radius_xx2*yy ;
}
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
GUI_Point(draw_x0,draw_y0,color);
GUI_Point(draw_x1,draw_y1,color);
GUI_Point(draw_x2,draw_y2,color);
GUI_Point(draw_x3,draw_y3,color);
}
}
void GUI_Display_Data(INT8U data,INT16S x0,INT16S y0,INT8U color)
{
INT8U i;
for(i=0;i<8;i++)
{
if( (data&(1<<i)) )
{
Outdoor_DrawPoint(x0+7-i,y0,color);
Indoor_DrawPoint(x0+7-i,y0,color);
}
}
}
void GUI_Display_ASCII(INT8U Char,INT16S x0,INT16S y0,INT8U color)
{
INT8U i;
INT16U temp;
//if(x0>=LCD_XSIZE) x0=x0%LCD_XSIZE;
//if(y0>=LCD_YSIZE) y0=y0%LCD_YSIZE;
for(i=0;i<16;i++)
{
temp=i+(INT16U)(Char-0x20)*16;
GUI_Display_Data(nAsciiDot[temp],x0,y0+i,color);
}
}
void GUI_Display_Chinese(INT16U UniCode,INT16S x0,INT16S y0,INT8U color)
{
INT16U CodeID;
INT8U i,ImgData;
INT8U temp;
INT8U ziku[32];
//if(x0>=LCD_XSIZE) x0=x0%LCD_XSIZE;
//if(y0>=LCD_YSIZE) y0=y0%LCD_YSIZE;
if( GUIChineseFont==Chinese_16x16 )
{
//在字库里搜索汉字
for(CodeID=0; CodeID < HzNum; CodeID++)
{
// 找到 指定汉字的 Index 后, 跳出循环
if( (GB_16[CodeID].Index[0]==UniCode/256) && (GB_16[CodeID].Index[1]==UniCode%256) )
{
break;
}
}
//如果从Flash里面没有搜索到汉字,就从字库芯片里取数据。
if( CodeID == HzNum )
{
//未检索到的汉字,显示个"##"提示吧
//GUI_Display_ASCII('#',x0,y0,color);
//GUI_Display_ASCII('#',x0+Char_XSIZE,y0,color);
Read_GT21L16S1W(UniCode,ziku); //从字库芯片GT21L16S1W读取数据到缓存ziku[];
temp=y0;
for(i=0; i<Chinese_XSIZE*2; i+=2)
{
ImgData = ziku;
GUI_Display_Data(ImgData,x0,temp++,color);
}
temp=y0;
for(i=1; i<Chinese_XSIZE*2; i+=2)
{
ImgData = ziku;
GUI_Display_Data(ImgData,x0+8,temp++,color);
}
return;
}
else
{
//----------------------------------
temp=y0;
for(i=0; i<Chinese_XSIZE*2; i+=2)
{
ImgData = GB_16[CodeID].Msk;
GUI_Display_Data(ImgData,x0,temp++,color);
}
temp=y0;
for(i=1; i<Chinese_XSIZE*2; i+=2)
{
ImgData = GB_16[CodeID].Msk;
GUI_Display_Data(ImgData,x0+8,temp++,color);
}
}
}
else if( GUIChineseFont==Chinese_12x12 )
{
//在字库里搜索汉字
for(CodeID=0; CodeID < HzNum; CodeID++)
{
// 找到 指定汉字的 Index 后, 跳出循环
if( (GB_12[CodeID].Index[0]==UniCode/256) && (GB_12[CodeID].Index[1]==UniCode%256) )
{
break;
}
}
if( CodeID == HzNum )//未检索到的汉字,显示个"##"提示吧
{
GUI_Display_ASCII('#',x0,y0,color);
GUI_Display_ASCII('#',x0+Char_XSIZE,y0,color);
return;
}
//----------------------------------
temp=y0;
for(i=0; i<Chinese_XSIZE*2; i+=2)
{
ImgData = GB_12[CodeID].Msk;
GUI_Display_Data(ImgData,x0,temp++,color);
}
temp=y0;
for(i=1; i<Chinese_XSIZE*2; i+=2)
{
ImgData = GB_12[CodeID].Msk;
GUI_Display_Data(ImgData,x0+8,temp++,color);
}
}
}
void GUI_DispStringAt(INT8U *s,INT16S x0,INT16S y0, INT8U color)
{
INT8U i;
INT16U temp;
//if(x0>LCD_XSIZE) x0=x0%LCD_XSIZE;
//if(y0>LCD_YSIZE) y0=y0%LCD_YSIZE;
i = 0;
while(s!='\0')
{
if (s < 0x80) //是ASCII
{
if(s == '\n')
{
x0 = 0;
y0 += Char_YSIZE;
}
else
{
if(x0 > GUI_XWORD*16-Char_XSIZE)
{
x0 = 0;
y0 += Char_YSIZE;
}
GUI_Display_ASCII(s,x0, y0,color);
x0 += Char_XSIZE;
}
}
else //是中文
{
Char_YSIZE=En_8x16_YSIZE;//如果有中文,英文强制转换 8*16
if(x0 > GUI_XWORD*16-Chinese_XSIZE)
{
x0 = 0;
y0 += Chinese_YSIZE;
}
temp=(INT16U)(s)*256+s[i+1];
GUI_Display_Chinese(temp,x0,y0,color);//中文
x0 += Chinese_XSIZE;
i++;
}
i++;
}
}
void GUI_CursorOn(INT16S x0, INT16S y0, INT8U color)
{
INT8U i;
for(i=0;i<8;i++)
{
//Outdoor
Outdoor_DrawPoint(x0,y0+i,color);
Outdoor_DrawPoint(x0+1,y0+i,color);
//Indoor
Indoor_DrawPoint(x0,y0+i,color);
Indoor_DrawPoint(x0+1,y0+i,color);
}
}
// ---- 显示不带符号的整数 (数字 起始位置XY,显示长度) -----------------------------
void GUI_Display_Number(INT16U number, INT16S x0, INT16S y0, INT8U lenth, INT8U color)
{
INT8U temp;
x0 = ( x0 + lenth *En_8x16_XSIZE - En_8x16_XSIZE );
for(; lenth>0; lenth--)
{
temp =(INT8U)(number%10) + '0';
GUI_Display_ASCII(temp,x0,y0,color);
x0 -= En_8x16_XSIZE;
number = number / 10;
}
}
/****************************************************************************
* 名称:GUI_RectangleFill()
* 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。
* 入口参数: x0 矩形左上角的x坐标值
* y0 矩形左上角的y坐标值
* x1 矩形右下角的x坐标值
* y1 矩形右下角的y坐标值
* color 填充颜色
* 出口参数:无
* 说明:操作失败原因是指定地址超出有效范围。
****************************************************************************/
void GUI_RectangleFill(INT16S x0, INT16S y0, INT16S x1, INT16S y1, INT8U color)
{
INT16S x,y;
for(x=x0;x<x1;x++)
{
for(y=y0;y<y1;y++)
{
Outdoor_DrawPoint(x,y,color);
Indoor_DrawPoint(x,y,color);
}
}
}
void GUI_Write_Module(void)
{
INT8U i,module;
//禁止中断
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 , DISABLE);
//Outdoor
for(module=0;module<OutMODULE_NUM;module++)
{
Convert(module);//GUI缓冲转化为模组缓冲数据
for(i=0;i<32;i++)
{
LCD_RedBuffer[module] =Module_RedBuffer[module];
LCD_GreenBuffer[module]=Module_GreenBuffer[module];
}
}
//Indoor
for(module=0;module<InMODULE_NUM;module++)
{
for(i=0;i<32;i++)
{
LCD_Red1Buffer[module] =Module_Red1Buffer[module];
LCD_Red2Buffer[module] =Module_Red2Buffer[module];
LCD_Green1Buffer[module]=Module_Green1Buffer[module];
LCD_Green2Buffer[module]=Module_Green2Buffer[module];
}
}
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 , ENABLE);
} |
|