如何在fontconfig中设置每个Unicode范围/代码点的字体?

Joh*_*zer 6 linux unicode fonts fontconfig

我最近想出了如何fontconfig在Linux 上使用serif,sans-serif和monospaced字体设置系统默认字体; 基本上,您~/.config/fontconfig/fonts.conf使用以下内容保存XML配置文件:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>

<match>
  <test qual="any" name="family"><string>serif</string></test>
  <edit name="family" binding="strong" mode="prepend_first">
    <string>Gentium</string>
    <string>Sun-ExtA</string>
    <string>HanaMinA</string>
    <string>HanaMinB</string>
    </edit>
  </match>

</fontconfig>
Run Code Online (Sandbox Code Playgroud)

这些binding="strong" mode="prepend_first"属性确保匹配规则优先于其他设置,并且字体名称序列确保字体不包含给定的代码点/字符,尝试列表中的下一个字体(此列表适用于top-to -bottom;恕我直言,它应该是一个后来更强大的逻辑,但无论如何).

这种配置的优点在于它可以在文本编辑器和终端仿真器中使用.

然而,还有一个问题:在许多情况下,给定的字体确实包含给定的字形,但另一种字体对于该代码点是可取的; 例如,它Sun-ExtA是CJK字符的一个很好的默认字体,但它也涵盖了很多很多非CJK字符,并且有一些有问题的字形.

假设我不喜欢? U+3007 IDEOGRAPHIC NUMBER ZEROin 的外观Sun-ExtA而宁愿使用HanaMinA它,我怎么能这样做fontconfig呢?很显然,我不能只优先考虑的进入HanaMinASun-ExtA,因为这将影响到所有包含在两种字体字形的.

我的预感是应该有一个涉及元素的解决方案<charset>(根据 fontconfig用户文档,"此元素至少包含一个Unicode代码点或更多的元素")和/或<range>("此元素包含范围的两个元素表示"-presumably表示一系列Unicode代码点".但是,我找不到一个如何使用这些元素的例子.

是否可以将fontconfig配置为对单个Unicode代码点或一系列代码点使用特定字体?

小智 5

在扫描模式内,在标记<minus>中包含一个元素<edit>可以让您从字符集中减去。

这主要是为了从字体中删除“坏”或有问题的字符而设计的,但更进一步,您可以编写一个<test>匹配除您想要使用的字体之外的所有字体的字体:

<match target="scan">
  <test name="family" compare="not_eq">
    <string>VL Gothic</string>
  </test>
  <edit name="charset" mode="assign">
    <minus>
      <name>charset</name>
      <range>
        <int>0x0021</int>
        <int>0x00FF</int>
      </range>
    </minus>
  </edit>
</match>
Run Code Online (Sandbox Code Playgroud)

类似的配置也可用于lang从字体中删除整个 s。

据我所知,这之前并没有真正记录在案,我是从 Redhat bug 中发现的

  • 首先,这个答案包含一个错误:fontconfig 抱怨“范围”周围缺少“字符集”。而且,不幸的是,它似乎要么无法与 fontconfig 2.13 一起工作,要么会干扰其他东西。所有应用程序(包括浏览器和终端模拟器)仍然使用应从中删除的字体呈现“已删除”字符:( (3认同)
  • 对我来说,类似的情况不适用于 fontconfig 2.13.1,而不在 `&lt;range&gt;` 部分添加 `&lt;charset&gt;` 标签,即 `&lt;charset&gt;&lt;range&gt;&lt;int&gt;0x0021&lt;/int&gt;&lt;int&gt; 0x00FF&lt;/int&gt;&lt;/range&gt;&lt;/charset&gt;`,(也可以使用多个范围。) (3认同)

nim*_*nim 2

您可以使用以下命令在 fontconfig 中升级特定区域设置的字体:

   <match>
    <test name="lang">
      <string>[RFC-3066 language code]</string>
    </test>
    <test name="family">
      <string>[genericname]</string>
    </test>
    <edit name="family" mode="prepend">
      <string>[fontname]</string>
    </edit>
  </match>
   <alias>
    <family>[fontname]</family>
     <default>
      <family>[genericname]</family>
     </default>
   </alias>
Run Code Online (Sandbox Code Playgroud)

需要仔细使用 fontconfig 优先级,以便在您不需要的字体之前和常见的拉丁/希腊/西里尔字体之后提升字体(因为 CJK 拉丁字形往往很糟糕)。

当然,假设当您在需要此覆盖的语言环境中读/写时,您的软件环境能够向 fontconfig 发出信号。