多语言字符串的字体问题
来源:互联网 发布:java utf8转换为gbk 编辑:程序博客网 时间:2024/06/06 00:22
一个字符能够在Windows界面上显示出来,首先是当前编码要跟该字符的编码一致,同时还需要当前的字体支持。如果编码不匹配,显示出来往往就是乱码,如果字体不匹配,显示出来则往往是一个个方框。这里我们要分析一下字体的问题,对于一段字符串,如果里面包含了多种语言,尤其东亚语言,则用户选定的字体,往往不能支持所有的语言,比如中文并不支持Arial和Tahoma等字体。如果该字符没有对应的字体支持,就不会正常显示。那么究竟如何选择字体来显示含有多语言的字符串呢?
首先来介绍一下原理。OpenType font是由Microsoft和Adobe联合开发的基于Unicode的字体系统,它扩展了由Apple开发的TrueType font,能够对应字符(character)和它的图形(glyph)。在Windows中,核心字体包括Times New Roman, Courier New, Arial, Microsoft Sans Serif和Tahoma,这些字体能够显示包括了拉丁,希伯来、阿拉伯、希腊等语言,但没有包括东亚语言。当选择上面这些字体时,对于东亚语言,实际上是用了另外的字体进行了显示。也就是说,对于一段含有多语言的字符串,虽然选定了一种字体,但实际上对于那些该字体支持不了的字符,有另外的字体与之对应。
这种字体对应的技术,在Windows中主要包括Font Fallback和Font Linking两种技术。一般而言,Font Fallback是在Application中完成,而Font Linking是在操作系统的GDI中完成。可以想见,如果两种技术都用到的话,那么一个字符的显示,首先用Font Fallback处理,然后还会用Font Linking处理,也就说后者可能会覆盖前者的结果。
Font Fallback - 为每种语言提供默认字体
-----------------------------------------
微软提供了Uniscribe模块,以库USP10.DLL的形式,能够使Application实现Windows的Font Fallback。Uniscribe是一组处理unicode字符的API函数服务集,这些函数可以被分成两大类:一种是底层的API函数,另一种就是叫做ScriptString的Wrapper library,封装了底层的API。ScriptString一般用于单种选定的字体(包含实际显示不同语言字符的不同字体)或者单种颜色的情况,典型的例子就是Windows的Notepad程序。但一些高级的应用,就不能简单的使用ScriptString,而是要用到Uniscribe的底层API函数。
注意,对于Font Fallback,Uniscribe的底层API并没有处理它,所以基于Uniscribe的应用可能需要自己内建fallback font列表来解决这个问题;但是ScriptString,即Uniscribe的封装库,却提供了这个功能,但是需要操作系统激活它才行(见后面说明)。请参考http://www.catch22.net/tuts/more-uniscribe-mysteries
我们下面所说的,都是指Uniscribe自动支持Font Fallback的情况,比如Notepad显示复杂字符串的过程。(一般Windows提供的API,比如DrawText,都会调用ExtTextOut,应该使用Uniscribe的ScriptString来实现Font Fallback功能?,所以如果你要实现自己的复杂的编辑器,比如word那样的软件,你可能不能简单的使用ExtTextOut,而是要用到Uniscribe的底层API?)
通过Uniscribe提供Font fallback的过程,可参见下面的图。当Application通过Win32 API函数ExtTextOut()输出字符串时,如果该函数发现作为参数输入的字符串是复杂字符串,并会调用Uniscribe提供的API函数进行处理,然后传给GDI进行显示;当然字符串不是复杂字符串,则可以直接传送给GDI。
比如Notepad上要显示一段文本,包括了英语、希伯来语和Telugu语,用户选用Tahoma来显示它。Tahoma是Opentype字体,支持英语和希伯来语的显示,但不支持Telugu语,所以当解析到Telugu字符时,Uniscribe发现Tahoma无法显示字符,便使用Telugu的默认字体Gautami来显示它。这些默认的字体,用户无法增加或修改。整个过程对用户来讲是透明的,不需要用户去关心其中。
需要注意的是,网上有资料说,ExtTextOut()函数本身并不会自动支持复杂字符串的处理,必须在Windows XP中选中下图所示的两个配置后,Uniscribe的Font Fallback技术才能被激活使用。参见http://www.catch22.net/tuts/introduction-uniscribe
在Windows 7之后,提供了DirectWrite,实现Uniscribe类似的功能。
有关Font Fallback在Windows中的支持,详见http://msdn.microsoft.com/en-us/goglobal/bb688099
Font Linking - 为一种字体提供多种链接字体
--------------------------------------------
Font Linking技术被GDI实现。不像Font Fallback固定的使用默认字体,Font Linking技术能够使用一种甚至多种字体(linked font)链接到另外一种字体(base font)。你如果使用base font去显示某一段多语言的文本,对于不支持base font的文字,系统能够自动使用linked font代替。
比如,我们将hangul字体和Japanese字体链接到Tahoma字体上,也就说这里base font是Tahoma,linked font有两个,是hangul和Janpanese字体。这样,对于包含日文和韩文的文本,用户可以设定Tahoma字体来统一显示,对于里面的韩文,系统自动会用hangul字体显示。
如果系统使能了Font Linking,用户可以在Windows注册表上修改Font Linking信息。它们在HKEY_LOCAL_MACHINE–\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink中能够找到。我们可以如下图所示进行修改。
注意上面对话框中的Value data表示linked fonts信息,每一行表示一个Linked font,前面是font的文件名,用逗号分隔,后面则是字体名。
修改后,必须重启系统才能生效。
Font Substitution
--------------------------------------------------------
提供了对将对一种字体的请求转化到另一种字体的机制。参见注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes
详细的信息,参考网址:http://msdn.microsoft.com/en-us/goglobal/bb688134
实际问题的分析
---------------------------------------------------------
问题现象:一个英文韩文混杂的文件,在Windows XP的系统上用Notepad显示,如字体用Tahoma,则显示正常,如果字体用Arial或其他几种,则韩文显示成方框,文件编码正常,主要是字体问题,如何解释?
原因分析:
根据前面介绍,该文件内部的字符串要正常显示,可能会先后经过Font Fallback和Font Linking这两种技术的处理。对于Font Fallback,因为在Windows XP系统的语言设置中,没有完全激活自动的Font Fallback功能,所以不再考虑。对于Font Linking技术,看到Windows注册表中,对于Tahoma字体,设置了其到能够显示韩文的字体的Linking,所以当我们选择字体Tahoma时,能够正常显示,但选择Arial时,注册表中并没有对其做Font Linking,所以没法显示。
- 多语言字符串的字体问题
- 关于c语言中的字符串的问题
- c语言关于字符串常量的问题
- C语言的字符串倒置问题
- C语言中字符串的输入问题
- C语言特殊要求的字符串问题
- 【C语言·字符串】关于字符串的存储问题
- 【C语言·字符串】关于字符串的输入问题
- 【C语言·字符串】关于字符串的输出问题
- c语言字符串问题
- netbean的语言字体设置
- Qt中多语言及字体的分析
- Qt中多语言及字体的分析 .
- C语言的字符数组和字符串的问题
- C语言字符串的问题和蛇形矩阵的问题解答
- 多语言的问题
- C语言:关于计算字符串中空格数的问题
- 关于C语言字符串拷贝的一个问题
- 浅析SQL Server 2008中的代码安全之一:存储过程加密
- JavaScript的那些书
- http://msdn.microsoft.com/zh-cn/gg502456
- Excel与datable的转换 用于Excel的导入
- 主动FTP与被动FTP...
- 多语言字符串的字体问题
- python任务调度轻量级框架
- php上传图片代码
- 如何在C语言中使用constructor和destructor,gcc环境
- .NET批量上传控件——HtmlInputFiles
- (转)简单实现UCWeb的新特性展示
- 关于viewDidLoad里调用presentModalViewController的问题
- Android framework系统默认设置修改
- 上传了资料--分布式Java