Skip to content

Instantly share code, notes, and snippets.

@cfillion
Last active August 16, 2018 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cfillion/1a3aeaac8df119b7c1365f14958157fb to your computer and use it in GitHub Desktop.
Save cfillion/1a3aeaac8df119b7c1365f14958157fb to your computer and use it in GitHub Desktop.
Font family matching with FontConfig demo
// c++ -lfontconfig fctest.cpp
// ./a.out 'DejaVu Sans Mono' monospace 'Andale Mono' 'Ubuntu Mono' Lato
#include <cstdio>
#include <fontconfig/fontconfig.h>
class FontConfig {
public:
FontConfig() : m_config(FcInitLoadConfigAndFonts()) {}
FontConfig(const FontConfig &) = delete;
~FontConfig() { FcConfigDestroy(m_config); }
operator FcConfig *() { return m_config; }
private:
FcConfig *m_config;
};
class FontPattern {
public:
FontPattern(FcPattern *p = FcPatternCreate()) : m_pattern(p) {}
FontPattern(const FontPattern &) = delete;
~FontPattern() { FcPatternDestroy(m_pattern); }
operator bool() const { return m_pattern; }
template<typename T> T get(const char *object, int n = 0) const;
template<typename T> bool add(const char *object, T val);
FontPattern bestMatch(FcConfig * = nullptr);
private:
FcPattern *m_pattern;
};
template<>
const char *FontPattern::get(const char *object, const int n) const {
FcChar8 *value;
if(FcPatternGetString(m_pattern, object, n, &value) == FcResultMatch)
return reinterpret_cast<const char *>(value);
return nullptr;
}
template<>
bool FontPattern::add(const char *object, const char *val) {
return FcPatternAddString(m_pattern, object, reinterpret_cast<const FcChar8 *>(val));
}
template<>
bool FontPattern::add(const char *object, const int val) {
return FcPatternAddInteger(m_pattern, object, val);
}
FontPattern FontPattern::bestMatch(FcConfig *cfg) {
FcConfigSubstitute(cfg, m_pattern, FcMatchPattern);
FcDefaultSubstitute(m_pattern);
FcResult result;
return {FcFontMatch(cfg, m_pattern, &result)};
}
int main(const int argc, const char *argv[]) {
FontConfig fc;
for(int i = 1; i < argc; ++i) {
FontPattern query;
query.add(FC_FAMILY, argv[i]);
// query.add(FC_WEIGHT, FC_WEIGHT_BOLD);
// query.add(FC_SLANT, FC_SLANT_ITALIC);
// ...
const FontPattern &font = query.bestMatch(fc);
if(font) {
printf("found font matching '%s': '%s' in '%s'\n", argv[i],
font.get<const char *>(FC_FAMILY), font.get<const char *>(FC_FILE));
}
else
printf("no font matching '%s' found\n", argv[i]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment