Last active
August 16, 2018 01:14
-
-
Save cfillion/1a3aeaac8df119b7c1365f14958157fb to your computer and use it in GitHub Desktop.
Font family matching with FontConfig demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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