📄 text.c
字号:
#include "TXT.H"
//电子书操作函数
//还没有加入向前翻页的操作,等搞完毕业论文再弄了。。。
//正点原子@SCUT
//V1.2
//字体大小选择
u8 FSIZE=FONTSIZE16;//汉字大小,默认为16*16的
u32 FONT16CLUSTER=0;//16字体的首簇
u32 FONT12CLUSTER=0;//12字体的首簇
//Cluster 簇的序号 返回为该簇号所对应的扇区地址
//得到Cluster
unsigned long GetSysFileSector(u8 uoh,unsigned int Cluster)
{
unsigned long foffset=0;
unsigned int i;
if(uoh==16)foffset=FONT16CLUSTER;//得到unicode码的首簇
else if(uoh==12)foffset=FONT12CLUSTER;
i=Cluster;
while(i)
{
//printf("foffset:%d\n",foffset);
foffset=FAT_NextCluster(foffset);
i--;
}
//printf("final foffset:%d\n",foffset);
return fatClustToSect(foffset);
}
//code 字符指针开始
//从字库中查找出字模
//code 字符串的开始地址,ascii码
//mat 数据存放地址 FSIZE*2 bytes大小
void Get_HzMat(unsigned char *code,unsigned char *mat)
{
unsigned char qh,wh;
unsigned char i;
unsigned int sector,cluster,secoff;
unsigned long foffset;
if(*code<0xa1)if(*code++<0xa1)//非常用汉字
{
code--;
for(i=0;i<(FSIZE*2);i++)*mat++=0xff;//填充满格
return; //结束访问
}
qh=(*code++)-0xa1;
wh=(*code)-0xa1;
foffset=((unsigned long)94*qh+wh)*(FSIZE*2);//得到字库中的字节偏移量
sector=foffset/BytesPerSector; //得到总的完整的扇区数(不要写成(unsigned int )
secoff= (unsigned int) foffset%BytesPerSector;//扇区内的字节数偏移
wh=(unsigned char)sector%SectorsPerClust;
cluster=(unsigned int)sector/SectorsPerClust;//得到总的簇数
foffset=GetSysFileSector(FSIZE,cluster); //取汉字库的clusor簇数的扇区地址
if(BytesPerSector-secoff>=(FSIZE*2))//确定是否跨扇区?
{
SD_Read_Bytes(foffset+wh,mat,secoff,(FSIZE*2)); //读取(FSIZE*2)字节
}else
{
i=BytesPerSector-secoff; //读取的数据已跨扇区
SD_Read_Bytes(foffset+wh,mat,secoff,i);
if(++wh>SectorsPerClust)
{
wh=0;
foffset=GetSysFileSector(0,++cluster);//读取的数据已经跨簇
}
SD_Read_Bytes(foffset+wh,mat+i,0,(FSIZE*2)-i); //读取剩余的数据
}
}
//显示一个指定大小的汉字
//x,y :汉字的坐标
//font:汉字ASCII码
//mode:0,全填充写入.1,有效部分写入(适合在图片上叠加汉字)
void show_font(u8 x,u16 y,u8 *font,u8 mode)
{
u8 t1,t2;
u8 temp=0;
//扫描方式控制
TFT_WR_CMD(0,0x00,0x84); //上至下,左至右 型扫描
//面板大小设置 开辟1个FSIZE*FSIZE的空间
TFT_WR_CMD(0,0x02,x); //设置X坐标点
TFT_WR_CMD(1,0x03,y); //设置Y坐标点
TFT_WR_CMD(0,0x04,x+FSIZE-1);//结束列数
TFT_WR_CMD(1,0x05,y+FSIZE-1);//结束行数
TFT_WR_REG(0x0E);//开始写数据GRAM
if(!mode)//非叠加模式
{
for(t1=0;t1<FSIZE;t1++)//共FSIZE个字节,每次读两个
{
temp=font[t1];
for(t2=0;t2<8;t2++)
{
if(temp&0x01)TFT_WR_Data16(POINT_COLOR);
else TFT_WR_Data16(BACK_COLOR);
temp>>=1;
}
temp=font[t1+FSIZE];
for(t2=0;t2<(FSIZE-8);t2++)//这里对16*16和其以下的字体合适
{
if(temp&0x01)TFT_WR_Data16(POINT_COLOR);//写入画笔色
else TFT_WR_Data16(BACK_COLOR);//填充背景色
temp>>=1;
}
}
}else//叠加模式
{
for(t1=0;t1<FSIZE;t1++)//共FSIZE个字节,每次读两个
{
temp=font[t1];
for(t2=0;t2<8;t2++)
{
if(temp&0x01)TFT_DrawPoint(x+t1,y+t2);//画一个点
temp>>=1;
}
temp=font[t1+FSIZE];
for(t2=0;t2<(FSIZE-8);t2++)//这里对16*16和其以下的字体合适
{
if(temp&0x01)TFT_DrawPoint(x+t1,y+t2+8);//画一个点
temp>>=1;
}
}
}
//恢复原来的设置.
TFT_WR_CMD(0,0x00,0x04); //上至下,左至右 型扫描
TFT_WR_CMD(0,0x04,239);//结束列数
TFT_WR_CMD(1,0x05,319);//结束行数
}
//在指定位置开始显示一个字符串
//非叠加方式显示
//支持自动换行
//(x,y):起始坐标
//str :字符串
//mode :模式:
//bit 0:1,叠加模式;0,覆盖模式
//bit 1:1,自动换行;0,不自动换行;
void Show_Str(u8 x,u16 y,u8*str,u8 mode)
{
u8 bHz=0; //字符或者中文
unsigned char *mat; //保存点陈内容
mat=jpg_buffer+512;//指向jpg_buffer的后半部分.前半部分用来存放文本文件了.
while(*str!=0)//数据未结束
{
if(!bHz)
{
if(*str>0x80)bHz=1;//中文
else //字符
{
if(x>(239-FSIZE/2))//换行
{
if(mode&0x02)//判断是不是要自动换行?
{
y+=FSIZE;
x=0;
}else return;
}
if(y>(319-FSIZE))break;//越界返回
if(*str==13)//换行符号
{
y+=FSIZE;
x=0;
str++;
}
else TFT_ShowChar(x,y,*str,FSIZE,mode&0x01);//有效部分写入
str++;
x+=FSIZE/2; //字符,为全字的一半
}
}else
{
bHz=0;//有汉字库
if(x>(239-FSIZE))//换行
{
if(mode&0x02)//判断是不是要自动换行?
{
y+=FSIZE;
x=0;
}else return;
}
if(y>(319-FSIZE))break;//越界返回
Get_HzMat(str,mat);//得到点阵数据 (无字库不起动系统)
show_font(x,y,mat,mode&0x01); //显示这个汉字,空心显示
str+=2;
x+=FSIZE; //下一个汉字偏移
}
}
}
//在指定宽度的中间显示字符串
//如果字符长度超过了len,则用Show_Str显示
//len:指定要显示的宽度
//针对1616字体!!!
void Show_Str_Mid(u8 x,u16 y,u8*str,u8 mode,u8 len)
{
u16 strlenth=0;
strlenth=strlen((const char *)str);
strlenth*=8;
if(strlenth>len)Show_Str(x,y,str,mode);
else
{
strlenth=(len-strlenth)/2;
Show_Str(strlenth+x,y,str,mode);
}
}
//文本文件读取程序
//实现功能:把文件 FileName 打开.在液晶上显示出来
//打开txt/lrc文件
void Read_Book(FileInfoStruct *FileName)
{
u16 pointpos=0; //指针位置
unsigned long offlenth=0;//文件读取的大小
//unsigned long marklenth=0;//文件上一页的标记位
u16 x=0,y=0;
u8 *p=0; //指向txt文件
u8 temp[2]={0,0}; //换扇区使用
u8 bHz=0; //字符或者中文
unsigned char *mat; //保存点陈内容
u8 key;
u8 enout=0;//能否退出的标志
mat=jpg_buffer+512; //指向jpg_buffer的后半部分.前半部分用来存放文本文件了.
if((FileName->F_Type&0xF0)==0)return;//不是TXT类型的文件
F_Open(FileName);//打开文件
TFT_CLEAR(WHITE);//清屏
POINT_COLOR=BLUE;//蓝色笔头
while(1)
{
F_Read(FileName,jpg_buffer);//读取数据
p=jpg_buffer;//指向txt数据首地址
do
{
while(*p!=0)//数据未结束
{
if(!bHz)
{
if(*p>0x80)bHz=1;//中文字符
else //ASCII字符
{
if(x>(240-FSIZE/2)){y+=FSIZE;x=0;}//一行已满,换行
if(y>(320-FSIZE))break;//越界返回
if(*p==13)//换行符号
{
y+=FSIZE;
x=0;
p++;pointpos++;//跳过
}
else TFT_ShowChar(x,y,*p,FSIZE,1);
p++;pointpos++;
x+=FSIZE/2; //字符,为全字的一半
}
}else
{
bHz=0;//清除汉字标志
if(x>(240-FSIZE)){y+=FSIZE;x=0;}//换行
if(y>(320-FSIZE))break;//越界返回
//临界处理
if(pointpos==511)//保存上一扇区的最后一个字节,退出
{
temp[0]=*p; //记录最后的字节
break; //此扇区数据已经读完
}
if(temp[0])//上一次没有显示完
{
temp[1]=*p;//取第二扇区的第一个字节
Get_HzMat(temp,mat);//显示上一次的最后一个字 (无字库不起动系统)
p++;pointpos++;//偏移一个字节
temp[0]=0; //清除标记
}
else Get_HzMat(p,mat);//得到点阵数据 (无字库不起动系统)
show_font(x,y,mat,1); //显示这个汉字,空心显示
p+=2;pointpos+=2; //指针偏移
x+=FSIZE; //下一个汉字偏移
}
if(pointpos>511)break;
}
if(pointpos>=511)break;//一个扇区读取完毕,直接跳出,读下一个扇区,防止停顿
Pen_Point.Key_Sta=Key_Up;//释放显示期间的触发
enout=0; //退出使能标志不使能
while(1) //是否显示下一屏数据
{
if(Pen_Point.Key_Sta==Key_Down||NPEN)key=Touch_Key_Pro(2);//扩展按键扫描
if(key==MOVE_DOWN||key==MOVE_RIGHT)//向下翻页
{
if(offlenth+pointpos+1>=FileName->F_Size)return;//文件读取结束(长度结束)
if(y>(320-FSIZE)){x=0;y=0;}//非结尾返回,屏幕已满,清屏
TFT_CLEAR(WHITE);//清屏
key=0;//清除此次按键
break;
}
if(key==MOVE_LEFT)//滑动触摸
{
enout=1;//使能退出
printf("前面的数据:\n");
for(key=0;key<20;key++)printf("%x ",jpg_buffer[key]);
F_Read(FileName,jpg_buffer); //读取后512数据
printf("后面的数据:\n");
F_PrevRead(FileName,jpg_buffer);//读取前512数据
for(key=0;key<20;key++)printf("%x ",jpg_buffer[key]);
printf(" \n");
POINT_COLOR=RED;
TFT_Fill(0,298,239,319,0X81BF);//填充底部颜色
Show_Str(203,300,"返回",0x01); //叠加模式,非自动换行
POINT_COLOR=BLUE;
key=0;//清除此次按键
}
if(enout&&key==CLICK_POINT&&Is_In_Area(200,300,239,319))return;//退出文件阅读...
delay_ms(5);
}
}while(pointpos<511);
offlenth+=pointpos+1;//文件长度累加
pointpos=0; //清除指针计数器
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -