[Feelings & Sharing] 【水】关于字体微调和Fontconfig
Tofloor
poster avatar
enforcee
deepin
2023-07-16 03:39
Author

字体微调(Font Hinting)是一种让字体更清晰的方法。原理是调整字形,移动文字的笔画对准屏幕的像素。如果笔画处于像素的夹缝之间,经过平滑(抗锯齿)就会产生半透明。

我看很多人都说Windows的字体显示效果是微软的专利,别的系统用不了,这是错误的,从维基百科可以看到:https://en.wikipedia.org/wiki/FreeType

1.字体微调是苹果的专利,微软的专利是ClearType(我们称之为子像素渲染,在LCD屏幕上把每个像素的红绿蓝排列位置也考虑到文字渲染中去。)

2.这些专利都过期了。字体微调是2010年,ClearType是2019年。

最重要的是这个功能本来就有,就是没默认开启。估计Fontconfig是想让设计或者打包字体的去配置。因为有些字体是自带微调能力的,但是没有内置微调的字体也可以使用自动微调(autohint)来优化效果。

比如说创建这个配置文件 ~/.config/fontconfig/fonts.conf 给所有字体开启自动微调(子像素是默认开启的,不需要再配置了。):




    
    
      true
    
    
      hintslight
    
  


要想看到效果只需要退出再重新登录用户即可。(有些应用会立刻生效。)

不过在系统配置文件目录(/etc/fontconfig/conf.d)中一些文件可能比这个文件更后加载,把某些字体的配置覆盖掉了。这种情况就需要单独修改各个配置文件了。

这个配置使用hintslight,只添加竖直方向的微调(和Windows应该是一样的)。如果换成hintmedium或者hintfull,会增加水平方向的微调,不过这也有可能造成较小字体的字符左右摆动,看着英文不整齐。

采用Pango/Cairo(GTK组件包、Firefox、Thunderbird)或Qt组件包的程序都能生效。

有些程序在开启autohint后还需要单独设置,比如GNOME Shell和GTK4应用还需要用GNOME Tweaks里面的字体选项再调整,blender需要再设置里先自定义一个字体再开启微调(而且不能选Noto Sans CJK系列,因为blender不能读组合型的字体文件。)

图片.png

为什么配置一个文件能让几乎所有程序都有效果呢?其实这都是Fontconfig的功劳。过去GTK和Qt的字体渲染都是各干各的,而Fontconfig出世以后,统一了字体选择和配置,给开发者和用户省去了很多麻烦。

https://www.freedesktop.org/wiki/Software/fontconfig/

Fontconfig包括协议、库、配置文件和各种工具。既然他叫config,自然方便配置是主要目标。Fontconfig使用xml作为配置文件的格式。不过仔细一看,感觉他们好像是拿xml做了个编程语言。

各种工具的作用如下:

fc-conflist:列出找到的配置文件,是否加载以及加载顺序。

fc-list:列出所有安装的字体。

fc-query:查看一个字体文件的信息。

fc-scan:和fc-query类似,但是可以检查目录。

fc-pattern:把一个简略的字体描述(称为样式pattern)解析成详细信息。

fc-match:通过简略的字体描述(样式pattern),在已安装的字体中找到一个符合的(如果没有就显示默认字体)。另外加上-v选项可以用来检查配置文件是否生效。

fc-validate:检查字体是否能覆盖某种语言的字符需求。

fc-cache:创建字体信息缓存文件。

fc-cat:读取字体信息缓存。


这次写得很着急,因为不想太多花费时间在研究文字上。以后估计都是这个风格了。

Reply Favorite View the author
All Replies
阿尼樱奈奈
Moderator
2023-07-16 03:40
#1

感谢您的分享。

Reply View the author
enforcee
deepin
2023-07-16 03:47
#2

