完美解决中文在英文Windows上显示高矮不一的问题

问题简介

就像在旧的Windows7/8/8.1上也可能出现的问题一样,如果Windows的系统语言是英文,那么在某些应用程序中中文的显示有可能很丑陋,可能出现中文字体高矮不一的情况。

 

最近我从Windows 7升级到Windows 10。激活Windows后我又重新安装了一次Windows,所以需要重新安装所有常用的软件,于是遇到了本文提到的问题。在网上也正好看到有人也遇到同样的问题,网上能找到的解决办法有些并不适用,而且解释也不清楚。于是有了写篇日志的想法,想把自己的对这个问题的认识记录下来,也希望能对别人有所帮助。

 

图像永远比文字更有说服力。下面是应用软件TotalCommander的主界面屏幕截图。TotalCommander的语言设置已经切换到中文。我们可以看到,在靠近底边的几个按钮的中文说明的显示就有字体高矮不一的问题。

TotalCommander的中文界面在英文Windows 10上显示时会有中文字体大小、高矮不一的问题。
TotalCommander的中文界面在英文Windows 10上显示时会有中文字体大小、高矮不一的问题。

 
除了TotalCommander,其它应用程序包括Windows自带的Notepad以及CMD也有类似的问题。

缺省情况下Notepad在英文Windows 10上显示中文也有中午字体大小不一的问题。
缺省情况下Notepad在英文Windows 10上显示中文也有中午字体大小不一的问题。

英文Windows 10自带的CMD在显示中文目录、文件名时也有问题。这个截图中中文目录名变成了几个方框。
英文Windows 10自带的CMD在显示中文目录、文件名时也有问题。这个截图中中文目录名变成了几个方框。

 

以上截图是在英文Windows 10上截取的。Windows的区域和语言设置如下图所示

截取以上截图时Windows 10的区域和语言设置。
截取以上截图时Windows 10的区域和语言设置。

 

在上面这个截图中,我们可以发现中文的显示其实很正常。这也就说明我们在TotalCommander、Notepad、以及CMD中所看到的中文显示问题是种特殊现象,它只发生在某些软件中,另外,虽然本文的截图是以中文为例,不过在英文Windows上显示日文、韩文也应该有类似的问题。

测试环境

本文所涉及的测试都是在英文Windows 10上使用以下软件来完成的:

 

  • TotalCommander 8.52 x64
  • CMD (system default)
  • Notepad (system default)

 

分析

上面的截图说明了两种问题:一是中文的显示使用了错误的字体,二是没有找到相应的中文字体。其中CMD中文本的显示可能有些特别,中文目录名是以方框的形式显示的。这些问题通常出现在显示中文、日文、韩文等多字节的文本时出现。解决的办法就是给应用软件指定正确的字体。

 

方法 1: 选用正确的字体

如果软件容许用户设置字体,比如TotalCommander可以容许用户选择语言以及字体等。我们可以考虑选择一个可以正常显示中文的字体,比如微软雅黑字体等。TotalCommander的字体设置和其它可选项等都可以在其配置对话框上修改。配置对话框可以通过菜单“配置–>选项”调用。关于字体的选项在对话框上的”字体“标签页。字体的缺省选项如下图所示

缺省情况下,中文界面的TotalCommander的字体设置对话框。
缺省情况下,中文界面的TotalCommander的字体设置对话框。

 
如前所述,我们可以选择包含中文字体信息的微软雅黑,启用后,我们可以看到,之前看到的问题没有了,中文显示正常了。

把界面字体设为微软雅黑后的TotalCommander字体设置对话框。
把界面字体设为微软雅黑后的TotalCommander字体设置对话框。

 
选择包含中文字体信息的字体,可以确保中文的显示正常。但是有时候我们可能不想采用这种办法。比如在有些情况下,尤其是在Notepad以及CMD之类的应用中,我们仍然希望当中、英文混排的时候,在确保中文(包括日、韩文)可以正常显示的前提下,英文能够用漂亮的等宽字体。在这种情况下,我们可以考虑使用下面将要提到的类似虚拟字体的技术来建立正确的字体映射,来达到多种语言文本都能正常显示的目的。

 

