如何使用fontconfig获取字体列表(C/C++)?

Azm*_*sov 8 c c++ truetype

我听说fontconfig是在linux中获取字体的最佳选择.不幸的是,我一直在查看他们的开发人员文档,我完全不知道我在做什么.看来没有简单的函数来获取系统字体列表.我必须执行模式搜索......对吗?

简而言之,使用fontconfig获取真实字体(它们的族,面和目录)列表的最佳方法是什么?当然,如果有比fontconfig更好的东西,我肯定会接受其他解决方案.

Sco*_*ter 10

我有一个类似的问题,并发现这篇文章(fontconfig文档有点难以通过).MindaugasJ的反应非常有用,但请注意额外的线路调用FcPatternPrint()或打印出的结果FcNameUnparse().此外,您需要在FC_FILE传递给的参数列表中添加一个参数FcObjectSetBuild.像这样的东西:

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);
Run Code Online (Sandbox Code Playgroud)

我有一个稍微不同的问题要解决,我需要找到字体文件传递给freetype的FC_New_Face()函数给定一些字体"名称".此代码能够使用fontconfig查找与名称匹配的最佳文件:

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);
Run Code Online (Sandbox Code Playgroud)

  • 您的第二个代码示例是非法的,因为它在“FcFontMatch(config, pat, NULL)”中传递了一个 NULL 指针,该指针将被取消引用并写入。断言在 fontconfig 的调试版本中进行,但不在发布版本中。请解决这个问题!https://cgit.freedesktop.org/fontconfig/tree/src/fcmatch.c#n779 (2认同)

小智 5

这并不完全是您要的,但是它将为您提供可用字体的列表。

#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);
Run Code Online (Sandbox Code Playgroud)