关于子像素渲染,需要注意的是屏幕的RGB排列顺序。一般LCD都是默认从左到右RGB的,但是比如说平板电脑可能会有屏幕旋转的情况或者一些设备的屏幕是旋转着安装的,这样就需要根据实际情况调整了。有个挺有意思的简单方法能测出屏幕的RGB顺序,见网站:http://www.lagom.nl/lcd-test/subpixel.php

看这张图片的时候,不要放大,用显示器的原始分辨率看,浅蓝色方块的四边有一条显得更黑,而那一边的线条图也比其他三个更清晰,对应的排列顺序就是当前显示器的顺序。

另外这个主要是给LCD屏幕使用的,其他类型的屏幕就没必要研究了。

Reply View the author
f@deepin
deepin
2023-07-16 07:53
#3

~/.config/fontconfig/font.conf

还是

~/.config/fontconfig/fonts.conf

如果用 font.conf,fc-conflist 看不到加载

Reply View the author
enforcee
deepin
2023-07-16 08:34
#4
f@deepin

~/.config/fontconfig/font.conf

还是

~/.config/fontconfig/fonts.conf

如果用 font.conf,fc-conflist 看不到加载

是这样,我写错了

Reply View the author
enforcee
deepin
2023-07-16 19:14
#5

可恶,发现了cairo的个bug

sad

Reply View the author
superJunior
deepin
2023-07-17 05:55
#6

想不到2023了还有讨论字体渲染的大佬,这个话题其实在win10出来之后已经没什么讨论了,因为微软正努力跟上mac/ubuntu的印刷模式渲染😂在此之前都是吐槽win7/xp字体渲染难看的,还有专门的仿mactype优化软件。在手机1080P起步,笔记本普遍2k的现在,大可不必追求微软那个牺牲字形的“清晰”方式了。

Reply View the author
enforcee
deepin
2023-07-17 06:06
#7
superJunior

想不到2023了还有讨论字体渲染的大佬,这个话题其实在win10出来之后已经没什么讨论了,因为微软正努力跟上mac/ubuntu的印刷模式渲染😂在此之前都是吐槽win7/xp字体渲染难看的,还有专门的仿mactype优化软件。在手机1080P起步,笔记本普遍2k的现在,大可不必追求微软那个牺牲字形的“清晰”方式了。

给世界再多留一点知识吧

blush

Reply View the author
enforcee
deepin
2023-07-17 06:24
#8

其实很多应用hintmedium和hintfull是完全一样的,而cairo在子像素抗锯齿的情况下hintfull却和hintslight一致,hintmedium才是最强的微调(我已经给开发者提了issue,不知道他会不会修),这个bug影响GTK工具包和Firefox等应用。

所以实际上只有三个模式,hintnone关闭微调,hintslight竖直方向微调(和Windows的处理方法一致),以及hintmedium/hintfull竖直方向+水平方向微调(建议用hintmedium规避问题)。

blush

然后如果觉得微调之后的字体还是不够清楚,可以选用一款点阵字体(比如「文泉驿点阵正黑」),这种字体内嵌了点阵数据(而不是常用的矢量字形,这样就不存在矢量转栅格的问题了),和特别古老的电脑字体效果类似,不过字形也不会很好看。

Reply View the author
enforcee
deepin
2023-07-17 23:46
#9

LCD屏幕的任何字体调节都必须在原生分辨率运行才能有效果(否则就是劣化)。

另外对于其他技术的屏幕(CRT、OLED),也需要根据实际情况进行调整,不能盲目套用。

Reply View the author
enforcee
deepin
2023-07-19 07:02
#10

可恶*2,我发现的那个bug其实不是bug,是设计原因
blush

Reply View the author
enforcee
deepin
2023-07-20 19:22
#11

