Please add add <group> → <match> → <good-lang>
This is a part of: #200
Purpose
The good-lang
element in a match
block is used to declare locales, a set of font files is definitely suitable for.
Proposed syntax
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- SPDX-License-Identifier: MIT -->
<fontconfig>
<group>
<target>@canonical_family_name@</target>
<match>
<family>@technical_family_name@</family>
<good-lang>@good_lang_tag@</good-lang>
</match>
</group>
</fontconfig>
Behaviour
good-lang
promotes the corresponding font files, over other matching font files, when assembling @canonical_family_name@
for the @good_lang_tag@
locale.
It also demotes those font files, after other matching font files, when assembling @canonical_family_name@
for any other locale, that overlaps with @good_lang_tag@
, unless they are also tagged with this other locale via another good-lang
element.
Tagging files that already match @canonical_family_name@
, with @good_lang_tag@
, can be done with a specific match
block inside group
.
Substitution
good-lang
also affects substitution. Families, that include elements with the correct good-lang
tag, are promoted over families that do not, in the substitution list defined in #194
They are still lower priority than the family own font files (target
+ family
+ match
blocks within group
). It is not possible for a substitution font family to override part of the assembled font family, even if it explicitly tagged with a lang, and the assembled family files are not.
There should be no need to tag families with a particular good-lang
in substitution lists (like
). The good-lang
s declared in their own group
block should be sufficient both for themselves, and when used as substitutes.
Past alternatives
The canonical way to achieve this result now is the following. However, this pattern is highly susceptible to ordering mistakes, and does not play well with substitutions.
<match>
<test name="lang" compare="contains">
<string>@good_lang_tag@</string>
</test>
<test name="family">
<string>@technical_family_name@</string>
</test>
<edit name="family" mode="prepend">
<string>@canonical_family_name@</string>
</edit>
</match>
A recently proposed alternative would be to use:
<match target="scan">
<test name="family">
<string>font name</string>
</test>
<edit name="lang" mode="assign">
<minus>
<name>lang</name>
<langset>
<string>@bad_lang_tag@</string>
...
</langset>
</minus>
</edit>
</match>
However:
- that rule is negative (and fonts are added to a system to support specific
lang
s, not to break others), - does not make use of fontconfig’s knowledge of overlapping locales,
- it completely voids a lang instead of just promoting known-good files.
Both of those patterns are overly verbose and do not present lang
overrides in the context of the target font family.
Minimal real-world example
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- SPDX-License-Identifier: MIT -->
<fontconfig>
<group>
<target>Noto Sans UI</target>
<match>
<family>Noto Sans Devanagari UI</family>
<good-lang>hi</good-lang>
<good-lang>mr</good-lang>
</match>
<match>
<family>Noto Sans Khmer UI</family>
<good-lang>km</good-lang>
</match>
</group>
</fontconfig>