diff options
author | mrwastl <mrwastl@users.sourceforge.net> | 2012-06-16 16:30:44 +0200 |
---|---|---|
committer | mrwastl <mrwastl@users.sourceforge.net> | 2012-06-16 16:30:44 +0200 |
commit | 433faa596510971f78a73c44b8152166e5774df8 (patch) | |
tree | e7c9ad8b092bddb22342413add070d89aca9487d /glcdskin/font.c | |
parent | 6ce1975169f81c113b343b67821554062d2859e9 (diff) | |
download | graphlcd-base-433faa596510971f78a73c44b8152166e5774df8.tar.gz graphlcd-base-433faa596510971f78a73c44b8152166e5774df8.tar.bz2 |
added support for fontconfig font name representations (eg.: <font id="FontInfo" url="fc:Sans Serif:bold:size=12"/>). Attention: specifying a size term (eg. 'size=12') is mandatory!
Diffstat (limited to 'glcdskin/font.c')
-rw-r--r-- | glcdskin/font.c | 100 |
1 files changed, 92 insertions, 8 deletions
diff --git a/glcdskin/font.c b/glcdskin/font.c index 731b1fa..47f211a 100644 --- a/glcdskin/font.c +++ b/glcdskin/font.c @@ -6,9 +6,16 @@ #include "skin.h" #include "function.h" +#ifdef HAVE_FONTCONFIG + #include <fontconfig/fontconfig.h> +#endif + namespace GLCD { +int cSkinFont::FcInitCount = 0; + + cSkinFont::cSkinFont(cSkin * Parent) : mSkin(Parent), mCondition(NULL), @@ -17,36 +24,113 @@ cSkinFont::cSkinFont(cSkin * Parent) { } +cSkinFont::~cSkinFont(void) { +#ifdef HAVE_FONTCONFIG + cSkinFont::FcInitCount --; + if (cSkinFont::FcInitCount <= 0) { + FcFini(); + } +#endif +} + bool cSkinFont::ParseUrl(const std::string & url) { - std::string::size_type count = std::string::npos; + bool isFontconfig = false; + std::string rawfont = ""; if (url.find("fnt:") == 0) { mType = ftFNT; + rawfont = url.substr(4); mSize = 0; } else if (url.find("ft2:") == 0) { mType = ftFT2; - std::string::size_type pos = url.find(":", 4); + rawfont = url.substr(4); + std::string::size_type pos = rawfont.find(":"); if (pos == std::string::npos) { syslog(LOG_ERR, "cFontElement::Load(): No font size specified in %s\n", url.c_str()); return false; } - std::string tmp = url.substr(pos + 1); + std::string tmp = rawfont.substr(pos + 1); mSize = atoi(tmp.c_str()); - count = pos - 4; + rawfont = rawfont.substr(0,pos); } +#ifdef HAVE_FONTCONFIG + else if (url.find("fc:") == 0) + { + mType = ftFT2; + isFontconfig = true; + rawfont = url.substr(3); + + std::string::size_type pos = rawfont.find(":size="); + if (pos == std::string::npos) { + syslog(LOG_ERR, "cFontElement::Load(): No font size specified in %s (e.g.: 'size=<fontsize>')\n", url.c_str()); + return false; + } + std::string sizeterm = rawfont.substr(pos + 1); + + pos = sizeterm.find(":"); // find terminating : + if (pos != std::string::npos) { + sizeterm = sizeterm.substr(0, pos); + } + + pos = sizeterm.find("="); + if (pos == std::string::npos) { + syslog(LOG_ERR, "cFontElement::Load(): Invalid size term '%s' (must be 'size=<fontsize>')\n", url.c_str()); + return false; + } + + std::string tmp = sizeterm.substr(pos + 1); + mSize = atoi(tmp.c_str()); + if (mSize <= 0) { + syslog(LOG_ERR, "cFontElement::Load(): Invalid font size in '%s'\n", url.c_str()); + return false; + } + + if (cSkinFont::FcInitCount <= 0) { + FcInit(); + } + cSkinFont::FcInitCount ++; + + FcPattern *pat = FcNameParse((FcChar8 *) rawfont.c_str() ); + rawfont = ""; + FcPatternAddBool(pat, FC_SCALABLE, FcTrue); + FcConfigSubstitute(NULL, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL); + if (fontset) { + FcBool scalable; + for (int i = 0; i < fontset->nfont; i++) { + FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable); + if (scalable) { + FcChar8 *s = NULL; + FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s); + rawfont = (char *)s; // set font path + break; + } + } + FcFontSetDestroy(fontset); + } + FcPatternDestroy(pat); + + if (rawfont == "") { + syslog(LOG_ERR, "cFontElement::Load(): No usable font found for '%s'\n", url.c_str()); + return false; + } + } +#endif else { syslog(LOG_ERR, "cSkinFont::ParseUrl(): Unknown font type in %s\n", url.c_str()); return false; } - if (url[4] == '/' || url.find("./") == 4 || url.find("../") == 4) - mFile = url.substr(4, count); + if (isFontconfig || (rawfont[0] == '/' || rawfont.find("./") == 0 || rawfont.find("../") == 0)) { + mFile = rawfont; + } else { // first try skin's font dir @@ -57,7 +141,7 @@ bool cSkinFont::ParseUrl(const std::string & url) mFile += '/'; } mFile += "fonts/"; - mFile += url.substr(4, count); + mFile += rawfont; #if (__GNUC__ < 3) std::ifstream f(mFile.c_str(), std::ios::in | std::ios::binary); #else @@ -76,7 +160,7 @@ bool cSkinFont::ParseUrl(const std::string & url) if (mFile[mFile.length() - 1] != '/') mFile += '/'; } - mFile += url.substr(4, count); + mFile += rawfont; } } |