[Fontconfig] How to prevent Chromium from scaling bitmapped fonts?
Kynn Jones
kynnjo at gmail.com
Wed Mar 16 16:37:00 UTC 2016
On Sat, Mar 12, 2016 at 10:08 AM, Raimund Steger <rs at mytum.de> wrote:
> On Sat, 12 Mar 2016 15:04:27 +0100
> Raimund Steger <rs at mytum.de> wrote:
>> [...]
Thank you very much for all this!
Also, pardon the "radio silence". I had a major "computer accident"
after I posted my initial question, and I've been working frantically
since to recover from that. Also, I don't understand `fontconfig`
very well, so it's taken me some time to put your suggestions into
practice.
>> FC_DEBUG tells me that Chromium first looks up Terminus with FcFontSort. Afterwards, the pixel size from the CSS is looked up with FcFontMatch but the result isn't used; what's used is the upscaled 12px version. That's really weird.
This confirms my guess.
> ...I think I need some more time to figure out what's going on here.
>
> OK I've now looked at the source and I think I get it.
>
> In Chromium's world, different font sizes can't differ in font file but only in rendering settings. That's what the FcFontMatch is for.
>
> This means you could only get around it by using a TTF wrapper that contains all of your sizes in one file.
>
> I. e. download the Terminus source and use:
>
> fonttosfnt -o terminus.ttf *n.bdf
> fonttosfnt -o terminus_bold.ttf *b.bdf
>
> Copy the resulting TTFs somewhere where fontconfig finds them.
> You might then have the problem that Chromium doesn't prefer the TTFs and still lands on the PCFs.
Indeed, that is the case: I built the *.ttf files as you suggested,
and `fc-list` finds them, but Chromium still won't use them.
> ... The more conservative approach could be to apply a rule that assigns fontformat=TrueType to the pattern if prgname=chromium.
I tried to implement this idea, but I have not managed to hit on the
right syntax.
My *starting* `fonts.conf` file (i.e. the one that I must modify in
order to implement your suggestion) consists of only one rule, which
works for most things, Chromium being the most notable exception:
<match>
<edit name="family" mode="assign"
binding="strong"><string>Terminus</string></edit>
<edit name="postscriptname" mode="assign"
binding="strong"><string>Terminus</string></edit>
<edit name="foundry" mode="assign"
binding="strong"><string>xos4</string></edit>
<edit name="fontformat" mode="assign"
binding="strong"><string>PCF</string></edit>
<edit name="scalable" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="antialias" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="outline" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="decorative" mode="assign"
binding="strong"><bool>false</bool></edit>
</match>
In order to prevent this rule from being affected by any additional
rules I put in the file, I tried adding to it the `<test>` clause
shown below, so that the rules applies only when `prgname` is *not*
`chromium`; unfortunately, this causes the rule to stop working (e.g.
on Iceweasel):
<match>
<test name="prgname" mode="not_eq"><string>chromium</string></test>
<edit name="family" mode="assign"
binding="strong"><string>Terminus</string></edit>
<!-- etc., as shown above -->
</match>
I've tried a few variations of this test clause, but they all seem to
break the containing rule.
Be that as it may, I also added the rules below, to match only when
`prgname=chromium`:
<match>
<test name="prgname" qual="all" mode="eq">
<string>chromium</string> </test>
<test name="weight" qual="all" mode="less"> <int>140</int>
</test>
<edit name="weight" mode="assign"
binding="strong"><int>100</int></edit>
<edit name="style" mode="assign"
binding="strong"><const >regular</const></edit>
<edit name="scalable" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="antialias" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="outline" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="decorative" mode="assign"
binding="strong"><bool>false</bool></edit>
<edit name="fullname" mode="assign"
binding="strong"><string>Terminus</string></edit>
<edit name="postscriptname" mode="assign"
binding="strong"><string>Terminus</string></edit>
<edit name="family" mode="assign"
binding="strong"><string>Terminus</string></edit>
<edit name="foundry" mode="assign"
binding="strong"><string>unknown</string></edit>
<edit name="fontformat" mode="assign"
binding="strong"><string>TrueType</string></edit>
<edit name="file" mode="assign"
binding="strong"><string>/usr/share/fonts/X11/terminus/ttf/terminus.ttf</string></edit>
</match>
<match>
<test name="prgname" qual="all" mode="eq">
<string>chromium</string> </test>
<test name="weight" qual="all" mode="more_eq"><int>140</int>
</test>
<edit name="weight" mode="assign"
binding="strong"><int>200</int></edit>
<!-- same as for previous -->
<edit name="file" mode="assign"
binding="strong"><string>/usr/share/fonts/X11/terminus/ttf/terminus_bold.ttf</string></edit>
</match>
...but they had no effect on Chromium. I imagine these rules fail for
the same reason that the one using the `mode="not_eq"` test on
`prgname` fails.
So I need a bit more specific instructions for implementing the
strategy that you described at the very end of your last message.
BTW, in general, is there a better way to test the syntactic
correctness of a `fonts.conf` file than by observing the effects it
may have on running applications?
Lastly, do you know of a good source of examples that illustrate the
fontconfig syntax? I've read the documentation multiple times, but I
still hardly understand at all how to configure stuff through
`fonts.conf`.
Again, thank you very much for your help!
kj
PS: FWIW, I've reported the problem with Chromium, here
https://bugs.chromium.org/p/chromium/issues/detail?id=593041
unfortunately, the issue has received scant attention.
More information about the Fontconfig
mailing list