Qt的微调模式:
Qt5(https://doc.qt.io/qt-5/qfont.htm):

PreferDefaultHinting PreferNoHinting PreferVerticalHinting PreferFullHinting
Windows Vista (w/o Platform Update) and earlier Full hinting Full hinting Full hinting Full hinting
Windows 7 and Windows Vista (w/Platform Update) and DirectWrite enabled in Qt Full hinting Vertical hinting Vertical hinting Full hinting
FreeType Operating System setting No hinting Vertical hinting (light) Full hinting
Cocoa on macOS No hinting No hinting No hinting No hinting

Qt6(https://doc.qt.io/qt-6/qfont.html):

PreferDefaultHinting PreferNoHinting PreferVerticalHinting PreferFullHinting
Windows and DirectWrite enabled in Qt Full hinting Vertical hinting Vertical hinting Full hinting
FreeType Operating System setting No hinting Vertical hinting (light) Full hinting
Cocoa on macOS No hinting No hinting No hinting No hinting
Reply View the author
enforcee
deepin
2023-07-20 19:30
#12

其实Qt和Cairo字体渲染用的都是FreeType库。从上面的表格上能看出来,Qt的微调只有三个模式,无、竖直方向、水平和竖直方向。也就是说,在fontconfig的四个微调模式(无、轻微、中等、全部)中,对于Qt来说后两个是完全相同的。

有意思的是可以看到其他系统中,macOS确实是没有微调的(这也印证了网友的印象)。Windows的微调似乎是不能关闭的。

Reply View the author
enforcee
deepin
2023-07-20 20:35
#13

Cairo的模式有点复杂,我去读了源代码,Cairo的字体渲染是由fontconfig中的抗锯齿和微调两个属性来控制FreeType的模式,大概是这样的:

https://gitlab.freedesktop.org/cairo/cairo/-/blob/master/src/cairo-ft-font.c

无抗锯齿 灰度抗锯齿 次像素抗锯齿
无微调 A C C
轻微微调 B D D
中等微调 B E E
全部微调 B E F

A:无微调+单调(monochrome)滤镜。
B:单调专用微调模式+单调滤镜。也就是说,无抗锯齿时的各种微调其实都是一种模式。

C:无微调。
D:轻度微调模式(只有竖直方向)
E:正常微调模式(竖直和水平方向)
以上C、D、E三个模式虽然在灰度和次像素抗锯齿时共用的,但是因为抗锯齿也同时影响字体的外观,所以实际上是不一样的。另外在灰度抗锯齿时,中等微调和全部微调是一样的。

F:根据设置的LCD次像素排列顺序选择对应的模式。如果是水平排列,则选择「水平LCD专用微调模式」,实际上是「轻度微调模式」的变体。如果是竖直排列,则选择「竖直LCD专用微调模式」,实际上是「正常微调模式」的变体。
所以在这种模式下,如果是水平LCD,则看上去和轻微微调非常相似(只有个别文字有像素级别的颜色差异,视觉难以分辨,我用了GIMP放大交替图层对比才看出来),这也是一开始我以为他是bug的原因。因此在Cairo中「中等微调」才是在所有模式中保持最大微调的设置。


以上简介中对应的FreeType定义:
正常微调模式:FT_LOAD_TARGET_NORMAL
轻度微调模式:FT_LOAD_TARGET_LIGHT
单调微调模式:FT_LOAD_TARGET_MONO
水平LCD专用微调模式:FT_LOAD_TARGET_LCD
竖直LCD专用微调模式:FT_LOAD_TARGET_LCD_V
无微调:FT_LOAD_NO_HINTING
单调滤镜:FT_LOAD_MONOCHROME
https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html

Reply View the author
enforcee
deepin
2023-07-20 22:00
#14

https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/text/freetype/qfontengine_ft.cpp
Qt的模式和上面差不多,只是Qt并没有使用FreeType的LCD专用微调模式,也就是说把上面Cairo的表格F换成E。

Reply View the author
enforcee
deepin
2024-04-04 14:30
#15

GTK4取消了子像素渲染(ClearType)的功能:
https://blog.gtk.org/2024/03/07/on-fractional-scales-fonts-and-hinting/

Reply View the author