本帖最后由 liklon 于 2020-6-27 22:10 编辑
BabyOS的GUI功能模块是基于uGUI开源代码,但是uGUI带的字库只支持英文字符的显示。这样精简的GUI,如果能显示中文就完美了。 提到中文字库,字库从哪里来?是否有统一的标准? emWIN使用的汉字字库可以通过软件(FontCvtST.exe)生成,十分方便。那么就让uGUI也支持emWIN的汉字字库,这样大家就不用纠结字库的来源。 XBF字库简单介绍(汉字编码为unicode): XBF文件的前18个字节是文件信息,从18个字节后开始,每6个字节为一组,是字库中字符的索引信息。 字符的索引信息所在的地址是:(unicode - 0x0020) * 6 + 18 + base_addr (unicode是字符的unicode编码,base_addr是存储基地址) 索引信息包含两个信息:4个字节的字模数据地址,2个字节的字模数据长度 字模数据包含了三个信息:字符的宽度(2个字节),每行数据对应的字节数(2个字节),字模(字模数据长度 - 4个字节) 我们将字模获取到后便可以再屏上显示了。 值得注意的是,MDK汉字编码为UTF-8,而字库是unicode编码,所以在使用汉字字库时,将BabyOS算法目录中utf转unicode的c文件添加至工程。 然后修改ugui.c的如下几个函数: UG_PutString
UG_ConsolePutString
_UG_PutText
增加unicode显示的函数:
void UG_PutCharUnicode(uint32_t v, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc )
{
uint8_t i = 0, j = 0, k = 0;
uint8_t tmp_data = 0;
XBF_Info_t info;
XBF_Data_t _data;
uint32_t info_addr = 0;
info_addr = _XBF_FILE_ADDR + ((v - ' ') * 6) + 18;
UG_ReadXBF(info_addr, (uint8_t *)&info, sizeof(XBF_Info_t)); //读取索引信息
UG_ReadXBF(info.addr, (uint8_t *)&_data, sizeof(XBF_Data_t)); //读取字模信息
if((gui->font.char_height * _data.x_byte + sizeof(XBF_Data_t)) == info.len)
{
for(k = 0;k < (info.len - sizeof(XBF_Data_t));)
{
for(i = 0;i < _data.x_byte;i++)
{
UG_ReadXBF(info.addr + sizeof(XBF_Data_t) + k + i, &tmp_data, 1);
for(j = 0;j < 8;j++)
{
if((i * 8 + j) >= _data.x_len)
{
break;
}
if((tmp_data << j) & 0x80)
{
gui->pset(x + i * 8 + j,y + k / _data.x_byte, fc);
}
else
{
gui->pset(x + i * 8 + j,y + k / _data.x_byte, bc);
}
}
}
k += _data.x_byte;
}
}
}
下面演示如何基于BabyOS使用uGUI。
1.使能功能模块UGUI配置中配置LCD的物理尺寸。字体方面:选择FONT_XBF。编译器的中文编码方式:MDK使用UTF-8,所以配置文件里面选择了UTF-8。 XBF字库文件有1M多,默认是存储再SPIFLASH中,配置文件中指定XBF存储的基地址,这里配置的是0. 将字库文件放在SD卡中,再从SD卡拷贝至SPIFLASH,BabyOS一键移植FatFS:1.使能FS功能模块,选择FATFS 2.勾选SD卡,填写SD卡容量 2.添加第三方代码FatFS3.添加SPIFLASH和SD卡驱动4.将SD卡中的字库文件拷贝至SPIFLASH4.1字库生成方式选择字体和字号 保存为XBF文件 if(0 == bFS_Init()) //初始化FatFS
{
/* copy font12.xbf */
_CopyFontFile(&fil, "1:font12.xbf"); //执行拷贝
}
static int _CopyFontFile(FIL *pf, char *fname) //每次拷贝4K字节
{
int retval, ret = 0;
int fd = -1;
uint32_t font_size;
int i = 0;
uint32_t r = 0;
bCMD_Erase_t cmd;
fd = bOpen(SPIFLASH, BCORE_FLAG_RW);
if(fd < 0)
{
b_log_e("open err\r\n");
return -1;
}
retval = f_open(pf, fname, FA_READ);
if(retval == FR_OK)
{
font_size = f_size(pf);
b_log("filesize:%d\r\n", font_size);
for(i = 0;i < font_size;)
{
f_read(pf, TmpBuf, 4096, &r);
if(r)
{
b_log("r:%d\r\n", r);
cmd.addr = i;
cmd.num = 1;
bCtl(fd, bCMD_ERASE_SECTOR, &cmd);
bLseek(fd, i);
bWrite(fd, TmpBuf, r);
}
if(r < 4096)
{
b_log("end...\r\n");
break;
}
i += 4096;
}
f_close(pf);
}
else
{
ret = -1;
b_log("open err:%d\r\n", retval);
}
bClose(fd);
return ret;
}
5.显示字符串 bGUI_Init(TFT, -1); //初始化GUI模块
UG_FillScreen(C_BLACK); //填充背景色
UG_PutString(0, 0, "你好hello"); //显示6.main函数......
bInit();
#if COPY_FONTFILE
if(0 == bFS_Init())
{
/* copy font12.xbf */
_CopyFontFile(&fil, "1:font12.xbf");
}
#else
char test[4] = "你 ";
b_log("%x %x %x\r\n", test[0], test[1], test[2]);
bGUI_Init(TFT, -1);
UG_FillScreen(C_BLACK);
UG_PutString(0, 0, "你好hello");
#endif
while (1)
{
bExec();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
......
BabyOS master分支 https://gitee.com/notrynohigh/BabyOS
|