📄 hanzi.h
字号:
u32 FONT16ADDR ;//16字体存放的地址
u32 FONT12ADDR ;//12字体存放的地址
u32 UNI2GBKADDR;//UNICODE TO GBK 表存放地址
#define LCD_W 240
#define LCD_H 320
//code 字符指针开始
//从字库中查找出字模
//code 字符串的开始地址,ascii码
//mat 数据存放地址 size*2 bytes大小
//正点原子@HYW
//CHECK:09/10/30
void Get_HzMat(unsigned char *code,unsigned char *mat,u8 size)
{
unsigned char qh,ql;
unsigned char i;
unsigned long foffset;
unsigned char ziti;
if(size==16)ziti=2;
else ziti=3;
qh=*code;
ql=*(++code);
if(qh<0x81||ql<0x40||ql==0xff||qh==0xff)//非 常用汉字
{
for(i=0;i<(size*ziti);i++)*mat++=0x00;//填充满格
return; //结束访问
}
if(ql<0x7f)ql-=0x40;//注意!
else ql-=0x41;
qh-=0x81;
foffset=((unsigned long)190*qh+ql)*(size*ziti);//得到字库中的字节偏移量
if(size==24)SPI_Flash_Read(mat,foffset+FONT16ADDR,72);
else SPI_Flash_Read(mat,foffset+FONT12ADDR,32);
}
//显示一个指定大小的汉字
//x,y :汉字的坐标
//font:汉字GBK码
//size:字体大小
//mode:0,正常显示,1,叠加显示
//正点原子@HYW
//CHECK:09/10/30
void Show_Font(u8 x,u16 y,u8 *font,u8 size,u8 mode)
{
u8 temp,t,t1;
u16 x0=x;
u8 dzk[72];
u16 tempcolor;
unsigned char ziti;
if(size==16)ziti=2;
else ziti=3;
Get_HzMat(font,dzk,size);//得到相应大小的点阵数据
if(mode==0)//正常显示
{
for(t=0;t<size*ziti;t++)
{
temp=dzk[t];//得到12数据
for(t1=0;t1<8;t1++)
{
if(temp&0x80)LCD_DrawPoint(y,x);
else
{
tempcolor=POINT_COLOR;
POINT_COLOR=BACK_COLOR;
LCD_DrawPoint(y,x);
POINT_COLOR=tempcolor;//还原
}
temp<<=1;
x--;
if((x0-x)==size)
{
x=x0;
y++;
break;
}
}
}
}else//叠加显示
{
for(t=0;t<size*ziti;t++)
{
temp=dzk[t];//得到12数据
for(t1=0;t1<8;t1++)
{
if(temp&0x80)LCD_DrawPoint(x,y);
temp<<=1;
x--;
if((x0-x)==size)
{
x=x0;
y++;
break;
}
}
}
}
}
//在指定位置开始显示一个字符串
//支持自动换行
//(x,y):起始坐标
//str :字符串
//size :字体大小
//mode:0,非叠加方式;1,叠加方式
//正点原子@HYW
//CHECK:09/10/30
void Show_Str(u8 x,u16 y,u8*str,u8 size,u8 mode)
{
u8 bHz=0; //字符或者中文
while(*str!=0)//数据未结束
{
if(!bHz)
{
if(*str>0x80)bHz=1;//中文
else //字符
{
if(x>(LCD_W-size/2))//换行
{
y+=size;
x=0;
}
if(y>(LCD_H-size))break;//越界返回
if(*str==13)//换行符号
{
y+=size;
x=0;
str++;
}
else LCD_ShowChar(x,y,*str,size,mode);//有效部分写入
str++;
x+=size/2; //字符,为全字的一半
}
}else//中文
{
bHz=0;//有汉字库
if(x>(LCD_W-size))//换行
{
y+=size;
x=0;
}
if(y>(LCD_H-size))break;//越界返回
Show_Font(x,y,str,size,mode); //显示这个汉字,空心显示
str+=2;
y+=size;//下一个汉字偏移
}
}
}
//得到字符串的长度
//正点原子@HYW
//CHECK OK 091118
u16 my_strlen(u8*str)
{
u16 len=0;
while(*str!='\0')
{
str++;
len++;
}
return len;
}
u8 Font_Init(void)
{
u32 tempsys[2];//临时记录文件起始位置和文件大小
u8 fontok=0;
SPI_Flash_Read(&fontok,24,1);//读出字库标志位,看是否存在字库
if(fontok!=0XAA)return 1;
SPI_Flash_Read((u8*)tempsys,0,8);//读出8个字节
UNI2GBKADDR=tempsys[0];
//printf("tempsysgbk[0]:%d\n",tempsys[0]);
//printf("tempsysgbk[1]:%d\n",tempsys[1]);
SPI_Flash_Read((u8*)tempsys,8,8);//读出8个字节
//printf("tempsysf16[0]:%d\n",tempsys[0]);
//printf("tempsysf16[1]:%d\n",tempsys[1]);
FONT16ADDR=141998;//tempsys[0];
SPI_Flash_Read((u8*)tempsys,16,8);//读出8个字节
//printf("tempsysf12[0]:%d\n",tempsys[0]);
//printf("tempsysf12[1]:%d\n",tempsys[1]);
FONT12ADDR=tempsys[0];
return 0;
}
//将UNICODE码转换为GBK码
//unicode:UNICODE码
//返回值:GBK码
u16 UnicodeToGBK(u16 unicode)//用二分查找算法
{
u32 offset;
u8 temp[2];
u16 res;
if(unicode<=0X9FA5)offset=unicode-0X4E00;
else if(unicode>0X9FA5)//是标点符号
{
if(unicode<0XFF01||unicode>0XFF61)return 0;//没有对应编码
offset=unicode-0XFF01+0X9FA6-0X4E00;
}
SPI_Flash_Read(temp,offset*2+UNI2GBKADDR,2);//得到GBK码
res=temp[0];
res<<=8;
res+=temp[1];
return res ; //返回找到的编码
}
//将pbuf内的unicode码转为gbk码.
//pbuf:unicode码存储区,同时也是gbk码的输出区.必须小于80个字节.
//代码转换unit code-> GBK
//正点原子@HYW
//CHECK:09/10/30
void UniToGB(u8 *pbuf)
{
unsigned int code;
unsigned char i,m=0;
for(i=0;i<80;i++)//最长80个字符
{
code= pbuf[i*2+1]*256+pbuf[i*2];
if((code==0)||(code==0xffff))break;
if((code&0xff00)==0)//字母
{
if((code>=0x20)&&(code<=0x7e))
{
pbuf[m++]=(unsigned char)code;
}else pbuf[m++]='?';//无法识别的用?代替
continue;
}
if(code>=0X4E00)//是汉字
{
code=UnicodeToGBK(code);//把unicode转换为gb2312
pbuf[m++]=code>>8;
pbuf[m++]=(u8)code;
}else pbuf[m++]='?';//无法识别的用?代替
}
pbuf[m]='\0';//添加结束符号
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -