From Fedora Project Wiki

m (minor spacing correction)
 
(20 intermediate revisions by 5 users not shown)
Line 7: Line 7:
 
Before packaging a new (custom-created or upstream-created) fontconfig ruleset, please post it on the [[Fonts_SIG_mailing_lists| SIG list]] for review.}}
 
Before packaging a new (custom-created or upstream-created) fontconfig ruleset, please post it on the [[Fonts_SIG_mailing_lists| SIG list]] for review.}}
  
 +
{{Admon/note | Code snippets only |
 +
The examples given on this page are code snippets. They won't work if you do not add the usual [[#xml-wrapper| XML wrapper]] around them.}}
 +
 +
== Config file considerations ==
  
 
{{Anchor|ruleset-prefix}}
 
{{Anchor|ruleset-prefix}}
== Choosing a ruleset numeral prefix ==
+
=== Choosing a ruleset numeral prefix ===
  
 
Fontconfig will sort the ruleset files dropped in '''/etc/fonts/conf.d/''' by filename before evaluating them. Therefore the rules of '''01-xxx.conf''' and '''02-yyy.conf''' will have the same effect a single '''01-xy.conf''' file containing first xxx rules then yyy rules.
 
Fontconfig will sort the ruleset files dropped in '''/etc/fonts/conf.d/''' by filename before evaluating them. Therefore the rules of '''01-xxx.conf''' and '''02-yyy.conf''' will have the same effect a single '''01-xy.conf''' file containing first xxx rules then yyy rules.
  
 
Usually that means the files with the smaller prefix will have higher precedence. Unfortunately the fontconfig syntax is pretty flexible and allows prepending effects to existing rules. Careful testing is therefore required if your package deploys rules that interact with the existing fontconfig ruleset.
 
Usually that means the files with the smaller prefix will have higher precedence. Unfortunately the fontconfig syntax is pretty flexible and allows prepending effects to existing rules. Careful testing is therefore required if your package deploys rules that interact with the existing fontconfig ruleset.
 +
 +
{|
 +
|+ Fontconfig config file ordering
 +
|-
 +
! Prefix
 +
! Description
 +
|-
 +
| 50 || User overrides
 +
|-
 +
| 51 || Local system overrides
 +
|-
 +
| 55-59 || High priority LGC (latin greek cyrillic) fonts (distribution general-purpose default fonts)
 +
|-
 +
| 60 || Main LGC font list
 +
|-
 +
| 61-64 || Low priority LGC fonts
 +
|-
 +
| 65-69 || Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality
 +
|}
 +
 +
If you want to prioritize inbetween the prefix, you can have another number after that. e.g. 65-0-xxx.conf.
  
 
When in doubt ask the [https://admin.fedoraproject.org/pkgdb/packages/name/fontconfig Fedora fontconfig maintainer].
 
When in doubt ask the [https://admin.fedoraproject.org/pkgdb/packages/name/fontconfig Fedora fontconfig maintainer].
 +
 +
{{Anchor|xml-wrapper}}
 +
 +
=== Mandatory XML wrapper ===
 +
 +
Fontconfig configuration uses an XML dialect. The rules documented in the rest of this page '''MUST''' be inserted inside the following wrapper:
 +
 +
<pre>
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
 +
<fontconfig>
 +
  <!-- Insert your fontconfig rules here -->
 +
</fontconfig>
 +
</pre>
  
  
Line 22: Line 61:
 
You as a packager know your font is a good substitute to another one, because it has the same metrics, has been forked from the same root, etc. fontconfig unfortunately has no such knowledge. You can teach fontconfig to consider your font first when an application requests this other font by using the following rules.
 
You as a packager know your font is a good substitute to another one, because it has the same metrics, has been forked from the same root, etc. fontconfig unfortunately has no such knowledge. You can teach fontconfig to consider your font first when an application requests this other font by using the following rules.
  
=== For releases ≥ Fedora 9 ===
 
 
<pre>
 
<pre>
 
<alias binding="same">
 
<alias binding="same">
Line 31: Line 69:
 
</alias>
 
</alias>
 
</pre>
 
</pre>
 
=== For previous releases ===
 
 
<pre>
 
<match>
 
  <test name="family">
 
    <string>Name of the font to substitute for</string>
 
  </test>
 
  <edit name="family" mode="append" binding="same">
 
    <string>Name of your font</string>
 
  </edit>
 
</match>
 
</pre>
 
 
  
 
== Generic names ==
 
== Generic names ==
Line 59: Line 83:
 
</pre>
 
</pre>
  
 +
Adding this rule to your package will help fontconfig choose the right generic family to substitute glyphs from if the coverage of your font is insufficient for a run of text.
  
 
== Registering a font in default families ==
 
== Registering a font in default families ==
Line 65: Line 90:
  
 
{{Admon/warning | The following rules will change priorities for every language |
 
{{Admon/warning | The following rules will change priorities for every language |
It is strictly forbidden to use these rules, or any other rule changing priorities in default families, without consulting the [https://admin.fedoraproject.org/pkgdb/packages/name/fontconfig Fedora fontconfig maintainer] and the [[Fonts_SIG_mailing_lists| SIG list]] first.}}
+
It is strictly forbidden to pre-empt current distribution defaults without consulting the [https://admin.fedoraproject.org/pkgdb/packages/name/fontconfig Fedora fontconfig maintainer] and the [[Fonts_SIG_mailing_lists|Fonts SIG list]] first. To avoid pre-empting defaults, use high numbers in the [[Fontconfig_packaging_tips#Choosing_a_ruleset_numeral_prefix|prefix range]] appropriate for your font.}}
  
 
{{Anchor|simple-default-font-lists}}
 
{{Anchor|simple-default-font-lists}}
Line 81: Line 106:
 
</pre>
 
</pre>
  
When matching a family, fontconfig will use the first suitable font in its substitution list. Thus ''<family>'' elements within a ''<prefer>'' block are ordered by descending priority, and rulesets with low numeral prefixes take precedence over rulesets with high numeral prefixes:
+
When matching a family, fontconfig will use the first suitable font in its substitution list. Thus ''<family>'' elements within a ''<prefer>'' block are ordered by descending priority, and rulesets with low numeral prefixes take precedence over rulesets with high numeral [[#ruleset-prefix|prefixes]].
  
{|
+
{{Anchor|local-specific-default-font-overrides}}
|+ Fontconfig config file ordering
 
|-
 
! Prefix
 
! Description
 
|-
 
| 50 || User overrides
 
|-
 
| 51 || Local system overrides
 
|-
 
| 55-59 || High priority latin fonts (distribution general-purpose default fonts)
 
|-
 
| 60 || Main latin font list
 
|-
 
| 61-64 || Low priority latin fonts
 
|-
 
| 65-69 || Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality
 
|}
 
  
{{Anchor|local-specific-default-font-overrides}}
 
 
=== Locale-specific overrides ===
 
=== Locale-specific overrides ===
  
Line 121: Line 128:
 
     <string>Generic like sans-serif, serif, monospace, fantasy or cursive</string>
 
     <string>Generic like sans-serif, serif, monospace, fantasy or cursive</string>
 
   </test>
 
   </test>
   <edit name="family" mode="prepend" binding="same">
+
   <edit name="family" mode="prepend">
 
     <string>Name of your font</string>
 
     <string>Name of your font</string>
 
   </edit>
 
   </edit>
Line 137: Line 144:
 
| 65-69 || Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality
 
| 65-69 || Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality
 
|}
 
|}
 +
 +
== Auto-scaling problem fonts ==
 +
 +
Sometimes a font author designed a font around a size that just does not fit in with others. The following rule will autoscale such a font to fix the problem:
 +
 +
<pre>
 +
<match target="font">
 +
  <test name="family" compare="eq">
 +
    <string>Name of your font</string>
 +
  </test>
 +
  <edit name="matrix" mode="assign">
 +
    <times>
 +
      <name>matrix</name>
 +
      <matrix>
 +
        <double>Factor like 1.2</double> <double>0</double>
 +
        <double>0</double>  <double>Factor like 1.2</double>
 +
      </matrix>
 +
    </times>
 +
  </edit>
 +
</match>
 +
</pre>
 +
 +
== Templates and Examples ==
 +
 +
The '''fontpackages-devel''' package contains a very useful set of fontconfig file templates including documentation in the '''/usr/share/fontconfig/templates/''' directory.
  
 
{{:Fonts_SIG_signature}}
 
{{:Fonts_SIG_signature}}
 
[[Category:Fonts packaging]]
 
[[Category:Fonts packaging]]

Latest revision as of 12:39, 10 October 2018

A page of the Fonts Special Interest Group

Fontconfig directives will help you control our font substitution rules. While synthetic font compositions are not a complete substitute to good pan-unicode fonts [1], they're the next best thing. You should always consider adding fontconfig tuning to your font packages.


Important.png
Review required
Before packaging a new (custom-created or upstream-created) fontconfig ruleset, please post it on the SIG list for review.
Note.png
Code snippets only
The examples given on this page are code snippets. They won't work if you do not add the usual XML wrapper around them.

Config file considerations

Choosing a ruleset numeral prefix

Fontconfig will sort the ruleset files dropped in /etc/fonts/conf.d/ by filename before evaluating them. Therefore the rules of 01-xxx.conf and 02-yyy.conf will have the same effect a single 01-xy.conf file containing first xxx rules then yyy rules.

Usually that means the files with the smaller prefix will have higher precedence. Unfortunately the fontconfig syntax is pretty flexible and allows prepending effects to existing rules. Careful testing is therefore required if your package deploys rules that interact with the existing fontconfig ruleset.

Fontconfig config file ordering
Prefix Description
50 User overrides
51 Local system overrides
55-59 High priority LGC (latin greek cyrillic) fonts (distribution general-purpose default fonts)
60 Main LGC font list
61-64 Low priority LGC fonts
65-69 Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality

If you want to prioritize inbetween the prefix, you can have another number after that. e.g. 65-0-xxx.conf.

When in doubt ask the Fedora fontconfig maintainer.

Mandatory XML wrapper

Fontconfig configuration uses an XML dialect. The rules documented in the rest of this page MUST be inserted inside the following wrapper:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
<fontconfig>
  <!-- Insert your fontconfig rules here -->
</fontconfig>


Font substitution

You as a packager know your font is a good substitute to another one, because it has the same metrics, has been forked from the same root, etc. fontconfig unfortunately has no such knowledge. You can teach fontconfig to consider your font first when an application requests this other font by using the following rules.

<alias binding="same">
  <family>Name of the font to substitute for</family>
  <accept>
    <family>Name of your font</family>
  </accept>
</alias>

Generic names

Fontconfig is usually able to detect the font characteristics itself. Sometimes it needs a little help though:

<alias>
  <family>Name of your font</family>
  <default>
    <family>Generic like sans-serif, serif, monospace, fantasy or cursive</family>
  </default>
</alias>

Adding this rule to your package will help fontconfig choose the right generic family to substitute glyphs from if the coverage of your font is insufficient for a run of text.

Registering a font in default families

Fontconfig rules can also be used to add fonts in the substitution lists used to define synthetic default fonts like sans-serif. The effects of those rules are highly dependent on the numeral prefixes of the filenames used.

Warning.png
The following rules will change priorities for every language
It is strictly forbidden to pre-empt current distribution defaults without consulting the Fedora fontconfig maintainer and the Fonts SIG list first. To avoid pre-empting defaults, use high numbers in the prefix range appropriate for your font.

Simple priority lists

The substitution lists for default families are built using the following blocks:

<alias>
  <family>Generic like sans-serif, serif, monospace, fantasy or cursive</family>
  <prefer>
    <family>Name of your font</family>
  </prefer>
</alias>

When matching a family, fontconfig will use the first suitable font in its substitution list. Thus <family> elements within a <prefer> block are ordered by descending priority, and rulesets with low numeral prefixes take precedence over rulesets with high numeral prefixes.

Locale-specific overrides

The main default of simple substitution lists is they order whole fonts without taking the language being rendered into account. This would work fine if fonts never overlapped. All but the simplest real-world fonts, however, cover multiple scripts[2]. And the Unicode consortium itself made the dubious choice of regrouping different regional variants of some glyphs at unique codepoints.

  • If a font contains a very desirable drawing of script A, and a botched drawing of script B, you can not assign it a high priority for the sake of script A users without making script B users miserable. Since there are only so many good free/libre-open fonts, if the first group is numerous avoiding this font for the sake of the second group may not be possible.
  • Sometimes the drawing conventions of the same script are not the same in different locales, so putting any font that contains this script in a default font substitution list will make some users miserable[3]. Yet you do need to support users of this script in default fonts too.

Therefore it's very difficult to create a setup that pleases everyone using fontconfig default substitution lists only. Some locales will be sacrificed, which is not what we want. We need to complement the default lists using another method:

<match>
  <test name="lang">
    <string>Locale code like zh-cn</string>
  </test>
  <test name="family">
    <string>Generic like sans-serif, serif, monospace, fantasy or cursive</string>
  </test>
  <edit name="family" mode="prepend">
    <string>Name of your font</string>
  </edit>
</match>

This rule will override default substitution lists for a particular locale. Since it uses the prepend mode, it follows an inverted priority: rulesets with high numeral prefixes take precedence over rulesets with low numeral prefixes. If you need to ship such a rule, please use the following prefix range:

Fontconfig config file ordering, continued
Prefix Description
65-69 Fonts with less common encodings, ending with fonts that provide coverage of exotic unicode blocks at the expense of drawing quality

Auto-scaling problem fonts

Sometimes a font author designed a font around a size that just does not fit in with others. The following rule will autoscale such a font to fix the problem:

<match target="font">
  <test name="family" compare="eq">
    <string>Name of your font</string>
  </test>
  <edit name="matrix" mode="assign">
    <times>
      <name>matrix</name>
      <matrix>
        <double>Factor like 1.2</double> <double>0</double>
        <double>0</double>  <double>Factor like 1.2</double>
       </matrix>
    </times>
  </edit>
</match>

Templates and Examples

The fontpackages-devel package contains a very useful set of fontconfig file templates including documentation in the /usr/share/fontconfig/templates/ directory.


Idea.png
Fonts in Fedora
The Fonts SIG takes loving care of Fedora fonts. Please join this special interest group if you are interested in creating, improving, packaging, or just suggesting a font. Any help will be appreciated.
  1. Using them in digital documents, for example, will expose you to nasty surprises when trying to render the result on other systems
  2. Typically some script + latin, but more complex combinations are common. Users hate switching fonts when typing text so font designers will try to draw every script a target group may use in a single font.
  3. Unless a smart font that contains every regional variant of this script thanks to the locl Opentype feature is available.