SDB:如何报告字体问题
本文讨论了基于 fontconfig 的应用程序的字体渲染问题,以及如何正确地调试和报告这些问题。
情况
您注意到您桌面上的某些字体渲染不正确,并且希望在未来的 openSUSE 版本中改进它们,以便所有 openSUSE 用户都能受益。
涉及的库
- freetype -- 字体渲染库 (freetype 主页)
- fontconfig -- 用于配置和自定义字体访问的库 (fontconfig 主页)
流程
freetype 库使用多种字体渲染算法。使用 fontconfig 来确定 UI 或文档要选择的已安装字体,可以通过以下文件中的配置文件进行配置:/etc/fonts以及从那里包含的文件或目录(例如~/.fonts.conf文件)。
示例
尝试以下操作~/.fonts.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/local.conf file for local customizations -->
<fontconfig>
<match target="font">
<edit name="matrix">
<matrix>
<double>-1</double><double>0</double>
<double>0</double><double>1</double>
</matrix>
</edit>
</match>
</fontconfig>
并重新运行任何 X 应用程序,以查看此更改是否对其有影响。
必填部分
请提交一个错误报告。在摘要字段中,使用fontconfig:$family_name:$whats_wrong并用相应的值替换占位符。您需要弄清楚哪个字体系列渲染有问题,才能提交有用的错误报告。从您的系统中收集此信息没有唯一的方法。如果受影响的应用程序的字体对话框没有帮助,则以下命令可以为您提供线索:
其中 fc-debug.sh 包装器可以如下所示:
FC_DEBUG=1 $@ | egrep -A2 -e "Best score" -e "First font Pattern" | grep family: | sed 's:.*\(".*"\).*:\1:' | sort | uniq
注意:并非在相同情况下,相同的程序在其他系统上使用相同的字体;这取决于渲染库的配置以及安装了哪些字体。换句话说,对于相同的查询,您可以在不同的系统上获得不同的字体。
$whats_wrong也可以是通用的“渲染错误”,但任何细节都值得欢迎,并且始终需要截图。
示例
我们注意到,R 对于某些字体渲染错误。
我们当然对暴露问题的最快方法感兴趣,即
- 运行firefox https://en.opensuse.net.cn/SDB:How_to_Report_a_Printing_Issue
- Ctrl+Q
对于这种情况。使用fc-debug我们得到
$ fc-debug.sh firefox https://en.opensuse.net.cn/SDB:How_to_Report_a_Printing_Issue 2>/dev/null "Cantarell" "DejaVu Sans" "DejaVu Sans Mono" "Liberation Sans"
然后,可以通过任何能够显示您选择的字体的应用程序(例如,具有字体对话框的应用程序)来确定有问题字体。
现在很明显,罪魁祸首是 Liberation Sans。但是,渲染结果取决于字体大小:对于 10pt,这个问题几乎无法察觉。对于较小的字体,它变得更加明显。
可选部分
为了更好地帮助我们,您可以进行实验并尝试各种字体渲染算法,看看哪种算法可以更好地显示您认为的字体。
注意:请将次像素渲染放在一边 (专利,bugzilla 先例,如何启用次像素提示)。
使用以下 fontconfig 文件(例如,作为~/.fonts.conf):
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<test name="family">
<string>FAMILY_NAME</string>
</test>
<edit name="antialias" mode="assign">
<bool>true</bool>
</edit>
<edit name="hinting" mode="assign">
<bool>true</bool>
</edit>
<edit name="autohint" mode="assign">
<bool>false</bool>
</edit>
<edit name="hintstyle" mode="assign">
<const>hintfull</const>
</edit>
</match>
</fontconfig>
用有问题字体的名称替换 FAMILY_NAME。
- 可以启用抗锯齿 (antialiasing=true) 或禁用 (antialiasing=false),请参阅 字体栅格化
- 可以启用提示 (hinting=true) 或禁用 (hinting=false),请参阅 字体提示
- 提示可以使用字节码解释器 (BCI,DejaVu 提示教程,autohinting=false) 或使用 freetype 的自动提示 (FreeType 自动提示,autohinting=true)
- 提示级别使用hintstyle定义;此变量的预期值是0 (hintnone), 1 (hintslight), 2 (hintmedium) 和3 (hintfull)
据说大多数字体使用以下值可以获得最佳结果
| 字体的本机指令 | 抗锯齿 | 提示 | 自动提示 | hintstyle |
|---|---|---|---|---|
| 好 | true | true | false | 3 |
| 不完整或没有 | true | true | true | 1 |
这可能是一种品味问题,是的。例如,有些用户可能喜欢没有抗锯齿的字体渲染。此外,一种算法的优势可能会被另一种算法的优势所平衡。
将告诉您用于渲染与 PATTERN 匹配的字体的算法。在极少数情况下,渲染算法的选择可能取决于模式的其他条目,因此字体名称有时是不够的。您可以通过组合渲染算法在~/fonts.conf中进行实验。不要忘记在更改 fontconfig 文件后重新运行测试程序。
示例
继续之前的示例。使用
我们得到
Pattern has 31 elts (size 32)
family: "Liberation Sans"(s)
familylang: "en"(s)
style: "Regular"(s)
stylelang: "en"(s)
fullname: "Liberation Sans"(s)
fullnamelang: "en"(s)
slant: 0(i)(s)
weight: 80(i)(s)
width: 100(i)(s)
size: 12(f)(s)
pixelsize: 12.5(f)(s)
foundry: "unknown"(s)
antialias: FcTrue(w)
hintstyle: 3(i)(w)
hinting: FcTrue(w)
verticallayout: FcFalse(s)
autohint: FcFalse(w)
globaladvance: FcTrue(s)
file: "/usr/share/fonts/truetype/LiberationSans-Regular.ttf"(s)
index: 0(i)(s)
outline: FcTrue(s)
scalable: FcTrue(s)
dpi: 75(f)(s)
scale: 1(f)(s)
charset:
0000: 00000000 ffffffff ffffffff 7fffffff 00000000 ffffffff ffffffff ffffffff
0001: ffffffff ffffffff ffffffff ffffffff 00040000 00000000 00000000 fc000000
0002: 0f000000 00000000 00000000 00000000 00000000 00000000 3f0002c0 00000000
0003: 00000000 00000000 00000000 40000000 ffffd7f0 fffffffb 00007fff 00000000
0004: ffffdffe ffffffff dffeffff 00000000 00030000 00000000 00000000 00000000
001e: 00000000 00000000 00000000 00000000 0000003f 00000000 00000000 000c0000
0020: 7fbb0000 560d0047 00000010 80000000 00000000 00001098 00000000 00000000
0021: 00480020 00004044 78000000 00000000 003f0000 00000100 00000000 00000000
0022: c6268044 00000a00 00000100 00000033 00000000 00000000 00000000 00000000
0023: 00010004 00000003 00000000 00000000 00000000 00000000 00000000 00000000
0025: 11111005 10101010 ffff0000 00001fff 000f1111 14041c03 03008c10 00000040
0026: 00000000 1c000000 00000005 00000c69 00000000 00000000 00000000 00000000
00f0: 00000026 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00fb: 00000006 00000000 00000000 00000000 00000000 00000000 00000000 00000000
(s)
lang: aa|af|ast|av|ay|be|bg|bi|br|bs|ca|ce|ch|co|cs|cy|da|de|el|en|eo|es|et|eu|fi|fj|fo|fr|fur|fy|gd|gl|gv|ho|hr|hu|ia|id|ie|ik|io|is|it|ki|kl|kum|la|lb|lez|lt|lv|mg|mh|mo|mt|nb|nds|nl|nn|no|nr|nso|ny|oc|om|os|pl|pt|rm|ro|ru|se|sel|sk|sl|sma|smj|smn|so|sq|sr|ss|st|sv|sw|tk|tl|tn|tr|ts|uk|uz|vo|vot|wa|wen|wo|xh|yap|zu|an|crh|csb|fil|hsb|ht|jv|kj|ku-tr|kwm|lg|li|ms|na|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(s)
fontversion: 69468(i)(s)
capability: "otlayout:DFLT otlayout:cyrl otlayout:grek otlayout:latn"(s)
fontformat: "TrueType"(s)
embeddedbitmap: FcFalse(w)
decorative: FcFalse(s)
这意味着我们期望使用字体的提示指令比使用自动提示获得更好的结果。更改为autohinter=true和hintstyle=1通过
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font">
<test name="family">
<string>Liberation Sans</string>
</test>
<edit name="antialias" mode="assign">
<bool>true</bool>
</edit>
<edit name="hinting" mode="assign">
<bool>true</bool>
</edit>
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
<edit name="hintstyle" mode="assign">
<const>hintslight</const>
</edit>
</match>
</fontconfig>
给出


