Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.7.3
-
None
-
429f0507a68f4aa686449308af770ce5cf2c913f
Description
Per downstream report,
https://bugzilla.redhat.com/show_bug.cgi?id=705348
fedora is using fontconfig directives to enable freetype autohinter on a per-font basis. turns out qt doesn't handle this well, in that these end up applying globally to all displayed fonts.
In particular, ff one installs a /etc/fonts/conf.d/foo.conf that enables autohinting for a particular font family with a construct like:
<match target="font">
<test name="family" compare="eq">
<string>insert_real_font_family_here</string>
</test>
<edit name="autohint" mode="assign">
<bool>true</bool>
</edit>
</match>
The short version of the story is that Qt ends up erroneously applying this rule to (almost?) all fonts.
Per some comments in the downstream report too,
"
The way Pango is using fontconfig is completely correct and the way fontconfig
is designed to be used. In short, this is how to use fontconfig:
- Create a pattern specifying the characteristics you are looking for (ie.
"sans bold 18"). Call this pat.
- Call FcConfigSubstitute (NULL, pat, FcMatchPattern). That's where
target="pattern" configuration is applied.
- Call FcDefaultSubstitute (pat)
- Then either:
{
- Call FcFontSort (NULL, pat, ...). This will return a fontset, lets call
it fs.
- For any item in fs that you want to use (call that 'font'), you should:
- Call FcRenderPrepare (NULL, pat, font). This will implicitly call
FcConfigSubstituteWithPat (NULL, res, pat, FcMatchFont) on the pattern that it
returns. That's where target="font" configuration is applied.
- Use the resulting pattern to open the font and render it.
}
or
{ - Call FcFontMatch (NULL, pat, &result). This will return what we call a "font" pattern. It already has FcFontRenderPrepare (NULL, pat, font) called on it by FcFontMatch. }
Now! The way Qt is abusing fontconfig is:
- qt_fontSetForPattern calls FcFontSort (NULL, pat, ...) and gets the
resulting fontset 'fs' and saves it.
-
-
- Note that it should have called FcConfigSubstitute (pattern,
FcMatchPattern) and FcDefaultSubstitute (pattern) first, but it didn't.
- Note that it should have called FcConfigSubstitute (pattern,
-
- In QFontEngineMultiFT::loadEngine(), it gets font patterns out of fs, and
calls it pattern. Note that this is a target="font" kind of pattern.
- Then it calls:
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
-
-
- This is completely wrong, since pattern is a font pattern, not a query
pattern!
- This is completely wrong, since pattern is a font pattern, not a query
-
So, that's it. It's completely b0rked. Those two calls should be made before
FcFontSort(), and FcRenderPrepare called in place of those two.
"
and followup
"Ok, I digged this more. In fact, it was far far worse than I thought. The
code is stupid. It calls FcFontMatch() every other function...
I hacked up a patch together. It should improve things a lot. Can you test?
...."
which was accompanied by said patch.
I hope this can be used as a hint and good starting place for someone more familiar with the code to take this and run. Or at least, to help collaboratively find a better solution.
p.s. I submitted this prior as http://bugreports.qt.nokia.com/browse/QTBUG-19846 , which was abruptly closed due to, imo, an assumption that we were supplying a patch as-is for inclusion, rather than reporting a specific bug/problem. The basis for that assumption was largely my own fault for not including enough detail in the initial report. Hope this helps.
Attachments
Issue Links
- is required for
-
QTBUG-2148 Selective pixel size rule in FontConfig affects all fonts in Qt
- Closed