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 | |
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!
-rw-r--r-- | Make.config | 3 | ||||
-rw-r--r-- | glcdskin/Makefile | 4 | ||||
-rw-r--r-- | glcdskin/font.c | 100 | ||||
-rw-r--r-- | glcdskin/font.h | 3 |
4 files changed, 102 insertions, 8 deletions
diff --git a/Make.config b/Make.config index a14fd18..5ff6534 100644 --- a/Make.config +++ b/Make.config @@ -54,6 +54,9 @@ DEFINES += -D_GNU_SOURCE # comment this variable out if you don't want to use FreeType2 font rendering HAVE_FREETYPE2=1 +# comment this variable out if you don't want to use fontconfig font names +HAVE_FONTCONFIG=1 + # uncomment one of the following two lines if you want either GraphicsMagick/ImageMagick support #HAVE_IMAGEMAGICK=1 #HAVE_GRAPHICSMAGICK=1 diff --git a/glcdskin/Makefile b/glcdskin/Makefile index d7f3520..7dcee7f 100644 --- a/glcdskin/Makefile +++ b/glcdskin/Makefile @@ -23,6 +23,10 @@ HEADERS = cache.h config.h display.h font.h function.h object.h parser.h skin.h ### Inner graphlcd-base dependencies LIBS += -L../glcdgraphics -lglcdgraphics -L../glcddrivers -lglcddrivers +ifdef HAVE_FONTCONFIG + LIBS += -lfontconfig + DEFINES += -DHAVE_FONTCONFIG +endif ### Implicit rules: 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; } } diff --git a/glcdskin/font.h b/glcdskin/font.h index d11fa50..80e5556 100644 --- a/glcdskin/font.h +++ b/glcdskin/font.h @@ -49,8 +49,11 @@ private: cSkinDisplay mDummyDisplay; cSkinObject mDummyObject; + static int FcInitCount; + public: cSkinFont(cSkin * Parent); + ~cSkinFont(void); bool ParseUrl(const std::string & Text); bool ParseCondition(const std::string & Text); |