如何将多个字体名称与单个字体名称相匹配元素?

如何将多个字体名称与单个字体名称相匹配元素?

如果我愿意宋体什么时候黑体 或者 似曾相识 Sans要求,此配置工作正常:

<match target="pattern">
  <test name="family"><string>Helvetica</string></test>
  <edit binding="strong" mode="prepend" name="family">
    <string>Arial</string>
  </edit>
</match>

<match target="pattern">
  <test name="family"><string>DejaVu Sans</string></test>
  <edit binding="strong" mode="prepend" name="family">
    <string>Arial</string>
  </edit>
</match>

快速测试:

$ echo Terminus Helvetica | xargs -n1 fc-match
ter-x12n.pcf.gz: "Terminus" "Regular"
arial.ttf: "Arial" "Regular"

但它太冗长了。 fontconfig 手册提到了<or>element,但缺乏如何正确使用它的示例。我尝试搜索github https://github.com/search?q=match+test+or+extension%3Aconf,它返回一堆与以下内容非常相似的示例:

<match target="font">
  <or>
    <test name="family"><string>Nasu</string></test>
    <test name="family"><string>NasuM</string></test>
  </or>
  <edit name="autohint"><bool>false</bool></edit>
</match>

不幸的是,如果我天真地将我的配置重写为

<match target="pattern">
  <or>
    <test name="family"><string>Helvetica</string></test>
    <test name="family"><string>DejaVu Sans</string></test>
  </or>
  <edit binding="strong" mode="prepend" name="family">
    <string>Arial</string>
  </edit>
</match>

这会破坏所有匹配:

$ echo Terminus Helvetica | xargs -n1 fc-match
arial.ttf: "Arial" "Regular"
arial.ttf: "Arial" "Regular"

答案1

不幸的是,没有比<match>为您想要匹配的每个姓氏重复整个元素更好的解决方案了。这在 fonts-conf(5) 手册页中有记录:

   <--
        The example of the requirements of OR operator;
        If the 'family' contains 'Courier New' OR 'Courier'
        add 'monospace' as the alternative
   -->
   <match target="pattern">
        <test name="family" compare="eq">
             <string>Courier New</string>
        </test>
        <edit name="family" mode="prepend">
             <string>monospace</string>
        </edit>
   </match>
   <match target="pattern">
        <test name="family" compare="eq">
             <string>Courier</string>
        </test>
        <edit name="family" mode="prepend">
             <string>monospace</string>
        </edit>
   </match>

看着字体配置错误#33644,有人抱怨元素<string>内有多个元素的规则<test>没有按预期工作。该规则与您的规则非常相似,如下所示:

<match target="pattern"> <test name="family"> <string>Helvetica</string> <string>DejaVu Sans</string> </test> <edit binding="strong" mode="prepend" name="family"> <string>Arial</string> </edit> </match>

此类规则的问题在于,如果模式中存在规则中提到的多个值,则该规则将匹配规则中先前指定的值,即使相应的值出现在模式中其他匹配值之后;那么mode="prepend"可能达不到想要的效果。对于你的例子:

  • 如果模式包含“Helvetica, DejaVu Sans”,则规则将匹配“Helvetica”并产生“Arial, Helvetica, DejaVu Sans”;
  • 如果模式包含“DejaVu Sans, Helvetica”,则该规则仍会匹配“Helvetica”并导致“DejaVu Sans, Arial, Helvetica”,因此不会根据需要选择 Arial。

如果您使用单独的规则,则这两种规则都将应用于两种情况,并且您将得到“Arial,Helvetica,Arial,DejaVu Sans”或“Arial,DejaVu Sans,Arial,Helvetica”,因此在两种情况下都会选择Arial案例。

回应该错误报告fontconfig 已更改为<test>在配置中找到具有多个值的元素时打印警告,因此即使该功能可以正常工作,您也不应该使用它。

至于<or>元素,它仅适用于表达式,采用两个或多个布尔值并返回一个布尔值,因此它不适合您的任务。

相关内容