页次: 1
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;
}
页次: 1