UTF-8
分配、设置、注册EncodingOpr结构体,由Encoding_manager.c通过链表管理。
static T_EncodingOpr g_tUtf8EncodingOpr = {
.name = "utf-8",
.iHeadLen = 3, /*文件头的长度: 一般在文件的开始用几个字节来表示它的编码方式*/
.isSupport = isUtf8Coding, /* 用这个函数来判断是否支持某个文件 */
.GetCodeFrmBuf = Utf8GetCodeFrmBuf, /* 取出一个字符的编码值 */
};
判断缓冲区中数据的编码方式是否为UTF8
static int isUtf8Coding(unsigned char *pucBufHead){
const char aStrUtf8[] = {0xEF, 0xBB, 0xBF, 0}; //判断前3个字节
if (strncmp((const char*)pucBufHead, aStrUtf8, 3) == 0)
return 1; /* UTF-8 编码 */
else
return 0;
}
从缓冲区中取出第1个字符的UTF8编码并且转换为UNICODE值,参数:buf起始地址,buf结束地址,取出编码值存在pdwCode处。返回值表示从pucBufStart开始用到了多少个字符才取得这个编码值,0表示缓冲区处理完毕,没有得到编码值。
static int Utf8GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode){
/*
* 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
* 如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
* 如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
* 如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
* 如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;
* 因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;
* 根据前二位,可判断该字节是否为一个字符编码的第一个字节;
* 根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;
* 根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。
*/
int iNum; //前导1的个数
unsigned char ucVal; //单个字节
unsigned int dwSum = 0; //多个字节组合成的unicode值,即返回值
if (pucBufStart >= pucBufEnd) /* 文件结束 */
return 0;
ucVal = pucBufStart[0];
iNum = GetPreOneBits(pucBufStart[0]); //获取前导1的个数
if ((pucBufStart + iNum) > pucBufEnd) /* 文件结束 */
return 0;
if (iNum == 0){ // ASCII码
*pdwCode = pucBufStart[0];
return 1;
}
else{
ucVal = ucVal << iNum; //先左移再右移,删掉前导的1
ucVal = ucVal >> iNum;
dwSum += ucVal;
for (int i = 1; i < iNum; i++){ //后面INum个字节只保留底6位
ucVal = pucBufStart[i] & 0x3f;
dwSum = dwSum << 6; //结果左移6位,再加上该字节
dwSum += ucVal;
}
*pdwCode = dwSum;
return iNum;
}
}
获取前导1的个数
获得"从bit7开始为1的位的个数",比如二进制数 11001111 有2位,11100001 有3位,01100001 有0位。
static int GetPreOneBits(unsigned char ucVal){
int j = 0;
for (int i = 7; i >= 0; i--){
if (!(ucVal & (1<<i)))
break;
else
j++;
}
return j;
}
根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图,
Utf8EncodingInit先给g_tUtf8EncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
最后注册g_tUtf8EncodingOpr。
int Utf8EncodingInit(void){
AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("freetype"));
AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("ascii"));
return RegisterEncodingOpr(&g_tUtf8EncodingOpr);
}
UTF-16be
static T_EncodingOpr g_tUtf16beEncodingOpr = {
.name = "utf-16be",
.iHeadLen = 2,
.isSupport = isUtf16beCoding,
.GetCodeFrmBuf = Utf16beGetCodeFrmBuf,
};
判断缓冲区中数据的编码方式是否为UTF16BE,参数:缓冲区首地址,一般是文本文件经过mmap得到的缓冲区地址。
static int isUtf16beCoding(unsigned char *pucBufHead){
const char aStrUtf16be[] = {0xFE, 0xFF, 0};
if (strncmp((const char*)pucBufHead, aStrUtf16be, 2) == 0)
return 1; /* UTF-16 big endian */
else
return 0;
}
从缓冲区中取出第1个字符的UTF16BE编码并且转换为UNICODE值
static int Utf16beGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode){
if (pucBufStart + 1 < pucBufEnd){
*pdwCode = (((unsigned int)pucBufStart[0])<<8) + pucBufStart[1];
return 2;
}
else
return 0; /* 文件结束 */
}
根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图
Utf16beEncodingInit先给g_tUtf16beEncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
最后注册g_tUtf16beEncodingOpr。
int Utf16beEncodingInit(void){
AddFontOprForEncoding(&g_tUtf16beEncodingOpr, GetFontOpr("freetype"));
AddFontOprForEncoding(&g_tUtf16beEncodingOpr, GetFontOpr("ascii"));
return RegisterEncodingOpr(&g_tUtf16beEncodingOpr);
}
UTF-16le
static T_EncodingOpr g_tUtf16leEncodingOpr = {
.name = "utf-16le",
.iHeadLen = 2,
.isSupport = isUtf16leCoding,
.GetCodeFrmBuf = Utf16leGetCodeFrmBuf,
};
判断缓冲区中数据的编码方式是否为UTF16LE,pucBufHead缓冲区首地址,一般是文本文件经过mmap得到的缓冲区地址
static int isUtf16leCoding(unsigned char *pucBufHead){
const char aStrUtf16le[] = {0xFF, 0xFE, 0};
if (strncmp((const char *)pucBufHead, aStrUtf16le, 2) == 0)
return 1; /* UTF-16 little endian */
else
return 0;
}
从缓冲区中取出第1个字符的UTF16LE编码并且转换为UNICODE值
static int Utf16leGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode){
if (pucBufStart + 1 < pucBufEnd){
*pdwCode = (((unsigned int)pucBufStart[1])<<8) + pucBufStart[0];
return 2;
}
else
return 0; /* 文件结束 */
}
根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图
Utf16leEncodingInit先给g_tUtf16leEncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
最后注册g_tUtf16leEncodingOpr。
int Utf16leEncodingInit(void){
AddFontOprForEncoding(&g_tUtf16leEncodingOpr, GetFontOpr("freetype"));
AddFontOprForEncoding(&g_tUtf16leEncodingOpr, GetFontOpr("ascii"));
return RegisterEncodingOpr(&g_tUtf16leEncodingOpr);
}