Skip to content

Instantly share code, notes, and snippets.

@CallumDev
Created January 21, 2015 14:08
Show Gist options
  • Save CallumDev/7c66b3f9cf7a876ef75f to your computer and use it in GitHub Desktop.
Save CallumDev/7c66b3f9cf7a876ef75f to your computer and use it in GitHub Desktop.
FontConfig sample in C
//compiled gcc fonttest.c -o fonttest -lfontconfig
//Sample output: /usr/share/fonts/steam-fonts/arial.ttf
#include <stdio.h>
#include <stdlib.h>
#include <fontconfig/fontconfig.h>
int main()
{
FcConfig* config = FcInitLoadConfigAndFonts();
//make pattern from font name
FcPattern* pat = FcNameParse((const FcChar8*)"Arial");
FcConfigSubstitute(config, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
char* fontFile; //this is what we'd return if this was a function
// find the font
FcResult result;
FcPattern* font = FcFontMatch(config, pat, &result);
if (font)
{
FcChar8* file = NULL;
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
{
//we found the font, now print it.
//This might be a fallback font
fontFile = (char*)file;
printf("%s\n",fontFile);
}
}
FcPatternDestroy(pat);
return 0;
}
@Rickodesea
Copy link

Thanks for this. But you need to also call FcInit() at the beginning and FcFini() at the end. Also, you need to call FcConfigDestroy(config) to free the config memory and FcPatternDestroy(font) to free the font memory.

//Reference
//https://www.freedesktop.org/software/fontconfig/fontconfig-devel/x103.html#AEN3038

Example:

#include <stdio.h>
#include <stdlib.h>
#include <fontconfig/fontconfig.h>
int main()
{
	FcInit(); //initializes Fontconfig
	FcConfig* config = FcInitLoadConfigAndFonts(); //Most convenient of all the alternatives

	//does not necessarily has to be a specific name.  You could put anything here and Fontconfig WILL find a font for you
	FcPattern* pat = FcNameParse((const FcChar8*)"Arial");

	FcConfigSubstitute(config, pat, FcMatchPattern);//NECESSARY; it increases the scope of possible fonts
	FcDefaultSubstitute(pat);//NECESSARY; it increases the scope of possible fonts

	char* fontFile;
	FcResult result;

	FcPattern* font = FcFontMatch(config, pat, &result);

	if (font)
	{
		//The pointer stored in 'file' is tied to 'font'; therefore, when 'font' is freed, this pointer is freed automatically.
		//If you want to return the filename of the selected font, pass a buffer and copy the file name into that buffer
		FcChar8* file = NULL; 

		if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
		{
			fontFile = (char*)file;
			printf("%s\n",fontFile);
		}
	}
	FcPatternDestroy(font);//needs to be called for every pattern created; in this case, 'fontFile' / 'file' is also freed
	FcPatternDestroy(pat);//needs to be called for every pattern created
	FcConfigDestroy(config);//needs to be called for every config created
	FcFini();//uninitializes Fontconfig
        return 0;
}

@1baifeng1
Copy link

It's a good example. Do I need to add FcConfigDestroy(config); for every FcConfigGetCurrent()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment