老生常谈:Wine中文那些事

Date:  2016/2/4   Sort:  Linux&开源 3032 Views / 0 Comments 

    wine中文显示问题可以说是伴随大多数Linux中文用户的麻烦事。前一阵子换了系统,安装的时候区域设置(locale)选了法语(fr_FR.UTF-8),然后又手抽把原来home下的.wine给删了,结果再装各种Windows程序时各种奇葩问题层出不穷。于是狠心认真研究了一下,终于发现wine的字体设置居然会动态改变!


    首先说一下wine对注册表的处理。wine把基本的注册表内容存储在.wine目录下,名为system.reg和user.reg。虽然可以直接修改其中内容,但是并不代表下次启动wine时这些更改一定会生效,原因在于wine在启动时会根据启动环境自动修改注册表中的一些内容(比如语言、区域、字体等),并且在关闭时将它们写会.reg文件。所以捏,有时候辛辛苦苦改完了,下次启动又恢复原样(利用regedit.exe修改也是如此)。这时候就需要借助其他方法进行修改。


    然后是wine虚拟环境下的区域设置,这个与wine运行时的环境变量有关。有关注册表键值为:
    
[HKEY_CURRENT_USER\Control Panel\International]
"Locale"="00000804"
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Language]
"InstallLanguage"="00000804"
"Default"="00000804"

    其中“00000804”是“中文(中国)”的代号。若使用命令

env LANG=zh_CN.UTF-8 wine EXE文件

    运行程序,则wine会自动修改注册表中的这些键值。该设置适用于程序中的中文变成方块“□”的情形。


    其次是wine的字体设置。有关注册表键值为:

[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes]
"Arial Baltic,186"="Arial,186"
"Arial CE,238"="Arial,238"
"Arial CYR,204"="Arial,204"
"Arial Greek,161"="Arial,161"
"Arial TUR,162"="Arial,162"
"Courier New Baltic,186"="Courier New,186"
"Courier New CE,238"="Courier New,238"
"Courier New CYR,204"="Courier New,204"
"Courier New Greek,161"="Courier New,161"
"Courier New TUR,162"="Courier New,162"
"Helv"="MS Sans Serif"
"Helvetica"="Arial"
"MS Shell Dlg"="Tahoma"
"MS Shell Dlg 2"="Tahoma"
"Times"="Times New Roman"
"Times New Roman Baltic,186"="Times New Roman,186"
"Times New Roman CE,238"="Times New Roman,238"
"Times New Roman CYR,204"="Times New Roman,204"
"Times New Roman Greek,161"="Times New Roman,161"
"Times New Roman TUR,162"="Times New Roman,162"
"Tms Rmn"="Times New Roman"

    以上为wine1.9默认配置。但是在显示中文时,这些字体都不含中文字形,因而系统会默认改用后备(fallback)字体,也就是Droid Sans Fallback Full(不同系统可能有所差异)。此字体在处理中文时可能出现一些奇怪的问题:比如在腾讯QQ中,部分以中文开头的文本会显示为方块“□”,但若字符串中含有英文/数字,则英文/数字之后的中文又不受影响。个人推测原因是字符串处理函数对ANSI与UNICODE的兼容性不佳,导致字首中文被解析为无法显示的字符编码。
    解决方法是使用文泉驿字体,只需要修改“MS Shell Dlg”一项为文泉驿字体的名称即可。然而问题在于:
        1、wine在启动时,会根据区域设置修改“MS Shell Dlg”和“Tms Rmn”两项。如果区域设置为中文,则会做以下替换:

"MS Shell Dlg"="SimSun"
"Tms Rmn"="NSimSun"

        而wine一般不会自带“SimSun”即宋体字库(“NSimSun”为新宋体);
        2、一般文泉驿字体的名称为中文(“文泉驿微米黑”,可以在“[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts]”里看到),但是wine对于这种情况并不认可,即便设置了也仍然会使用后备字体。
    因此,需要做以下调整:
        1、在Fonts中添加一项

"WenQuanYi"="Z:\\usr\\share\\fonts\\truetype\\wqy\\wqy-microhei.ttc"

        其中等号右侧为字体绝对路径,应当根据具体系统进行修改(注意使用双斜杠转义)。
        2、在FontSubstitutes中添加三项:

"MS Shell Dlg"="WenQuanYi"
"SimSun"="WenQuanYi"
"Tahoma"="WenQuanYi"

    也可以将原先的中文名称改为英文名称(比如“WenQuanYi_Micro_Hei”,最好不含空格),然后在FontSubstitutes中将上述三项改为该英文名称。当然,如果你愿意**违法**使用微软的有版权字体(比如直接复制Windows下的SimSun.ttc到.wine/driver_c/Windows/Fonts),方法也同上。


    由于水平和时间所限,本人未从源代码角度研究wine对有关区域/字体的处理方式。如有错误、疏漏,欢迎指正。

转载本站文章请注明,转载自:WTZ的小博[ http://wiblog.net/]
知识共享许可协议 本作品采用知识共享署名 4.0 国际许可协议进行许可。

更多