Como combinar vários nomes de fontes com um único elemento de correspondência?

3

Se eu quiser Arial quando Helvetica ou DejaVu Sans forem solicitados, esta configuração funciona bem:

<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>

Um teste rápido:

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

Mas é muito detalhado. O manual fontconfig menciona <or> element, mas não possui exemplos de como usá-lo corretamente. Eu tentei pesquisar o github link , que retorna vários exemplos muito semelhantes a:

<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>

Infelizmente, se eu reescrever ingenuamente minha configuração para

<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>

que quebra todas as correspondências:

$ echo Terminus Helvetica | xargs -n1 fc-match
arial.ttf: "Arial" "Regular"
arial.ttf: "Arial" "Regular"
    
por Alexander Gromnitsky 07.08.2017 / 20:56

1 resposta

0

Infelizmente, não há solução melhor do que repetir todo o elemento <match> para cada nome de família que você deseja corresponder. Isso está documentado na página man 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>

Veja o erro fontconfig # 33644 , em que alguém reclamou que a regra com vários elementos <string> dentro do elemento <test> não funcionou como esperado. Essa regra era muito semelhante à sua regra, que seria assim:

<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>

O problema com essas regras é que, se vários valores mencionados na regra estiverem presentes no padrão, a regra corresponderia ao valor especificado anteriormente na regra, mesmo que o valor correspondente apareça depois de outros valores correspondentes no padrão. ; então mode="prepend" pode não ter o efeito desejado. Por exemplo:

  • se o padrão contiver "Helvetica, DejaVu Sans", a regra corresponderia a "Helvetica" e resultaria em "Arial, Helvetica, DejaVu Sans";
  • se o padrão contiver “DejaVu Sans, Helvetica”, a regra ainda corresponderá a “Helvetica” e resultará em “DejaVu Sans, Arial, Helvetica”, portanto, Arial não será selecionado como desejado.

Se você usar regras separadas, ambas serão aplicadas em ambos os casos, e você receberá "Arial, Helvetica, Arial, DejaVuSans" ou "Arial, DejaVuSans, Arial, Helvetica", portanto, Arial seria selecionado em ambos os casos.

Em resposta a esse relatório de bug, o fontconfig foi alterado para imprimir avisos quando <test> elementos com vários valores são encontrados na configuração , portanto, você não deve usar esse recurso mesmo nos casos em que ele funcione corretamente.

Quanto ao elemento <or> , ele funciona somente em expressões, recebe dois ou mais valores booleanos e retorna um valor booleano, portanto, não é adequado para sua tarefa.

    
por 26.10.2018 / 10:00

Tags