How to use FcFontMatch to find a font with a given character

Elias MÃ¥rtenson <[email protected]> Fri, 29 Jun 2018 18:12:40 +0800
Newsgroups gmane.comp.fonts.fontconfig
Message-ID <CADtN0W+CN-oPJg4Tms+Az2=NkX8JHv6jMzqeDDKW=wJFX7ce1Q@mail.gmail.com>
Hello,

I am currently implementing character replacement in McCLIM
<https://github.com/McCLIM/McCLIM> (if a character is missing from the
font, pick a different font that has the character).

I observe that FcFontMatch returns some unexpected values.

The code is written in Lisp, but I wrote a simple C program that replicates
the behaviour. The program simply attempts to find a font that contains the
character U+063A.

When I use FcMatchPattern, the program returns DejaVuSans.ttf. If I use
FcMatchFont instead, it returns FreeMono.ttf.

The interesting thing is that none of these fonts actually contains U+0x63A
(checked by reading the "charset" value).

What is the correct way to perform this operation?

A second question: What is the actual difference between FcMatchPattern and
FcMatchFont? The documentation isn't very clear on that.

Regards,
Elias

The test program follows:

#include <fontconfig/fontconfig.h>
#include <stdio.h>
#include <stdlib.h>

void checkError(FcBool result) {
    if(!result) {
        fprintf(stderr, "error from fontconfig call\n");
        abort();
    }
}

int main(void)
{
    FcConfig *config = FcInitLoadConfigAndFonts();

    FcPattern *pattern = FcPatternCreate();

    FcCharSet *charset = FcCharSetCreate();
    checkError(FcCharSetAddChar(charset, 0x63a));
    checkError(FcPatternAddCharSet(pattern, "charset", charset));
    FcCharSetDestroy(charset);

    checkError(FcConfigSubstitute(config, pattern, FcMatchPattern));

    FcDefaultSubstitute(pattern);

    FcResult result;
    FcPattern *resultPattern = FcFontMatch(config, pattern, &result);
    if(result != FcResultMatch) {
        fprintf(stderr, "no fonts matched\n");
        return 1;
    }

    FcValue value;
    FcResult patternResult = FcPatternGet(resultPattern, "file", 0, &value);
    if(patternResult != FcResultMatch) {
        fprintf(stderr, "file value not found\n");
        return 1;
    }

    if(value.type != FcTypeString) {
        fprintf(stderr, "expected to find a string value\n");
        return 1;
    }

    printf("font file = %s\n", value.u.s);

    FcPatternDestroy(pattern);

    return 0;
}

_______________________________________________
Fontconfig mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/fontconfig