/****************************************Copyright (c)************************************************** * File Name: GUI.c * Function Describe: * Explain: * Writer: ShiLiangWen * Date: 2016-1-8 ********************************************************************************************************/ #include "includes.h" extern const unsigned char g_apucLetter16[]; extern const unsigned char g_apucCLetter16[]; extern const unsigned char g_apucLetter12[]; extern const unsigned char g_apucFonts12[]; extern const unsigned char g_apucLetter24[]; extern const unsigned char g_apucCLetter24[]; extern const unsigned char g_apucFonts16[]; extern const unsigned char g_apucCFonts16[]; extern const unsigned char g_apucFonts24[]; extern const unsigned char g_apucCFonts24[]; //字库结构体? SUT_HZK sutHzk16; SUT_HZK sutHzk12; unsigned char g_Palette[256*4];//调色板 顺序是BGRA 其中A未用 unsigned char g_aucLcdBuf[LCD_HEIGHT][LCD_WIDTH];//显示缓冲区 //unsigned char g_aucLcdCopyBuf[LCD_HEIGHT][LCD_WIDTH];//拷贝显示缓冲区 u8 g_ucWarnColorId; //警告颜色 u8 g_ucForeColorId; //画笔颜色索引 u8 g_ucBackColorId; //背景颜色索引 /**************************M20***********************************/ unsigned char RedColorId;//红色值 unsigned char BlueColorId;//蓝色值 unsigned char GreenColorId;//绿色值 unsigned char OrangeColorId;//橙色值 u16 g_usWarnColor;//警告色 u16 g_usForeColor;//前景色 RGB565值 需要根据颜色索引从当前调色板中获取 u16 g_usBackColor;//背景色 RGB656值 需要根据颜色索引从当前调色板中获取 void PaintToBuf(u16 x,u16 y,u16 width,u16 heigh,u8 *data); void PaintBufToLcd(u16 x,u16 y,u16 width,u16 heigh); u16 RGB888toRGB565(unsigned char R,unsigned char G, unsigned char B); void SetPaletteByBmpFile(char *filename); void UpdateColor(void); void GuiDrawDot(u16 x,u16 y); /*************************************************************************** 在调色板中查找与期望颜色最接近的颜色并返回其索引 输入:ColorRGB 格式:0xRRGGBB 红绿蓝 返回:在调色板中,最接近ColorRGB的颜色索引 算法:对调色板内的每个色素点分别求出RGB之差的绝对值并求和,然后找出最小值所对应的色素点的索引即可 ****************************************************************************/ int FindColorIndex(unsigned long ColorRGB) { int i,j,k; int R,G,B; int fR,fG,fB;//计算期望RGB和调色板内每个RGB差的绝对值 int fSum,fSumMin; R=(int)((ColorRGB>>16)&0xff); G=(int)((ColorRGB>>8)&0xff); B=(int)(ColorRGB&0xff); fSumMin=999999; k=0; for(i=0;i<256;i++){ j=i*4; fB=g_Palette[j]; fG=g_Palette[j+1]; fR=g_Palette[j+2]; //g_Palette[j+3]未用 fB=B-fB;//B差 if(fB<0)fB=-fB; //B差的绝对值 fG=G-fG;//G差 if(fG<0)fG=-fG;//G差的绝对值 fR=R-fR;//R差 if(fR<0)fR=-fR;//R差的绝对值 //RGB差的绝对值求和 fSum=fB+fG+fR; //找到RGB差的绝对值之和的最小值 if(fSum>3; // 取R色的高5位 g = G>>2; // 取G色的高6位 b = B>>3; // 取B色的高5位 return( (r<<11) + (g<<5) + (b<<0) ); } /***************************************** 从字库文件HZK16中提取某汉子的字库数据 输入:hiByte--汉字的高字节 loByte--汉字的低字节 字库文件存储在sFlash中,字库文件名为HZK16 输出:pHzk--提取到的字库数据,需要预留足够空间存储。如果是16*16 则应该是16*16/8=32Byte 返回:失败返回0 成功返回长度 ******************************************/ int GetHzk(u8 hiByte,u8 loByte,u8 *pHzk,u8 font) { u8 Q,W; u32 offset; if(hiByte<0xa0 || loByte<0xa0)return 0; Q=hiByte-0xa0; W=loByte-0xa0; if(!font) { offset=(94 * (Q-1) + (W-1))* 24; return ReadFileData(sutHzk12.FileIndex,offset,24,pHzk); }else { offset=(94 * (Q-1) + (W-1))* 32; return ReadFileData(sutHzk16.FileIndex,offset,32,pHzk); } } /****************************************** *汉子库初始化 *输入:汉字库文件名 *输出:汉字库数据首地址存放在sHZK16中 *返回:1--成功 0--失败,找不到文件 *******************************************/ int HzkInit(const char *filename) { int i; if(g_sutFilesList.FileCount==0)return 0; if(!strcmp(filename,"HZK16")) {memset(&sutHzk16,0,sizeof(SUT_HZK)); i=GetFileIndex(filename); if(i<0)return 0; sutHzk16.width=16; sutHzk16.heigh=16; sutHzk16.len=(sutHzk16.width * sutHzk16.heigh)/8; sutHzk16.FileIndex=i; sutHzk16.FileLen=g_sutFilesList.FileInfo[i].FileLen; return 1; }else if(!strcmp(filename,"HZK12")){ memset(&sutHzk12,0,sizeof(SUT_HZK)); i=GetFileIndex(filename); if(i<0)return 0; sutHzk12.FileIndex=i; sutHzk12.FileLen=g_sutFilesList.FileInfo[i].FileLen; return 1; } } /************************************************************* 将整个显示区域填充为背景色 **************************************************************/ void GuiClearAll(void) { memset(g_aucLcdBuf,g_ucBackColorId,sizeof(g_aucLcdBuf)); PaintBufToLcd(0,0,LCD_WIDTH,LCD_HEIGHT); //0 0 //18 } /************************************************************* 将整个显示区域填充为背景色 **************************************************************/ void GuiClearAllM20(void) { unsigned char i,j; //tsk_lock(); memset(g_aucLcdBuf,g_ucBackColorId,sizeof(g_aucLcdBuf)); for(i=0;i<19;i++){ for(j=0;j<=LCD_WIDTH;j++){ g_aucLcdBuf[i][j]=COLOR_BLACK; } } //PaintBufToLcd(0,0,LCD_WIDTH,18); //0 0 //18 PaintBufToLcd(0,0,LCD_WIDTH,LCD_HEIGHT); //tsk_unlock(); } void GuiClearAllM20Test(unsigned char color) { unsigned char i,j; memset(g_aucLcdBuf,color,sizeof(g_aucLcdBuf)); PaintBufToLcd(0,0,LCD_WIDTH,LCD_HEIGHT); } /****************************************** GuiInit 初始化GUI *******************************************/ void GuiInit(void) { if(!HzkInit(HZK16_FILE_NAME)) { printf("Can't find the HzkFile(%s)!\r\n",HZK16_FILE_NAME); } if(!HzkInit(HZK12_FILE_NAME)) { printf("Can't find the HzkFile(%s)!\r\n",HZK12_FILE_NAME); } //设置默认调色板 //GuiSetDefaultPalette();//设置系统调色板为程序代码中预设的调色板 SetPaletteByBmpFile("logo.bmp");//从指定BMP文件中提取调色板作为系统调色板 //设置前景色和背景色,设置前景色和背景色前需要先设置调色板 GuiSetColor(COLOR_ORANGE,COLOR_WHITE,COLOR_RED);//200 RedColorId=FindColorIndex(COLOR_RED); BlueColorId=FindColorIndex(COLOR_BLUE); GreenColorId=FindColorIndex(COLOR_GREEN); OrangeColorId=FindColorIndex(COLOR_ORANGE); //清空所有显示区域,即将所有显示区域设置为背景色 //GuiClearAll(); LcdClrAll(); } /************************************************************ GuiPainToBuf 将位图数据刷到显示缓冲区 位图数据按:每行从左到右,从上行到下行扫描 *************************************************************/ void PaintToBuf(u16 x,u16 y,u16 width,u16 heigh,u8 *data) { int i,j,k,t; for(j=0;j=LCD_WIDTH || y>=LCD_HEIGHT)return; if(x+width>LCD_WIDTH)width=LCD_WIDTH-x-1; if(y+heigh>LCD_HEIGHT)heigh=LCD_HEIGHT-y-1; IWDG_ReloadCounter();//防止刷的死机 LcdBlockWrite(x,y,x+width-1,y+heigh-1); for(j=0;j>3; // 取R色的高5位 g = G>>2; // 取G色的高6位 b = B>>3; // 取B色的高5位 RGB565=((r<<11) + (g<<5) + (b<<0)); LcdSendData(RGB565 >> 8); LcdSendData(RGB565 & 0xff); } } } /*************************************************************************** PaintCharToBuf 在显示缓存中写字符,并未刷到LCD显示 ****************************************************************************/ void PaintCharToBuf(u16 x,u16 y,u8 hiByte,u8 loByte,u8 mode) { unsigned short i,j,k,m,n; unsigned short width,height; unsigned char ByteWidth,data; unsigned char colorH,colorL; unsigned char bgcolorH,bgcolorL; const unsigned char *l_pucFont,*l_pucLetter; unsigned char *p; unsigned char font;//字体 unsigned char cover;//覆盖方式 unsigned char sucHzk12[24]; unsigned char sucHzk16[32]; font=mode&0xf0; cover=mode&0x0f; k=0; //=================先根据字符设置显示的宽、高、点阵数据指针等=== if(!hiByte) //english { if(font==0x00) //8*12 { width=12;//8 height =12; ByteWidth = 2;//1 l_pucFont = g_apucFonts12; l_pucLetter = g_apucLetter12; }else{ //8*16 width=8; height =16; ByteWidth = 1; l_pucFont = g_apucFonts16; l_pucLetter = g_apucLetter16; } while(*l_pucLetter) { if(loByte == *l_pucLetter)break; l_pucLetter ++; k ++; } //查找到字库的开始位置 l_pucFont += k * ByteWidth * height; } else { //chinese if(font == 0x00)//12 *16 { width=16; height = 12; ByteWidth = 2; l_pucFont = sucHzk12; l_pucLetter = 0; k=0; if(sizeof(sucHzk12)!=GetHzk(hiByte,loByte,sucHzk12,font)){//从sFlash的HZK文件中读取字库数据 //找不到字库,显示"口" l_pucFont=g_apucCLetter16; } }else{//16*16 width=16; height = 16; ByteWidth = 2; l_pucFont = sucHzk16; l_pucLetter = 0; k=0; if(sizeof(sucHzk16)!=GetHzk(hiByte,loByte,sucHzk16,font)){//从sFlash的HZK16文件中读取字库数据 //找不到字库,显示"口" l_pucFont=g_apucCLetter16; } } // } //====================再处理点阵数据========== if(y+height>=LCD_HEIGHT)return; if(x+width>=LCD_WIDTH)return; #if 1 //根据字模在显存中画点 for(j=0;j>k)){//有点,画上前景色 g_aucLcdBuf[m][n+k]=g_ucForeColorId; }else{//无点 if(cover){//覆盖模式下,无点的位置也填上背景颜色 g_aucLcdBuf[m][n+k]=g_ucBackColorId; } } } } } #else //以下直接将点阵刷到LCD,不用显存。用于测试,注意调用不要调用PaintBufToLcd,否则也刷屏了 colorH=0xff; colorL=0xff; bgcolorH=0x00; bgcolorL=0x00; LcdBlockWrite(x,y,x+width-1,y+height-1); for(j=0;j>k)){ LcdSendData(colorH); LcdSendData(colorL); }else{ //if(cover){ LcdSendData(bgcolorH); LcdSendData(bgcolorH); //} } } } } #endif } void GuiShowStr(u16 x, u16 y,const char *string,u8 mode) { unsigned char width1,width2,heigh; unsigned char *p; unsigned short i; unsigned char font;//字体 font=mode&0xf0; if(font == 0x00) //12*12 font { width1 = 12; width2 = 1; heigh=12; } else //16*16 font { width1 = 16; width2 = 1; heigh=16; } p = (unsigned char *)string; i = 0; while(*p) { if (*p > 0x9f) //chinese letter { PaintCharToBuf(x+i,y,*p, *(p+1),mode); i += width1 ; p += 2; } else //english letter { PaintCharToBuf(x + i,y,0,*p,mode); if(font==0){ i += width2 * 8; //8 }else{ i += width2 * 8; } p ++; } } //将内容从显存刷到LCD显示 PaintBufToLcd(x,y,i,heigh); } /*************************************************************************** PaintCharToBuf 在显示缓存中写字符,并未刷到LCD显示 M20 仅 状态栏使用 ****************************************************************************/ void PaintCharToBuf2(u16 x,u16 y,u8 hiByte,u8 loByte,u8 mode,unsigned char Fore, unsigned char Back) { unsigned short i,j,k,m,n; unsigned short width,height; unsigned char ByteWidth,data; unsigned char colorH,colorL; unsigned char bgcolorH,bgcolorL; const unsigned char *l_pucFont,*l_pucLetter; unsigned char *p; unsigned char font;//字体 unsigned char cover;//覆盖方式 unsigned char sucHzk12[24]; unsigned char sucHzk16[32]; font=mode&0xf0; cover=mode&0x0f; //=================先根据字符设置显示的宽、高、点阵数据指针等=== k = 0; if(!hiByte) //english { if(font==0x00) //8*12 { width=12; height =12; //16 ByteWidth = 2; l_pucFont = g_apucFonts12; l_pucLetter = g_apucLetter12; }else{ //8*16 width=8; height =16; ByteWidth = 1; l_pucFont = g_apucFonts16; l_pucLetter = g_apucLetter16; } while(*l_pucLetter) { if(loByte == *l_pucLetter)break; l_pucLetter ++; k ++; } //查找到字库的开始位置 //l_pucFont += k * ByteWidth * height; l_pucFont += k * ByteWidth * height; } else { //chinese if(font == 0x00)//12 *16 { width=16; height = 12; ByteWidth = 2; l_pucFont = sucHzk12; l_pucLetter = 0; k=0; if(sizeof(sucHzk12)!=GetHzk(hiByte,loByte,sucHzk12,font)){//从sFlash的HZK文件中读取字库数据 //找不到字库,显示"口" l_pucFont=g_apucCLetter16; } }else{//16*16 width=16; height = 16; ByteWidth = 2; l_pucFont = sucHzk16; l_pucLetter = 0; k=0; if(sizeof(sucHzk16)!=GetHzk(hiByte,loByte,sucHzk16,font)){//从sFlash的HZK16文件中读取字库数据 //找不到字库,显示"口" l_pucFont=g_apucCLetter16; } } // } //====================再处理点阵数据========== if(y+height>=LCD_HEIGHT)return; if(x+width>=LCD_WIDTH)return; //根据字模在显存中画点 for(j=0;j>k)){//有点,画上前景色 g_aucLcdBuf[m][n+k]=Fore;//COLOR_WHITE; }else{//无点 if(cover){//覆盖模式下,无点的位置也填上背景颜色 g_aucLcdBuf[m][n+k]=Back;//COLOR_BLACK; } } } } } } //GuiShowStr(x,y-8,buf,0x01); //M20 void GuiShowStrM20(u16 x, u16 y,const char *string,u8 mode,unsigned char Fore,unsigned char Back) { unsigned char width1,width2,heigh; unsigned char *p; unsigned short i; unsigned char font;//字体 font=mode&0xf0; if(font == 0x00) //12*12 font { width1 = 12; width2 = 1; heigh=12; } else //16*16 font { width1 = 16; width2 = 1; heigh=16; } p = (unsigned char *)string; i = 0; while(*p) { if (*p > 0x9f) //chinese letter { PaintCharToBuf2(x+i,y,*p, *(p+1),mode,Fore,Back); i += width1 ; p += 2; } else //english letter { PaintCharToBuf2(x + i,y,0,*p,mode,Fore,Back); if(font==0){ i += width2 * 8; //8 }else{ i += width2 * 8; } p ++; } } //将内容从显存刷到LCD显示 PaintBufToLcd(x,y,i,heigh); } /************************************************************ 从代码区读出图片并显示 *************************************************************/ void GuiShowPic(u8 x,u8 y,const unsigned char *pic) { int i,j,len; unsigned int width,heigh; u8 R,G,B; u16 RGB565; const unsigned char *data; HEADGRAY headgray; memcpy(&headgray,pic,sizeof(HEADGRAY)); LcdBlockWrite(x,y,x+headgray.w-1,y+headgray.h-1); len=headgray.w * headgray.h; data=pic+sizeof(HEADGRAY); for(i=0;i> 8); LcdSendData(RGB565 & 0xff); } } /************************************************************ GuiShowBmp 从sFlsh中读取BMP文件并显示 *************************************************************/ void GuiShowBmp(u16 x,u16 y,const char * filename) { int i,w,l; int index; int FileLen; unsigned short type; unsigned int width,heigh,SizeImage,bfOffBits; unsigned char temp[160]; index=GetFileIndex(filename); FileLen=GetFileLen(index); if(FileLen==0)return;//找不到文件,直接返回不处理 //读出位图类型 ReadFileData(index,28,2,(u8 *)&type);//读出int biBitCount ; // 每个像素所需的位数,必须是或 1,4,8 24(// 真彩色 ) 之一 (28-29 字节 ) if(type!=0x0008)return;//非256色的BMP图,直接返回不处理。 //读出位图的宽度 ReadFileData(index,18,4,(u8 *)&width); //int image_width ; // 位图的宽度,以像素为单位 (18-21 字节 ) // printf("width=%u\r\n",width); //读出位图的高度 ReadFileData(index,22,4,(u8 *)&heigh); //int image_heigh ; // 位图的高度,以像素为单位 (22-25 字节 ) //printf("heigh=%u\r\n",heigh); if(width>LCD_WIDTH || heigh>LCD_HEIGHT)return;//超过LCD显示范围,不处理 //读位图数据起始地址 ReadFileData(index,10,4,(u8 *)&bfOffBits); //int bfOffBits ; // 位图数据的起始位置,以相对于位图 (10-13 字节 ) //读取调色板数据 ReadFileData(index,54,1024,g_Palette); //以下读位图数据放到显示缓冲区 i=width%4; if(i>0){//每行像素数不是4的倍数,则需要补到4的倍数 w=width + (4-width%4);//每行字节数为4的倍数,不够的补齐 }else{ w=width; } l=heigh-1;//BMP扫描顺序是:从下往上,从左往右扫描,因此先从最后一行开始读数据 for(i=0;ix2||y1>y2)return; if(x2>=LCD_WIDTH)x2=LCD_WIDTH-1; if(y2>=LCD_HEIGHT)y2=LCD_HEIGHT-1; w=x2-x1+1; h=y2-y1+1; for(j=0;jx2||y1>y2)return; if(x2>=LCD_WIDTH)x2=LCD_WIDTH-1; if(y2>=LCD_HEIGHT)y2=LCD_HEIGHT-1; w=x2-x1+1; h=y2-y1+1; for(j=0;j=LCD_WIDTH||y>=LCD_HEIGHT)return; if(x+width >=LCD_WIDTH)width=LCD_WIDTH-x-1; if(y+heigh >=LCD_HEIGHT)heigh=LCD_HEIGHT-y-1; for(j=0;j=LCD_WIDTH||y>=LCD_HEIGHT)return; if(x+width >=LCD_WIDTH)width=LCD_WIDTH-x-1; if(y+heigh >=LCD_HEIGHT)heigh=LCD_HEIGHT-y-1; for(j=0;jx2||y1>y2)return; if(x1>=LCD_WIDTH || y1>=LCD_HEIGHT)return; if(x2>=LCD_WIDTH)x2=LCD_WIDTH-1; if(y2>=LCD_HEIGHT)y2=LCD_HEIGHT-1; w=x2-x1+1; h=y2-y1+1; for(j=0;j(LCD_HEIGHT-1))y=LCD_HEIGHT-1; for(i=0;i(LCD_WIDTH-1))x=LCD_WIDTH-1; { //g_aucLcdBuf[y][x]=g_ucForeColorId; switch(colorIndex) { case COLOR_WARN_RED:g_aucLcdBuf[y][x]=g_ucWarnColorId;break; case COLOR_CHARGE_BLUE : g_aucLcdBuf[y][x]=GreenColorId; break; case COLOR_DEFAULT_BLUE: default:g_aucLcdBuf[y][x]=g_ucForeColorId;break; } } } } PaintBufToLcd(x1,y1,w,h); } #else /**************************************************************************** GuiFillRect 指定矩形区域填充前景色 ****************************************************************************/ void GuiFillRect(u16 x1, u16 y1, u16 x2, u16 y2) { u16 i,j,h,w; u16 x,y; if(x1>x2||y1>y2)return; if(x1>=LCD_WIDTH || y1>=LCD_HEIGHT)return; if(x2>=LCD_WIDTH)x2=LCD_WIDTH-1; if(y2>=LCD_HEIGHT)y2=LCD_HEIGHT-1; w=x2-x1+1; h=y2-y1+1; for(j=0;j(LCD_HEIGHT-1))y=LCD_HEIGHT-1; for(i=0;i(LCD_WIDTH-1))x=LCD_WIDTH-1; g_aucLcdBuf[y][x]=g_ucForeColorId; } } PaintBufToLcd(x1,y1,w,h); } #endif /**************************************************************************** GuiDrawHLine 画水平线 ****************************************************************************/ void GuiDrawHLine(u16 x1, u16 x2, u16 y, u8 width) { if(width==0)return; if(x2x2||y1>y2)return; GuiDrawHLine(x1,x2,y1,width); GuiDrawHLine(x1,x2,y2,width); GuiDrawVLine(y1,y2,x1,width,COLOR_DEFAULT_BLUE); GuiDrawVLine(y1,y2,x2,width,COLOR_DEFAULT_BLUE); } /*************************************************************************** 根据前景色和背景色的颜色索引g_ucForeColorId、g_ucBackColorId,从当前调色板中获取前景色和背景色g_usForeColor、g_usBackColor ****************************************************************************/ void UpdateColor(void) { u16 temp,r,g,b,RGB565; u8 R,G,B; //更新前景色 temp=g_ucForeColorId*4;//调色板每个索引对应4个字节,分别是BGRA (蓝、绿、红、透明度),目前A未用 B=g_Palette[temp]; G=g_Palette[temp+1]; R=g_Palette[temp+2]; r = R>>3; // 取R色的高5位 g = G>>2; // 取G色的高6位 b = B>>3; // 取B色的高5位 RGB565=((r<<11) + (g<<5) + (b<<0)); g_usForeColor=RGB565; //更新背景色 temp=g_ucBackColorId*4;//调色板每个索引对应4个字节,分别是BGRA (蓝、绿、红、透明度),目前A未用 B=g_Palette[temp]; G=g_Palette[temp+1]; R=g_Palette[temp+2]; r = R>>3; // 取R色的高5位 g = G>>2; // 取G色的高6位 b = B>>3; // 取B色的高5位 RGB565=((r<<11) + (g<<5) + (b<<0)); g_usBackColor=RGB565; //更新警告色 temp=g_ucWarnColorId*4;//调色板每个索引对应4个字节,分别是BGRA (蓝、绿、红、透明度),目前A未用 B=g_Palette[temp]; G=g_Palette[temp+1]; R=g_Palette[temp+2]; r = R>>3; // 取R色的高5位 g = G>>2; // 取G色的高6位 b = B>>3; // 取B色的高5位 RGB565=((r<<11) + (g<<5) + (b<<0)); g_usWarnColor=RGB565; } /**************************************************************************** GuiDrawDot 画点:在显存及LCD上指定位置显示前景色! ****************************************************************************/ void GuiDrawDot(u16 x,u16 y) { LcdSendCommand(0x2a); LcdSendData(x>>8); LcdSendData(x&0x00ff); LcdSendCommand(0x2b); LcdSendData(y>>8); LcdSendData(y&0x00ff); LcdSendCommand(0X2C); g_aucLcdBuf[x][y]=g_ucForeColorId; LcdSendData(g_usForeColor >> 8); LcdSendData(g_usForeColor & 0xff); } /**************************************************************************** GuiShowArrow 显示箭头,箭头尺寸16*16 ,左上角坐标x,y 模式mode: 高四位代表填充: 0x--非填充(只有边缘线条) 1x--填充 低四位代表方向:x1--向左 x2--向右 x3--向上 x4--向下 ****************************************************************************/ void GuiShowArrow(u16 x,u16 y,u16 len,u8 mode) { u16 i; u8 dir,fill; // if(x>=(LCD_WIDTH-len) || y>=(LCD_HEIGHT-len))return; dir=mode&0x0f; fill=mode&0xf0; switch(dir) { case 1: for(i = 0 ; i < len ; i ++){ GuiDrawRect(x+i,y-i,x+i,y+i,1); } break; case 2: for(i = 0 ; i < len ; i ++){ GuiDrawRect(x-i,y-i,x-i,y+i,1); } break; case 3: for(i = 0 ; i < len ; i ++){ GuiDrawRect(x-i,y+i,x+i,y+i,1); } break; case 4: for(i = 0 ; i < len ; i ++){ GuiDrawRect(x-i,y-i,x+i,y-i,1); } break; default: break; } } /******************************************************* 移动一个矩形区域 *******************************************************/ void GuiMoveRect(u16 xstart,u16 ystart,u16 width,u16 height,u16 xend,u16 yend) { int i,j; int xs,ys,xe,ye; int xd,yd; if((xstart+width)>LCD_WIDTH)return; if((xend+width)>LCD_WIDTH)return; if((ystart+height)>LCD_HEIGHT)return; if((yend+height)>LCD_HEIGHT)return; xd=xend-xstart;//正数表示从左往右移动,负数表示从右往左移动 yd=yend-ystart;//正数表示从上往下移动,负数表示从下往上移动 if(yd>0){ if(xd>0){ //从左往右,从上往下 for(i=height-1;i>=0;i--){ for(j=width-1;j>=0;j--){ xs=xstart+j; ys=ystart+i; xe=xend+j; ye=yend+i; g_aucLcdBuf[ye][xe]=g_aucLcdBuf[ys][xs]; g_aucLcdBuf[ys][xs]=g_ucBackColorId; } } }else{ //从右往左,从上往下 for(i=height-1;i>=0;i--){ for(j=0;j0){ //从左往右,从下往上 for(i=0;i=0;j--){ xs=xstart+j; ys=ystart+i; xe=xend+j; ye=yend+i; g_aucLcdBuf[ye][xe]=g_aucLcdBuf[ys][xs]; g_aucLcdBuf[ys][xs]=g_ucBackColorId; } } }else{ //从右往左,从下往上 for(i=0;iLCD_WIDTH){ *width=0; *height=0; return; } //读出位图的高度 ReadFileData(index,22,4,(u8 *)&h); //int image_heigh ; // 位图的高度,以像素为单位 (22-25 字节 ) //printf("heigh=%u\r\n",h); if(h>LCD_HEIGHT){ *width=0; *height=0; return; } *width=w; *height=h; } /******************************************************* 显示一张BMP图,并使其移动 开始位置:(xstart,ystart) 终点位置(endx,endy) BMP图片文件名:filename 移动速度: d 每次移动的像素点 *******************************************************/ void GuiDrawBmpMoving(u16 xstart,u16 ystart,u16 xend,u16 yend,const char *filename,int d) { int i; u16 x,y,w,h; int xd,yd,xdd,ydd,r; w=0;h=0; GetBmpSize(filename,&w,&h); if(w==0 || h==0)return; GuiShowBmp(xstart,ystart,filename); //计算两个方向的距离xd yd xd=xend-xstart; yd=yend-ystart; //距离的绝对值xdd ydd if(yd<0) ydd=-yd; else ydd=yd; if(xd<0)xdd=-xd; else xdd=xd; if(xdd==ydd && xdd==0)return; //计算两个方向的步进xd yd,其中一个为1或-1 if(xdd>ydd){ if(ydd==0){ yd=0; if(xd>0)xd=d; else xd=-d; }else{ r=xdd/ydd; if(xd>0)xd=r*d; else xd=-r*d; if(yd>0)yd=d; else yd=-d; } }else if(ydd>xdd){ if(xdd==0){ xd=0; if(yd>0)yd=d; else yd=-d; }else{ r=ydd/xdd; if(yd>0)yd=r*d; else yd=-r*d; if(xd>0)xd=d; else xd=-d; } }else{//xdd==ydd if(xd>0)xd=d; else xd=-d; if(yd>0)yd=d; else yd=-d; } //move loop while(xstart!=xend || ystart!=yend) { x=xstart+xd; if(xd>0 && x>xend)x=xend; else if(xd<0 && x0 && y>yend)y=yend; else if(yd<0 && y=LCD_WIDTH)width=LCD_WIDTH-x;// -1 if(y+height>=LCD_HEIGHT)height=LCD_HEIGHT-y; for(j=0;j=LCD_WIDTH)width=LCD_WIDTH-x; if(y+height>=LCD_HEIGHT)height=LCD_HEIGHT-y; for(j=0;j=x2 || y1>=y2)return; if(x2>LCD_WIDTH || y2>LCD_HEIGHT)return; for(j=y1;j<=y2;j++){ for(i=x1;ix2||y1>y2)return; if(x1>=LCD_WIDTH || y1>=LCD_HEIGHT)return; if(x2>=LCD_WIDTH || y2>=LCD_HEIGHT)return; w=x2-x1+1; h=y2-y1+1; for(j=0;jx2||y1>y2)return; if(x1>=LCD_WIDTH || y1>=LCD_HEIGHT)return; if(x2>=LCD_WIDTH || y2>=LCD_HEIGHT)return; w=x2-x1+1; h=y2-y1+1; for(j=0;j sizeof(tempData)) { printf("sys.ini len=%d,should<=%d\r\n",len, sizeof(tempData)); return; } len=ReadFileData(sysIndex,0,len,(u8*)tempData); //读取HP_VOICE_TTS段内容,内容不超过80字节 len=GetParaFromStr(tempData, "HP_VOICE_TTS",sysStartTTS); if(len==0) { printf("no segment HP_VOICE_TTS\r\n"); sysStartTTS[0]=0; return; } if(0==ModemStrCmp(sysStartTTS,"NULL")) sysStartTTS[0]=0; printf("sys.ini ok\r\n%s\r\n",sysStartTTS); }