Further details on font ranking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello!

fonts-conf(5) § FONT MATCHING gives some explanations about how
Fontconfig sorts candidate fonts in order to match a pattern:

> The canonical font pattern is finally matched against all available
> fonts.  The distance from the pattern to the font is measured for each
> of several properties: foundry, charset, family, lang, spacing, pixel-
> size, style, slant, weight, antialias, rasterizer and outline.  This
> list is in priority order -- results of comparing earlier elements of
> this list weigh more heavily than later elements.

I read fonts-conf(5) and the API manpages as attentively as I could, but
there are still a couple of points that are not clear to me:

(NB: I've attached a code snippet, annotated with comments that
     hopefully illustrate what I am getting at.  Apologies for the
     complete lack of memory cleanup)

(1) The weighing process described above takes place with FcFontMatch
    and FcFontSort, is that correct?  Meaning that given the same
    FcPattern *p, as well as:

    FcFontSet *sorted_fs = FcFontSort(NULL, p, FcFalse, NULL, &result);

    FcPattern *matched_pt = FcFontMatch(NULL, p, &result);
    FcFontSet *matched_fs = FcFontSetCreate();
    FcFontSetAdd(matched_fs, matched_pt);

    … I can then assume that matched_fs->fonts[0] ≡ sorted_fs->fonts[0]?
    (E.g. their FC_FILE attribute will point to the same font file)

(2) Does FcFontList sort its results according to a well-defined order?
    Empirically, I see that the order of the fonts returned by this
    function does not match what FcFontSort returns (cf. comments in
    attached snippet).

(3) Given two files that define the same font, say

    - /usr/share/fonts/truetype/foo.ttf: installed by the distro,
      lagging wrt its upstream developer,

    - ~/.local/share/fonts/foo.ttf: installed by the user, latest
      version from upstream,

    how will FcFontMatch, FcFontSort and FcFontList sort these files?
    Empirically, it seems that FcFontMatch and FcFontSort rank the
    user's file higher than the distro's, but I have no idea whether
    that's due to (a) the directory order in fonts.conf, (b) the font's
    :version attribute, (c) the font's coverage, (d) another
    well-defined quality of the font, or (e) sheer dumb luck.

I ran my code snippet with FC_DEBUG=7, but the "Score" lines are
identical for both files, so I'm not sure what to make of that:

> Score 0 0 0 0 0 0 0 0 0 0 1e+99 0 0 0 0 0 0 0 0 0 0 0 0 0 0

I apologize if my questions already have documented answers.  Thank you
for your time.

/* -*- compile-command: "gcc fontconfig.c -lfontconfig" -*- */

#include <assert.h>
#include <stdio.h>

#include <fontconfig/fontconfig.h>

void fontset_show(FcFontSet *fset)
{
        assert(fset->nfont > 0);
        const size_t max = 2, nfont = fset->nfont;
        printf("nfont: %zu\n", nfont);

        for (size_t i=0; i<nfont && i<max; i++) {
                FcChar8 *file;
                assert(
                        FcPatternGetString(fset->fonts[i], FC_FILE, 0, &file)
                        == FcResultMatch
                );
                printf("fset->fonts[%zu]: %s\n", i, file);
        }
}

int main()
{
        FcResult r;

        puts("* Initializing");

        puts("** FcInit");
        assert(FcInit());

        puts("** FcPatternCreate");
        FcPattern *search = FcPatternCreate();
        assert(search);
        FcValue searchval = {
                .type = FcTypeString,
                .u = {
                        .s = (const FcChar8*)"Noto Color Emoji"
                }
        };
        puts("** FcPatternAdd");
        assert(
                FcPatternAdd(search, FC_FAMILY, searchval, FcFalse)
        );

        puts("** FcObjectSetBuild");
        FcObjectSet *objs = FcObjectSetBuild(FC_FILE, NULL);
        assert(objs);

        puts("* FcFontList");
        FcFontSet *fclisted = FcFontList(NULL, search, objs);
        assert(fclisted);
        fontset_show(fclisted);
        /* Prints:
nfont: 2
fset->fonts[0]: /usr/share/fonts/truetype/NotoColorEmoji.ttf
fset->fonts[1]: /home/peniblec/.local/share/fonts/NotoColorEmoji.ttf
        */

        puts("* FcFontSort");
        FcFontSet *fcsorted = FcFontSort(NULL, search, FcFalse, NULL, &r);
        assert(r == FcResultMatch);
        assert(fcsorted);
        fontset_show(fcsorted);
        /* Prints:
nfont: 3487
fset->fonts[0]: /home/peniblec/.local/share/fonts/NotoColorEmoji.ttf
fset->fonts[1]: /usr/share/fonts/truetype/NotoColorEmoji.ttf
         */

        puts("* FcFontMatch etc");
        puts("** FcFontSetCreate");
        FcFontSet *fcmatched = FcFontSetCreate();
        assert(fcmatched);
        puts("** FcFontMatch");
        FcPattern *match = FcFontMatch(NULL, search, &r);
        assert(r == FcResultMatch);
        puts("** FcFontSetAdd");
        FcFontSetAdd(fcmatched, match);
        fontset_show(fcmatched);
        /* Prints:
nfont: 1
fset->fonts[0]: /home/peniblec/.local/share/fonts/NotoColorEmoji.ttf
         */
}

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux