多语言字符串的字体问题

原创 2012年03月22日 12:20:01
一个字符能够在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 FallbackUniscribe是一组处理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中能够找到。我们可以如下图所示进行修改。
Figure 1: RegEdit's
注意上面对话框中的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,所以没法显示。
版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

不同内核浏览器的差异以及浏览器渲染简介

一、简单介绍一下什么是浏览器内核。  浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“解释引擎”,不过我们一般习惯将之称为“浏览器内核”。负责对网页语法的解释(如H...

不同内核浏览器的差异以及浏览器渲染简介

转载:http://www.cnblogs.com/imwtr/p/4481092.html 一、简单介绍一下什么是浏览器内核。 浏览器最重要或者说核心的部分是“Rendering E...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

浏览器css渲染差异

火狐浏览器中,非float的div前面有同一父级的float的div,此div若有背景图,要使用clear:both,才能显示背景图,而IE6.0中不用使用clear:both 在[text-deco...

tesseract OCR的多语言,多字体字符识别

识别多种字体、多种语言的字符,在实际应用中是很常见的问题。 经过测试,及查看tesseract3.01的源码,tesseract 3.01版本是不支持多语言、多种字体OCR识别的。 tessera...

android工程字符串多语言翻译遗漏查找工具

android的同学们一定都晓得,每个工程都有多种语言字符串。 当我们需要检测翻译是否完整的时候,一个个字符串对比效率太低,为此给出小工具源码如下: meld_string.c #inc...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)