这里主要写一下思路:
首先明确中文字库的取模顺序,我采用的是:阴码+逐行+顺向 (高位在前)
16*16的中文字库每一行是由2Bytes组成,而32*32的中文字库每一行是由4Bytes组成,所以只需要将每一个点扩大成两个点,比如第一个数为0x80,二进制表示为1000 0000,扩大后变为11000000 00000000,即只需要在每一个位后面插入跟前面一样的为即可。
那么纵向也需要扩大两倍,这个比较简单,只需要复制前面那一行即可。
如下是源代码:
/*
* @Description: 显示单个32x32中文字体
* @param: x,y :起点坐标
// fc:前置画笔颜色
// bc:背景颜色
// s:字符串地址
// mode:模式 0,填充模式;1,叠加模式
* @return:none
*/
void lcdDrawFont32(u16 x, u16 y, u16 fc, u16 bc, u8 *s,u8 mode)
{
u8 i,j;
u16 k;
u16 HZnum;
u16 x0=x;
u8 asc[32];
u16 asc16[16];
u8 zoneBitCode[2] = {0};
u16 HZKAddr = 0;
u32 fontAddr = 0;
zoneBitCode[0] = *(s) - 0xa0;
zoneBitCode[1] = *(s+1) - 0xa0;
HZKAddr = 94*(zoneBitCode[0] - 1) + zoneBitCode[1] - 1;
fontAddr = HZKAddr*32 + HZK16_OFFSET;
spiflashRead(asc,fontAddr,32);
for (i = 0; i<16; i++)
{
asc16 = (u16)(asc[i*2]<<8) | asc[i*2+1];
}
lcdSetWindow(x,y,x+32-1,y+32-1);
for(i=0;i<16;i++)
{
for (k = 0; k < 2; k++)
{
for(j=0;j<16;j++)
{
if(!mode) //非叠加方式
{
if(asc16&(0x8000>>j)){
lcdDrawPoint16Bit(fc);
lcdDrawPoint16Bit(fc);
}
else {
lcdDrawPoint16Bit(bc);
lcdDrawPoint16Bit(bc);
}
}
else
{
POINT_COLOR=fc;
if(asc16&(0x8000>>j))
{
lcdDrawPoint(x,y);//画一个点
x++;
lcdDrawPoint(x,y);//画一个点
x++;
}
else
{
x = x+2;
}
if((x-x0)==32)
{
x=x0;
y++;
break;
}
}
}
}
}
lcdSetWindow(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏
} |