How to use fontconfig to get a list of fonts (C / C ++)?

I heard fontconfig is the best option for getting fonts on Linux. Unfortunately, I was looking through the documentation of the developers, and I absolutely do not understand what I am doing. It would seem that there is no simple function to get a list of system fonts. Instead, I have to do a pattern search ... right?

In short, what is the best way to get a list of true type fonts (their family, face and directory) using fontconfig? Of course, if there is something better than fontconfig, I am certainly open to other solutions.

+7
source share
2 answers

I had a similar question and I found this post (fontconfig documentation is a bit complicated to go through). MindaugasJ's answer was useful, but make sure that extra lines call things like FcPatternPrint() or print the results of FcNameUnparse() . In addition, you need to add the FC_FILE argument to the list of arguments passed to FcObjectSetBuild . Something like that:

 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 that I needed to find a font file to go to the freetype FC_New_Face() function, given some font "name". This code is able to use fontconfig to find the best file according to the 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 FcPattern* font = FcFontMatch(config, pat, NULL); 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); 
+8
source

This is not what you are asking for, but it will provide you with a list of available fonts.

 #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); 
+4
source

All Articles