DebugDump Forum

本站无需注册,无需积分,无需回复可下载所有资料,如果真的喜欢小站,请您注册之后请至少回复一个帖子激活Id,谢谢支持! 站长QQ: 516333132 (挖坑网/填坑网) admin@debugdump.com

您尚未登录。

#1 2018-12-01 19:15:43

quop_mike
会员
注册时间: 2018-11-29
累计积分: 2

研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

LVGL版本是5.2,芯片是ESP32【内核是小端】,FATFS使能长文件名,然后同时使能了CP936(支持中文文件名)
问题来了,做了一个MP3播放器,然后在屏幕上显示正在播放的文件名,显示的文件名除了英文全部乱码
研究了一下,由于使能了CP936,所以FATFS读回来的文件名字串应该就是GBK编码的,但是LVGL不支持GBK编码,所以查不到对应的字库来显示,所以全乱码
刚开始以为LVGL直接支持unicode,把GBK强制转换成unicode以后还是乱码,一脸懵逼
搞了好久才弄清楚,LVGL支持的是UTF-8编码格式,简单来说就是英文是1个byte,中文是3byte,那就好办了
思路如下:
对于英文字符,ASCII和GBK还有UTF-8都是一毛一样的,那么
读GBK的字串中的一个byte
       若值<0x80,那么说明目前读取的就是英文字符,直接copy到输出即可

       若值>=0x80,那么说明读取到的已经不是英文字符了,那么先转换为unicode,然后再把unicode转换为UTF-8编码即可

代码如下,均为小端,大端请自行处理

/*------------------
*gbk 指向gbk字串的指针【输入】
*utf8 指向utf8字串的指针【输出】
--------------------*/
void StringGBK2UTF8(uint8_t *gbk, uint8_t *utf8)
{
	int i = 0;
	while (gbk[i] != 0)
	{
		if (gbk[i] < 0x80)
		{
			*utf8 = gbk[i];
			utf8++;
			i++;
		}
		else
		{
			WCHAR unicode = ff_oem2uni((WCHAR)(gbk[i] << 8 | gbk[i+1]), 936);
			int byte = enc_unicode_to_utf8_one(unicode, utf8);
			utf8 += byte;
			i = i + 2;
		}
	}
}

其中ff_oem2uni是FATFS自带的把相应的CODEPAGE编码字符转换成UNICODE字符的函数,不同版本的函数可能略有区别
enc_unicode_to_utf8_one函数是把一个unicode转换为utf-8编码

int enc_unicode_to_utf8_one(unsigned long unic,unsigned char *pOutput)
{  
	assert(pOutput != NULL);  
  
	if (unic <= 0x0000007F)  
	{  
		// * U-00000000 - U-0000007F:  0xxxxxxx  
		*pOutput     = (unic & 0x7F);  
		return 1;  
	}  
	else if (unic >= 0x00000080 && unic <= 0x000007FF)  
	{  
		// * U-00000080 - U-000007FF:  110xxxxx 10xxxxxx  
		*(pOutput + 1) = (unic & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 6) & 0x1F) | 0xC0;  
		return 2;  
	}  
	else if (unic >= 0x00000800 && unic <= 0x0000FFFF)  
	{  
		// * U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 2) = (unic & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >>  6) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 12) & 0x0F) | 0xE0;  
		return 3;  
	}  
	else if (unic >= 0x00010000 && unic <= 0x001FFFFF)  
	{  
		// * U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 3) = (unic & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 12) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 18) & 0x07) | 0xF0;  
		return 4;  
	}  
	else if (unic >= 0x00200000 && unic <= 0x03FFFFFF)  
	{  
		// * U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 4) = (unic & 0x3F) | 0x80;  
		*(pOutput + 3) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >> 12) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 18) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 24) & 0x03) | 0xF8;  
		return 5;  
	}  
	else if (unic >= 0x04000000 && unic <= 0x7FFFFFFF)  
	{  
		// * U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 5) = (unic & 0x3F) | 0x80;  
		*(pOutput + 4) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 3) = ((unic >> 12) & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >> 18) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 24) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 30) & 0x01) | 0xFC;  
		return 6;  
	}  
  
	return 0;  
}  

离线

#2 2018-12-01 19:42:19

arphone
会员
注册时间: 2017-11-03
累计积分: 60

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!

离线

#3 2018-12-01 20:00:59

晕哥
Administrator
注册时间: 1970-01-01
累计积分: 5,759

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!

离线

#4 2018-12-01 20:28:09

晕哥
Administrator
注册时间: 1970-01-01
累计积分: 5,759

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑



帮楼主补上视频

离线

#5 2018-12-01 20:29:51

晕哥
Administrator
注册时间: 1970-01-01
累计积分: 5,759

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

离线

#6 2018-12-03 19:08:39

dgtg
会员
注册时间: 2017-11-08
累计积分: 65

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

蛮酷的界面呀...

离线

#7 2019-01-18 20:33:46

jw__liu
会员
注册时间: 2019-01-18
累计积分: 37

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

正要用啊感谢。

离线

#8 2019-01-23 17:56:39

rpi
会员
注册时间: 2019-01-23
累计积分: 2

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!

离线

#9 2019-03-10 11:26:49

tink
会员
注册时间: 2019-03-09
累计积分: 32

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

mark

离线

#10 2019-03-10 13:12:23

Ken
会员
注册时间: 2019-01-06
累计积分: 25

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

mark. 感谢分享!

离线

页脚