[Fontconfig] Question about FcFontSetSort code

Jay Hobson Jay.Hobson at Sun.COM
Fri Jan 13 09:57:30 PST 2006

I've done some more digging on this, and I think that this code
has some real problems.

The values contained in nodeps[f]->score[MATCH_LANG_INDEX]
are going to be:

    0 if it was an exact match for the language
    100 if it was a language match, but possible country missmatch
    200 if it was not a match at all.

(The values returned from FcCompareLang are indeed 0, 1, or 2,
but these are multiplied by 100 before entered into score)

This code always does exact matches only up until the number
of languages requested for the set is above 100. (not realistic,
but comparing score to number of languages requested seems
odd anyway)

The basic problem with the entire loop is that if there are no
exact matches, as would be the case with ja_JP locale, then
all of the fonts are rescored to an equally bad 1000 by this
code, and fonts that don't even support the language are being
set as first priority.

Here is the code diffs to fix the problem (fix for 2.3.2 stable release):

<     int           *patternLangSat;
 >     FcBool                *patternLangSat;
<     patternLangSat = (int *) (nodeps + nnodes);
 >     patternLangSat = (FcBool *) (nodeps + nnodes);
<       patternLangSat[i] = 0;
<     /*
<      * For Solaris, because of ja_JP, en_US, and such locales, exact 
<      * with font language support is sporatic.
<      */
 >       patternLangSat[i] = FcFalse;
<       if (nodeps[f]->score[MATCH_LANG_INDEX] <= 100 )
 >       if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang)
<               if (patternLangSat[i] != 1 &&
 >               if (!patternLangSat[i] &&
<                   if (compare >= 0 && compare < 2 && ( 
patternLangSat[i] == 0 || compare + 1 < patternLangSat[i]))
 >                   if (compare >= 0 && compare < 2)
<                       patternLangSat[i] = (int)compare + 1;
 >                       patternLangSat[i] = FcTrue;

This fix basically retains the information about exact vs. close match 
by using an int instead of a bool, and allows a close match to be stored 
if no exact match exists. If an exact match shows up later in the list, 
then store it also.


Keith Packard wrote:

>On Wed, 2006-01-11 at 13:49 -0800, Jay Hobson wrote:
>>I'm looking at the FcFontSetSort code in fcmatch.c, line 893
>>in 2.3.93:
>> if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang)
>>Isn't this an apples to oranges comparison?
>I'm trying to remember what this does; my recollection is that this
>comparison allows for exact matches among any of the requested languages
>to be equivalent to an exact match for the first language; note that
>scores are increased by one each time the match is further along in the
>This means that a pattern of the form 'en,ja' will exactly match a 'ja'
>I don't exactly recall the details though. I do know that locales on
>essentially all other systems are of a similar form though, so any
>issues you're seeing on Solaris should be present on Linux, BSD and
>other systems.
>Fontconfig mailing list
>Fontconfig at lists.freedesktop.org

More information about the Fontconfig mailing list