unicode编码

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值