How to use fontconfig to get font list (C/C++)?

后端 未结 2 375
执念已碎
执念已碎 2021-02-06 03:40

I hear that fontconfig is the best option for getting fonts in linux. Unfortunately, I\'ve been looking through their developer documentation and I have absolutely no clue what

相关标签:
2条回答
  • 2021-02-06 04:02

    I had a similar question, and found this post (the fontconfig documentation is a little difficult to get through). MindaugasJ's response was useful, but watch out for the extra lines calling things like FcPatternPrint() or printing out the results of FcNameUnparse(). In addition, you need to add a FC_FILE argument to the list of arguments passed to FcObjectSetBuild. Something like this:

    FcConfig* config = FcInitLoadConfigAndFonts();
    FcPattern* pat = FcPatternCreate();
    FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *) 0);
    FcFontSet* fs = FcFontList(config, pat, os);
    
    printf("Total matching fonts: %d\n", fs->nfont);
    for (int i=0; fs && i < fs->nfont; ++i) {
       FcPattern* font = fs->fonts[i];
       FcChar8 *file, *style, *family;
       if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch &&
           FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch &&
           FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch)
       {
          printf("Filename: %s (family %s, style %s)\n", file, family, style);
       }
    }
    if (fs) FcFontSetDestroy(fs);
    

    I had a slightly different problem to solve in that I needed to find the font file to pass to freetype's FC_New_Face() function given some font "name". This code is able to use fontconfig to find the best file to match a name:

    FcConfig* config = FcInitLoadConfigAndFonts();
    
    // configure the search pattern, 
    // assume "name" is a std::string with the desired font name in it
    FcPattern* pat = FcNameParse((const FcChar8*)(name.c_str()));
    FcConfigSubstitute(config, pat, FcMatchPattern);
    FcDefaultSubstitute(pat);
    
    // find the font
    FcResult res;
    FcPattern* font = FcFontMatch(config, pat, &res);
    if (font)
    {
       FcChar8* file = NULL;
       if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
       {
          // save the file to another std::string
          fontFile = (char*)file;
       }
       FcPatternDestroy(font);
    }
    
    FcPatternDestroy(pat);
    
    0 讨论(0)
  • 2021-02-06 04:15

    This is not exactly what you are asking for, but it will give you the list of fonts available.

    #include <fontconfig.h>
    
    FcPattern *pat;
    FcFontSet *fs;
    FcObjectSet *os;
    FcChar8 *s, *file;
    FcConfig *config;
    FcBool result;
    int i;
    
    result = FcInit();
    config = FcConfigGetCurrent();
    FcConfigSetRescanInterval(config, 0);
    
    // show the fonts (debugging)
    pat = FcPatternCreate();
    os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, (char *) 0);
    fs = FcFontList(config, pat, os);
    printf("Total fonts: %d", fs->nfont);
    for (i=0; fs && i < fs->nfont; i++) {
        FcPattern *font = fs->fonts[i];//FcFontSetFont(fs, i);
        FcPatternPrint(font);
        s = FcNameUnparse(font);
        if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
            printf("Filename: %s", file);
        }
        printf("Font: %s", s);
        free(s);
    }
    if (fs) FcFontSetDestroy(fs);
    
    0 讨论(0)
提交回复
热议问题