打印
[GUI]

让uGUI使用emWIN的XBF中文字库

[复制链接]
1087|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liklon|  楼主 | 2020-6-27 22:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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   


使用特权

评论回复
沙发
zeshoufx| | 2020-6-28 08:26 | 只看该作者
谢谢分享,,,,,,babyos是什么操作系统?

使用特权

评论回复
板凳
王紫豪| | 2020-6-28 10:21 | 只看该作者
zeshoufx 发表于 2020-6-28 08:26
谢谢分享,,,,,,babyos是什么操作系统?

娃子系统,

开个玩笑。

使用特权

评论回复
地板
杨寅辉| | 2020-6-28 16:20 | 只看该作者
我也没听过,babyos是个什么东西呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

50

帖子

1

粉丝