Force font selection for a given character range
As per this answer on StackOverflow, I have this snippet in my ~/.config/fontconfig/fonts.conf:
<match target="scan">
<test name="family" compare="not_eq">
<string>Source Han Serif</string>
</test>
<edit name="charset" mode="assign">
<minus>
<name>charset</name>
<charset>
<range>
<int>0x3040</int>
<int>0x309F</int>
</range>
</charset>
</minus>
</edit>
</match>
What I want is to always render hiragana using Source Han Serif unless a specific font is requested. If every font except Source Han Serif has the characters 0x3040-0x309F removed, then it should select that font whenever that character is requested, correct? However:
$ fc-match -s ":charset=3041" | grep -i source
SourceHanSans-Regular.ttc: "Source Han Sans" "Regular"
SourceSansVariable-Roman.otf: "Source Sans Variable" "Regular"
SourceSansVariable-Italic.otf: "Source Sans Variable" "Italic"
SourceCodePro-Regular.otf: "Source Code Pro" "Regular"
SourceSerifVariable-Roman.otf: "Source Serif Variable" "Regular"
Oddly enough, Han Serif it is not even there. But Han Sans should not be in there, since it does not have that character range, correct?
$ fc-match -v ":charset=3041" | grep -e family: -e charset: -e 0030:
family: "Source Han Sans"(s) "源ノ角ゴシック"(s)
charset:
0030: ffffffff ffffffff fffffffe ffffffff fe7fffff ffffffff ffffffff ffffffff
So why does it have those characters? I can see they are removed when scanning:
$ FC_DEBUG=$((1|2|4|8|16|32|64|128|256|1024|2048|4096)) fc-cache -r 2>&1
Scanning file /usr/share/fonts/adobe-source-han-sans/SourceHanSans-Regular.ttc...
FcConfigSubstitute Pattern has 25 elts (size 32)
family: "Source Han Sans"(s) "源ノ角ゴシック"(s)
[...]
charset:
[...]
0030: ffffffff ffffffff fffffffe ffffffff fe7fffff ffffffff ffffffff ffffffff
[...]
Rule Set: /home/rzl/.config/fontconfig/fonts.conf
FcConfigSubstitute test scan any family NotEqual "Source Han Serif"
Substitute Edit charset Assign charset Minus charset
Append list before [marker]
Append list after
[...]
0030: ffffffff ffffffff 00000000 00000000 00000000 ffffffff ffffffff ffffffff
[...]
(w)
FcConfigSubstitute editPattern has 25 elts (size 32)
family: "Source Han Sans"(s) "源ノ角ゴシック"(s)
[...]
charset:
[...]
0030: ffffffff ffffffff 00000000 00000000 00000000 ffffffff ffffffff ffffffff
[...]
(w)
[...]
Final font pattern:
Pattern has 25 elts (size 32)
family: "Source Han Sans"(s) "源ノ角ゴシック"(s)
familylang: "en"(s) "ja"(s)
style: "Regular"(s)
stylelang: "en"(s)
fullname: "Source Han Sans"(s) "源ノ角ゴシック"(s)
fullnamelang: "en"(s) "ja"(s)
slant: 0(i)(s)
weight: 80(f)(s)
width: 100(f)(s)
foundry: "ADBO"(s)
file: "/usr/share/fonts/adobe-source-han-sans/SourceHanSans-Regular.ttc"(s)
index: 0(i)(s)
outline: True(s)
scalable: True(s)
charset:
[...]
0030: ffffffff ffffffff 00000000 00000000 00000000 ffffffff ffffffff ffffffff
[...]
(w)
lang: aa|ay|bg|bi|bin|br|ch|da|de|en|es|eu|fj|fo|fur|fy|gd|gl|gn|gv|haw|ho|ia|ig|id|ie|io|is|it|ja|ki|ko|kum|lb|mg|nb|nds|nl|nn|no|nr|oc|om|os|pt|rm|ru|sel|sm|sma|smj|so|sq|ss|st|sv|sw|tl|to|ts|uz|vo|wa|xh|yap|zh-cn|zh-hk|zh-mo|zh-sg|zh-tw|zu|an|fil|ht|jv|kj|kwm|li|ms|na|ng|pap-an|pap-aw|rn|rw|sc|sg|sn|su|za(s)
fontversion: 131137(i)(s)
capability: "otlayout:DFLT otlayout:cyrl otlayout:grek otlayout:hang otlayout:hani otlayout:kana otlayout:latn"(s)
fontformat: "CFF"(s)
decorative: False(s)
postscriptname: "SourceHanSans-Regular"(s)
color: False(s)
symbol: False(s)
variable: False(s)
fonthashint: False(s)
Am I misunderstanding how this is supposed to work? I know I can force one single character to use a certain font thus:
<match target="pattern">
<test name="charset" compare="eq">
<charset>
<int>0x3040</int>
</charset>
</test>
<edit name="family" mode="prepend">
<string>Source Han Serif</string>
</edit>
</match>
But listing all characters in this way would not be fun, given that there is no "in" comparison, nor there seems to be a way to or
tests. Is this the intended way to do it?