summaryrefslogtreecommitdiff
path: root/glcdskin/font.c
diff options
context:
space:
mode:
authormrwastl <mrwastl@users.sourceforge.net>2012-06-16 16:30:44 +0200
committermrwastl <mrwastl@users.sourceforge.net>2012-06-16 16:30:44 +0200
commit433faa596510971f78a73c44b8152166e5774df8 (patch)
treee7c9ad8b092bddb22342413add070d89aca9487d /glcdskin/font.c
parent6ce1975169f81c113b343b67821554062d2859e9 (diff)
downloadgraphlcd-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.c100
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;
}
}