背景
在最开始,有必要简单地介绍一下字体渲染的相关背景。在 Windows 上,字体的显示效果与以下几个因素有关。
1、屏幕显示分辨率。这个无需多说,如果屏幕显示分辨率不合适,整个显示画面都会被拉伸。
2、“文本、应用和其他项目的大小”,也就是 DPI。在屏幕分辨率较低的时代,一般的设定都是 100%,很少有人去关注这个问题。但是随着现在的高分辨率屏幕越来越多,如果再以 100% 去显示,那么字体会变得很小而不易阅读。屏幕分辨率越高,这一设定就应该越大(推荐设置如此,但也有人偏爱 100% 的小字体)。
3、渲染引擎。对于传统 Win32 应用来说,其字体显示由 Win32 API 提供,利用的是图形设备接口 GDI(Graphical Device Interface)。这一个接口的历史悠久,很多传统应用均采用了这一接口渲染字体。当然后来微软为了改进液晶屏上的显示效果,推出了 ClearType 来改进 GDI 在 LCD 屏幕上对字体的渲染。后来微软作为 GDI 以及 GDI+ 的替代品推出了 DirectWrite。 DirectWrite 更加适合高分辨率屏幕使用,对于不同的 DPI 设置都有良好的支持。但是这需要应用开发者加入对 DirectWrite 的支持,即自行调用 DirectWrite 进行字体渲染。
4、字体。字体包含了每个字形状的矢量信息。对于 Windows 上常见的中易宋体来讲,可以很明显地感觉到,在使用小四号字的时候,字体显示十分锐利,然而其屏幕显示效果与打印效果完全不一样。这正是对低分辨率屏幕的处理方案——增加 Hint 信息来保证清晰度。所谓 Hint 就是为了让字体在低分辨率的液晶屏幕上也能清晰显示的技术。在低分辨率屏幕上,如果没有合适的 Hint 信息,字体很有可能会丧失一些笔画或者模糊成一团。而如何正确地使用这一信息,要靠 GASP 表(Grid-fitting And Scan-conversion Procedure)。GASP 的作用是告诉字体渲染引擎,在什么样的分辨率下采用什么样的渲染参数。
苹果 Mac OS X对于字体的渲染和显示的思路是让屏幕上显示的和在纸上打印的效果相同,而微软 Windows 的思路则是适应更多的设备,让字体在低分辨率设备上也能看清楚,即便如此会导致字体笔画发生一定的改变。这一最初设计思路的不同也就导致了两者在字体渲染上很大的差异。从系统开发之初确定的这一思路陆续影响到了后来的应用开发。而到了高分辨率屏幕渐渐普及的今天,传统的 GDI 引擎不能适应高分辨率,也就导致之前开发的 Win32 应用中的字体在高 DPI 情况下显示模糊或者不正常。
到了Windows 10 之后,微软对于 Universal Windows Platform 的应用一律采用 DirectWrite 进行字体渲染,所以 UWP 应用基本上不用担心高 DPI 下字体的渲染问题,在高分辨率情况下的字体渲染与显示会很好。
Windows 10 的字体渲染问题
Windows 10 的字体渲染问题分为两个方面。
1、字体问题。对于 Windows 10 Build 10240 所带的微软雅黑6.20字体,其问题在于,其中包含了不合适的 GASP 表。比如在高 DPI 或者大字号下面就不需要让字体渲染引擎进行 Hint,大量的显示器像素点完全可以达到矢量字体的设计效果。只有在字比较小或者低分辨率屏幕上,就应该启用Hint,否则字体就模糊了。然而,如果用户的屏幕本身已经是高分辨率的情况下,再告诉渲染引擎用 Hint 对字体进行清晰化,就会导致本来可以清晰显示的字体变得十分难看,或是高低不平,或是挤成一团。就比如《Windows 10 体验记》一文中关于字体的截图。这一问题在 Windows 10 Build 10586 中附带的微软雅黑字体 6.21中有了一定的缓解。然而,对于处于高分辨率和低分辨率之间的模糊地带屏幕来说却仍然不够好。这些屏幕并没有 Retina 那样的高分辨率,但是对于普通屏幕来说分辨率也不低。就比如现在很多电脑使用的 1080p 的屏幕。使用推荐的 125% DPI情况下,字体笔画之间仍然会出现一些不协调的情况。
2、传统字体引擎 GDI 问题。这不能说是 Windows 10 的问题,而是存在于 Windows 7、Windows 8/8.1、Windows 10 中的一个历史遗留问题,也就是说只要是采用 GDI 引擎的传统 Win32 应用在高 DPI 下都会模糊。这一问题的解决方案也有两个:(1)DPI 设定为 100%;(2)使用 MacType 等第三方渲染引擎替代 GDI 对传统 Win32 应用进行渲染。
解决问题
1、对于第一个问题——字体问题,极限社区的大神 RadarNyan 给出了的方案是修正 GASP 表来使所有 DPI 下均不使用 Hint。利用一个脚本可以批量将字体的 GASP 表进行修正。我对这个脚本的通用性进行了一定的改进。
注意:以下操作涉及到系统文件修改,请注意备份。并且此修正方案在升级系统(大升级)后可能会消失。风险自负。
(1)下载这个脚本,并解压到合适位置。(GaspHack_v2_MOD)
(2)接着运行 GaspHack_v2_MOD.bat ,等待执行完成。
(3)执行完成后,在 workingDir\output 下面找到 msyh*.ttc(微软雅黑)、segoeui*.ttf、segui*.ttf(Segoe UI),复制出来待用。
(4)接着在“设置”,“更新和安全”,“恢复”中选择“立即重启”(注意保存好工作),在“疑难解答”中选择“命令提示符”。
(5)用 copy 命令将复制出来的字体覆盖到 X:\Windows\Fonts 下面(X为系统安装盘符)
(6)重新启动系统。
最后,你会发现DirectWrite下面字体的显示有了很大的提升。
2、对于第二个问题,可以安装 MacType 解决。
最后附上一张替换 Simsun.ttc 之后的效果(由 DirectWrite 渲染,DPI 设置为 100%)
参考资料
知乎专栏 可可苏玛
http://zhuanlan.zhihu.com/first-aid/20098798
http://zhuanlan.zhihu.com/first-aid/20098871
http://zhuanlan.zhihu.com/first-aid/20112246
http://zhuanlan.zhihu.com/first-aid/20112320
极限社区 RadarNyan
http://bbs.themex.net/showthread.php?t=16903935
看你这分析,才发觉为什么win8以后的自己感觉那么难看,明明从xp后就有cleartype这么好的技术了,为什么到新版本又变丑了。
之前不论给谁装系统,即使是xp系统我也会专门装cleartype,位in的话还会用系统自带的校正颜色。到了win8和win10一下子就难搞了,各种找不到或者没有,感觉好烦。
Win10 变丑的原因是微软雅黑的 Hinting。
Win8/8.1 Modern 应用的中文显示是有 Fallback 的 Bug 的,非中文系统开发的 Modern 应用在显示中文的时候会先 Fallback 到日韩文字体中的汉字,所以有些应用的显示上会比较奇怪(甚至在 Win8 的时候,开始屏幕的“开”字就明显画风不对,此处可以见我体验 Win8 的文章)。
ClearType 只能算是一个折衷的方案,仍然基于 GDI,高分辨率下显示效果很差。就算开 ClearType,高分辨率还是模糊(相当于是小字截图拉伸的效果)。
而 DirectWrite 已经是一个很优秀的字体渲染引擎了,但是 Windows 字体的问题其实出在应用上。早期没有做好,现在只能等开发者慢慢解决了。
作为对 GDI 的一个替换,其实既然民间有人能开发 MacType,按理说微软不可能没有这个实力,甚至一个补丁就能解决,但是至于为什么微软自己不对 GDI 进行一个改进,或许是有别的更深层次原因吧。
只可惜 DirectWrite 会有过细的毛病
不知道宋体特别细的毛病通过这样做是否可以解决?
现在的不清楚,只知道Ubuntu早年的字体渲染,漂亮得艳惊四座,Mac比起来都弱爆。
我也一直觉得Ubuntu的字体看着最舒服。。。
哇,非常有效,能否转一下修正 GASP 表的方法?
可以。Window 10 Creators Update 已经对传统应用(例如MMC)的字体渲染进行了修正,建议升级。
补充一下copy 命令为
copy C:\X\*.* C:\Windows\Fonts
(X为存放需要替换文件的位置)
Window 10 Creators Update 还需要修复字体渲染吗
应该说可以不用了
为什么不装MacType呢?
MacType 对系统影响有点大,大版本更新之后可能会有问题。
为什么我没有 segui.ttf 这个文件呢
不是中文版的系统?
是中文家庭版。
脚本是直接从Windows的字体文件夹(X:\Windows\Fonts)复制字体到临时目录然后再进行处理的,如果没有那就有可能是系统真的缺少这一字体,可以从其他相同版本的操作系统中复制一份。
好的,谢谢了。
不能放在带空格的文件夹下……