方法2:在Windows注册表创建正确的字体映射(fontlink)

Fontlink是Windows采用的一种类似虚拟字体的技术。使用Fontlink,某个字体可以和多个其它的字体建立连接关系。在这里,该字体通常被称作主字体,而其它那些与之连接的字体称作连接字体。在输出文本时,Windows如果在主字体中没有找到需要的字体信息,它会在连接字体中继续搜索。使用Fontlink技术,一个字体可以和多个其它的字体连接。这样,对于中文显示,基本思路就是我们可以给任何一个字体创建和中文字体比如微软雅黑的连接。这样可以保证英文文本可以使用用户指定的字体,同时中文也显得正常。

 
在网上搜索“中英文显示”,或者“fontlink 雅黑”等可以发现不少介绍通过创建相应的Fontlink来实现在Windows上完美中、英文混合显示的网页。关于如何在Windows注册表创建或者修改Fontlink设置,读者不妨参考搜索到的网页,这里只对具体步骤略作介绍,然后会着重讨论一下Fontlink里需要用到的一个重要的参数,也就是所谓的”缩放因子”(scaling factor)。网上能搜到的帖子或者网页关于缩放因子的介绍不多,也些甚至有误导的作用。本文稍后些会重点介绍。

 
Fontlink在Windows注册表中的具体键值保存在HKLM–>Software–>Microsoft–>Windows NT–>CurrentVersion–>Fontlink–>SystemLink。在英文版Windows 10上我们可以发现,系统已经定义了若干Fontlink。

注意:在增加或者修改Windows注册表键值之前,强烈建议把所要改动的键值导出并保存为磁盘文件以作为备份。

以TotalCommander为例,正如上面的屏幕截图所示,缺省字体是“Microsoft Sans Serif”。而该字体的缺省Fontlink设置如下所示:

Windows 10 English系统中,对应于Microsoft Sans Serif字体的缺省fontlink设置。
Windows 10 English系统中,对应于Microsoft Sans Serif字体的缺省fontlink设置。

当Windows需要在连接字体中搜索所需的字体信息的时候,它会在上面提到的这个键值所定义的字体列表中从上而下搜索,直到找到需要的字符信息。为了使得Windows能够正常显示中文信息,我们可以把对应的中文字体加到相应主字体的连接字体键值列表中。但是在正式修改前,先让我们来了解一下列表中每行文本的语法。

 

以微软雅黑字体为例,Fontlink列表中每个子项目的语法如下所示:

 

Fontlink列表中的每行的所有文字唯一的定义了该项目。所以在Fontlink的注册表键值中,以下两行分别代表两个不同的子项目:

其中“128,96”称作缩放因子(scaling factor)。根据MSDN上的相关文档,两种主要的图形显示技术GDI以及GDI+在搜索Fontlink键值时所用的语法有所不同。简单来说,GDI只会选用那些给出缩放因子的项目,相反的,GDI+会自动忽略那些带缩放因子参数的项目。这也就是说,如果想让所增加的连接字体能同时被GDI和GDI+调用,我们必须在Fontlink的键值中增加两行:一行有缩放印子给GDI,一行没有给GDI+。TotalCommander显然是使用GDI技术的,所以我们需要在Fontlink中给出缩放因子。

 
关于缩放因子是如何被使用的,或者我们应该如何设置缩放因子,我找不到任何有用的信息。现在只知道,如果缩放因子设成“128,96”的话,该字体不会被缩放。而在我的测试中发现,这样的话,中文比英文显得有点高,需要把雅黑中文字体缩小一点。最后我设置的Fontlink如下所示。关于缩放因子,下面会有更多介绍。

在英文Windows 10上,如此设置Microsoft Sans Serif字体的fontlink可以完美显示中文。
在英文Windows 10上,如此设置Microsoft Sans Serif字体的fontlink可以完美显示中文。

 
注意:为了使得新的Fontlink注册表设置生效,我们需要在Windows注销并再次登录即可。并不需要重启电脑!
 

