UCS-2 UCS-4 中文字符编码 TTF字库之间的关系.doc
《UCS-2 UCS-4 中文字符编码 TTF字库之间的关系.doc》由会员分享,可在线阅读,更多相关《UCS-2 UCS-4 中文字符编码 TTF字库之间的关系.doc(16页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、字体和字符编码的关系Sunny.Man一、事件的起因“回车键“”这个标记怎么样才能显示在文本框内?”一个哥们在群里问。我把这个符号复制到WORD里,然后按“ALT+X”看到了它的UNICODE码,然后告诉那哥们这个符号的Unicode码是0x21B5。顺手我把它复制到了我正打开的UE文件里时,它居然变成了一个”?”,马上查看它的十六进制码也变成了0x3F。为什么会有这个变化?我又把它复制到了WINDOWS的记事本里,记事本里却显示的好好的”。我想更清楚的看一下是不是这个符号,我点击字体,然后选择了“新宋体”,并设置了初号。结果更是另我大跌眼镜,居然变成了一个“”。为什么呢。心中似乎有答案,但又
2、不能完全说明白。还好我有度娘,按着我心里的思路咱一路百度,最终我得到了我认为合理的解释,由于具体的是不是这么回事,我没验证过。所以大家仅供参考。再弄懂这些乱七八遭的事前,先复习了一下相关概念。二、字符的编码1.什么是字符集字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等。“*“是一个字符“”也是一个字符。一组抽象字符的集合就是字符集(Charset)。字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集。一组有共同特征的字符也可以组成字符集,比如繁体汉字字符集、日文汉字字符集。字符集的子集也是字符集。2.
3、字符编码计算机只能处理0和1,如果计算机要处理各种字符就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。 制定编码首先要确定字符集,并将字符集内的字符排序,然后和二进制数字对应起来。根据字符集内字符的多少,会确定用几个字节来编码。 每种编码都限定了一个明确的字符集合,叫做被编码过的字符集(Coded Character Set),这是字符集的另外一个含义。通常所说的字符集大多是这个含义。说得通俗些就是0和1只能表示两个字符,为了表示人类使用的字符,就把它们编成一个个的二进制串,每个串表示一个字符。如果你是制度的创立者你完全可以规定,0000001就是”a”,而不用
4、使用1100001(97)这个串.可惜你不是计算的的编码发明者,所以得随大家一起用人家编好的。当然了这其中的编码都是科学合理的,也不是随心所欲的。3.常见字符集 3.1ASCII: American Standard Code for Information Interchange,美国信息交换标准码。 目前计算机中用得最广泛的字符集及其编码,由美国国家标准局(ANSI)制定。 它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。 ASCII字符集由控制字符和图形字符组成。 在计算机的存储单元中,一个ASCII码值占一个字节(8个二进制位),其最高位(b7)用作奇偶校验位。所谓
5、奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。 奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1。 偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。 下表就是ASCII编码表:ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符 0 NUT 32 (space) 64 96 、1 SOH 33 !65 A 97 a 2 STX 34 ”66 B 98 b 3 ETX 35 # 67 C 99 c 4 EOT 36 $ 68 D 100 d 5 ENQ 37 %
6、 69 E 101 e 6 ACK 38 & 70 F 102 f 7 BEL 39 , 71 G 103 g 8 BS 40 ( 72 H 104 h 9 HT 41 ) 73 I 105 i 10 LF 42 * 74 J 106 j 11 VT 43 + 75 K 107 k 12 FF 44 , 76 L 108 l 13 CR 45 - 77 M 109 m 14 SO 46 . 78 N 110 n 15 SI 47 / 79 O 111 o 16 DLE 48 0 80 P 112 p 17 DCI 49 1 81 Q 113 q 18 DC2 50 2 82 R 114 r 1
7、9 DC3 51 3 83 X 115 s 20 DC4 52 4 84 T 116 t 21 NAK 53 5 85 U 117 u 22 SYN 54 6 86 V 118 v 23 TB 55 7 87 W 119 w 24 CAN 56 8 88 X 120 x 25 EM 57 9 89 Y 121 y 26 SUB 58 : 90 Z 122 z 27 ESC 59 ; 91 123 28 FS 60 94 126 31 US 63 ? 95 127 DEL ASCII收录了空格及94个“可印刷字符”,足以给英语使用。 但是,其他使用拉丁字母的语言(主要是欧洲国家的语言),都有一定
8、数量的变音字母,故可以使用ASCII及控制字符以外的区域来储存及表示。 除了使用拉丁字母的语言外,使用西里尔字母的东欧语言、希腊语、泰语、现代阿拉伯语、希伯来语等,都可以使用这个形式来储存及表示。 很明显这种编码表示的字符范围很窄,无法表示中文字符。3.2汉字编码3.2.1区位码国标码1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准: GB2312-80信息交换用汉字编码字符集基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。这个标准用两个数来编码汉字和中文符号。第一个数称为“区”,第二个数称为“位”。所以也称为区位码。
9、1-9区是中文符号,16-55区是一级汉字,56-87区是二级汉字。 国标码是一个四位十六进制数,区位码是一个四位的十进制数,每个国标码或区位码都对应着一个唯一的汉字或符号,但因为十六进制数我们很少用到,所以大家常用的是区位码,它的前两位叫做区码,后两位叫做位码。用一句简单的话说就是区位码人使用起来比较方便,而国标码是为了给计算机使用。当然一会讲到两者的关系。总之这个GB2312-80就是一张大表,这张94*94的大表规定了哪个汉字用哪个编码(数字)来代替。例如”土”的区位码4533。它表示“土“字在45区的33位.其在表中的位置可以如下图所示:那它又是如何转为国标码的呢。按规定把区位码的区和
10、位分别+160就是相应的国标码, 45+160=205=0xCD,33+160=193=0xC1那么0xCDC1就是”土“的国标码。为什么要加上0xA0呢,主要是为了和ASCII的编码区分开来,以便让计算机知道是一个字节的英文还是两个字节的中文,现在计算机知道了所有的中文第一个字节都大于0xA0,由于经常说起人们还给他起了一个名字(Leading Byte)。这种表示的字符集又叫MBCS因为WINDOWS只使用了两个字节所以又叫DBCS。3.2.2大端和小端模式现在我们知道了在计算机里是用两个字节来表示一个中文字符的。现在有一个问题。当我们打开一个文本文件,并读取到了“D7 D6 B7 FB
11、BA CD B1 E0 C2 EB”这十个字节。现在我们知道D7 D6根据国标码规则应该是一个汉字,但这究竟应该是0xD7D6呢,还是0xD6D7呢。这就是有名的大端模式和小端模式。big endian和little endian(大端模式和小端模式) “endian”这个词出自格列佛游记。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,一个皇帝送了命,另一个丢了王位。我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。所谓大端模式就是高位字节排放
12、在内存的低地址端,低位字节排放在内存的高地址端。小端模式就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。下面是把一个LONG型的数据0x12345678存放到内存里里两种方式的排列方法:在我的X86结构的计算机里,用的是小端模式。那么其中”D7D6”就是国标码的”字”这个字符。3.2.3代码页现在我们知道了在中国大陆我们使用我们的GBK,那在台湾,在日本,在韩国使用什么呢?没错如你所猜测的,每个地区都有每个地区的标准。我们的叫GBK而台湾的就叫Big5。由于自己制定的标准那么就出现了一个编码按不同的编码出现两个符号的情况。0xD1C6这个国标码在GB2312的编码下是一个”哑”
13、字,而在Big5的编码下却是一个“字。那么WINDOWS到底应该把这个编码译为哪个字符呢。又是如何译的呢?这就不得不说代码页。代码页(Code Page)是个古老的专业术语,据说是IBM公司首先使用的。代码页和字符集的含义基本相同,代码页规定了适用于特定地区的字符集合,和这些字符的编码。可以将代码页理解为字符和字节数据的映射表。Windows为自己支持的代码页都编了一个号码。例如代码页936就是简体中文 GBK,代码页950就是繁体中文 Big5。代码页的概念比较简单,就是一个字符编码方案。这个方案由当地的编码机构进行制定。但要说清楚Windows的ANSI代码页,就要从Windows的区域(
14、Locale)说起了。微软为了适应世界上不同地区用户的文化背景和生活习惯,在Windows中设计了区域(Locale)设置的功能。Local是指特定于某个国家或地区的一组设定,包括代码页,数字、货币、时间和日期的格式等。在Windows内部,其实有两个Locale设置:系统Locale和用户Locale。系统Locale决定代码页,用户Locale决定数字、货币、时间和日期的格式。我们可以在控制面板的“区域和语言选项”中设置系统Locale和用户Locale:每个Locale都有一个对应的代码页。系统Locale对应的代码页被作为Windows的默认代码页。在没有文本编码信息时,Windows
15、按照默认代码页的编码方案解释文本数据。这个默认代码页通常被称作ANSI代码页(ACP)。ANSI代码页还有一层意思,就是微软自己定义的代码页。在历史上,IBM的个人计算机和微软公司的操作系统曾经是PC的标准配置。微软公司将IBM公司定义的代码页称作OEM代码页,在IBM公司的代码页基础上作了些增补后,作为自己的代码页,并冠以ANSI的字样。我们在“区域和语言选项”高级页面的代码页转换表中看到的包含ANSI字样的代码页都是微软自己定义的代码页。例如:874 (ANSI/OEM - 泰文) 932 (ANSI/OEM - 日文 Shift-JIS) 936 (ANSI/OEM - 简体中文 GBK
16、) 949 (ANSI/OEM - 韩文) 950 (ANSI/OEM - 繁体中文 Big5) 1250 (ANSI - 中欧) 1251 (ANSI - 西里尔文) 1252 (ANSI - 拉丁文 I) 1253 (ANSI - 希腊文) 1254 (ANSI - 土耳其文) 1255 (ANSI - 希伯来文) 1256 (ANSI - 阿拉伯文) 1257 (ANSI - 波罗的海文) 1258 (ANSI/OEM - 越南)我们不能直接设置ANSI代码页,只能通过选择系统Locale,间接改变当前的ANSI代码页。微软定义的Locale只使用自己定义的代码页。所以,我们虽然可以通过
17、“区域和语言选项”中的代码页转换表安装很多代码页,但只能将微软的代码页作为系统默认代码页。在Windows 2000以后,Windows统一采用UTF-16作为内部字符编码。现在,安装一个代码页就是安装一张代码页转换表。通过代码页转换表,Windows既可以将代码页的编码转换到UTF-16,也可以将UTF-16转换到代码页的编码。代码页转换表的具体实现可以是一个以nls为后缀的数据文件,也可以是一个提供转换函数的动态链接库。有的代码页是不需要安装的。例如:Windows将UTF-7和UTF-8分别作为代码页65000和代码页65001。UTF-7、UTF-8和UTF-16都是基于Unicode
18、的编码方案。它们之间可以通过简单的算法直接转换,不需要安装代码页转换表。在安装过一个代码页后,Windows就知道怎样将该代码页的文本转换到Unicode文本,也知道怎样将Unicode文本转换成该代码页的文本。3.2.4如何把文本文件打开的当我们打开了文本文件Test.txt,并知道它有十个字节的数据 “D7 D6 B7 FB BA CD B1 E0 C2 EB”。Windows首先根据locale来查看当前的代码页是多少,当然我的计算机是936于是它按GB2312来查找相应的字符。它得到DBCS字符串”字节和字符”。没错,代码页就是这么有用而且巧妙,微软不管你什么规则,不管你什么字符,总之
19、我按你给我的标准来。至于你是什么微软不关心。由于各代码页支持的字符范围不同,我们一般不会直接在代码页间转换文本。需要我们转换文本时,我们先把A(要转换的文本)转换为unicode码,然后再把这个unicode码转换为B(转换后的文本)。3.2.5如何把简体中文转换为Big5编码的繁体中文将GBK中文简体编码的文本转换到Big5繁体编码的正确步骤应该是:1.将GBK中文简体编码映射到GBK的中文繁体的; 2. GBK的中文繁体转换为Unicode中文繁体文本; 3. Unicode中文繁体的文本转换为Big5繁体的文本。1. 将GBK中文简体编码映射到GBK的中文繁体的LCID lcid = M
20、AKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);int nLength = LCMapStringA(lcid,LCMAP_TRADITIONAL_CHINESE,szGBKString,-1,NULL,0);/szGBKString =char * srcSimplifiedChinesechar* pBuffer=new charnLength+1;LCMapStringA(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,pBuffer,nL
21、ength);pBuffernLength=0;2. GBK的中文繁体转换为Unicode中文繁体文本;UINT nCodePage = 936; /GB2312int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0);/ szGBString GBK的中文字符串wchar_t* pBuffer = new wchar_tnLength+1;MultiByteToWideChar(nCodePage,0,szGBString,-1,pBuffer,nLength);pBuffernLength=0;/pBuffer为UN
22、ICODE码3. Unicode中文繁体的文本转换为Big5繁体的文本。UINT nCodePage = 950; /BIG5int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);char* pBuffer=new charnLength+1;WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);pBuffernLength=0;为什么要这样转换呢?如果你有一张区位码表你就会发现,一个简
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UCS-2 UCS-4 中文字符编码 TTF字库之间的关系 UCS 中文 字符 编码 TTF 字库 之间 关系
限制150内