如此设置Microsoft Sans Serif的Fontlink注册表键值后,即使字体仍然是Microsoft Sans Serif,TotalCommander的字体设置对话框上的中文显示已经正常了。如下图所示

正确设置fontlink注册表之后的TotalCommander的字体设置对话框。
正确设置fontlink注册表之后的TotalCommander的字体设置对话框。

 

接下来,我想花点时间说说缩放因子,毫无疑问,当用GDI输出文本时,缩放因子会影响显示效果。我希望能够弄清楚这两个整数是如何被使用的。可惜我找不到任何有用的信息。所有能在网上找到的信息都没有提到具体这两个缩放因子是如何被使用的。而且经过测试后我发现,有些网页上建议把缺省的数值,128和96,分别乘以一个相同的数,然后把结果作为缩放因子写入Fontlink的键值中。这让我感到十分困惑,因为以我自己现有对缩放因子的理解,对两个缺省的数值乘以一个相同的数是不会产生任何不同效果的。

 
如前所述,我找不到任何关于这两个缩放因子的详细资料,唯一能找到的相关信息就是开源软件gdipp的一个源程序文件。在这个文件里,Fontlink里定义的两个缩放因子被用来以如下方式计算另外一个缩放参数:

 

这至少说明如果给连个缺省的缩放因子乘以一个相关的系数是不会产生任何不同的效果的。根据上面这个公式,以及一些试验结果,我觉得我们至少可以对Fontlink中的缩放因子做出如下一些推断:

  1. 为了能使使用GDI技术输出文本的程序比如TotalCommander能够通过Fontlink使用多个字体,我们必须在Fontlink中给出带有缩放因子的项目
  2. 合适的缩放因子的数值可能和具体的显示设备有关。也就是说不同的显示设备对于同一个字体可能需要不一样的缩放因子
  3. 连接字体的显示大小未必和主字体相同。我们可能需要增加或者减小连接字体的大小。为了这个目的,我们可以保持其中一个缩放因子使用缺省数值,而只是相应的改变另外一个因子。具体保持哪个或者修改哪个不影响结果
  4. 把缩放因子的缺省数值乘以一个相同的数值后并不会导致文本输出后的结果

 
仍然以TotalCommander为例,让我们做几个试样,比较把缩放因子设成如下各种数值后的显示效果:

  1. 128,100, 或122, 96。显示结果应该一样。
  2. 128,128, 或64,64。显示结果应该一样。
  3. 128,72, 或171,92。显示结果应该一样。
在英文Windows 10的注册表中设置不同缩放因子后的显示效果比较。
在英文Windows 10的注册表中设置不同缩放因子后的显示效果比较。

在我的20英寸显示器上,Windows 10的分辨率设为1920×1080。如果使用缺省缩放因子,在TotalCommander中中文会显得比英文高一点,所以我需要把缩放因子设成“128,100”或者“122,96”以缩小中文。而对于系统自带的Notepad或者CMD,缺省的缩放因子就可以。

 

小结

在Windows 10上,如果系统语言是英文,那么中、日、韩文的显示可能会因为无法找到合适的字体信息而显得高矮不一。简单来说,可以有两种办法解决这个问题,那就是在相应的软件中选用正确的字体,或者在Windows注册表中创建正确的字体映射。

 
第二个方法,也就是创建正确的字体映射的方法,在多数情况下更可取,主要因为如下原因:

  1. 我们仍然希望英文能够使用我们想要的字体 (比如, Cosonlas)。
  2. 有些应用程序可能不容许我们修改字体。

 
使用Fontlink技术,一个主字体和多个其它字体连接起来,完美显示多种语言的文本。所连接字体可能和主字体的显示大小不匹配。所以有时我们需要在设置Fontlink时设定相应的缩放因子以达到更好的显示效果。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

9 条评论 “完美解决中文在英文Windows上显示高矮不一的问题”