diff --git a/config.c b/config.c index 8521df0..38f4fe7 100644 --- a/config.c +++ b/config.c @@ -77,6 +77,12 @@ void cDesignerConfig::SetEpgImagePath(cString path) { epgImagePathSet = true; } +bool cDesignerConfig::GetThemeColor(string &name, tColor &col) { + if (!tmplGlobals) + return false; + return tmplGlobals->GetColor(name, col); +} + void cDesignerConfig::ReadSkinFolder(cString &skinFolder, vector *container) { DIR *folder = NULL; struct dirent *dirEntry; diff --git a/config.h b/config.h index 9b6d884..2dccca6 100644 --- a/config.h +++ b/config.h @@ -58,6 +58,7 @@ public: void SetInstallerSkinPath(cString path); void SetLogoPath(cString path); void SetEpgImagePath(cString path); + bool GetThemeColor(string &name, tColor &col); void ReadSkins(void); void ReadSkinSetup(string skin); void InitSkinIterator(void) { skinIterator = skins.begin(); }; diff --git a/libcore/helpers.c b/libcore/helpers.c index 1e72dc3..bdddb66 100644 --- a/libcore/helpers.c +++ b/libcore/helpers.c @@ -149,6 +149,11 @@ bool FirstFileInFolder(string &path, string &extension, string &fileName) { return false; } +void CreateFolder(string &path) { + cString command = cString::sprintf("mkdir -p %s", path.c_str()); + system(*command); +} + // trim from start string <rim(string &s) { s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun(isspace)))); diff --git a/libcore/helpers.h b/libcore/helpers.h index cfcd70d..b370eb0 100644 --- a/libcore/helpers.h +++ b/libcore/helpers.h @@ -17,6 +17,7 @@ bool FileExists(const string &fullpath); bool FileExists(const string &path, const string &name, const string &ext); bool FolderExists(const string &path); bool FirstFileInFolder(string &path, string &extension, string &fileName); +void CreateFolder(string &path); string <rim(string &s); string &rtrim(string &s); diff --git a/libcore/imagecache.c b/libcore/imagecache.c index f9878fe..2e6a0fc 100644 --- a/libcore/imagecache.c +++ b/libcore/imagecache.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "imagecache.h" #include "cairoimage.h" @@ -42,9 +43,12 @@ void cImageCache::SetPathes(void) { iconPathTheme = *cString::sprintf("%s%s/themes/%s/", *skinPath, Setup.OSDSkin, Setup.OSDTheme); skinPartsPathTheme = *cString::sprintf("%s%s/themes/%s/skinparts/", *skinPath, Setup.OSDSkin, Setup.OSDTheme); + svgTemplatePath = *cString::sprintf("%s%s/svgtemplates/", *skinPath, Setup.OSDSkin); + dsyslog("skindesigner: using channel logo path %s", logoPath.c_str()); dsyslog("skindesigner: using icon path %s", iconPathTheme.c_str()); dsyslog("skindesigner: using skinparts path %s", skinPartsPathTheme.c_str()); + dsyslog("skindesigner: using svgtemplate path %s", svgTemplatePath.c_str()); } void cImageCache::CacheLogo(int width, int height) { @@ -381,8 +385,18 @@ bool cImageCache::LoadIcon(eImageType type, string name) { if (FileExists(*subIconSkinPath, name, "svg")) return LoadImage(*subIconSkinPath, name, "svg"); - else + else if (FileExists(*subIconSkinPath, name, "png")) return LoadImage(*subIconSkinPath, name, "png"); + + //and finally check if a svg template exists + cSVGTemplate svgTemplate(name, svgTemplatePath); + if (!svgTemplate.Exists()) + return false; + svgTemplate.ReadTemplate(); + if (!svgTemplate.ParseTemplate()) + return false; + string tmpImageName = svgTemplate.WriteImage(); + return LoadImage(tmpImageName.c_str()); } bool cImageCache::LoadLogo(const cChannel *channel) { @@ -422,8 +436,18 @@ bool cImageCache::LoadSkinpart(string name) { else if (FileExists(skinPartsPathSkin.c_str(), name, "svg")) return LoadImage(skinPartsPathSkin.c_str(), name, "svg"); - else + else if (FileExists(skinPartsPathSkin.c_str(), name, "png")) return LoadImage(skinPartsPathSkin.c_str(), name, "png"); + + //check if a svg template exists + cSVGTemplate svgTemplate(name, svgTemplatePath); + if (!svgTemplate.Exists()) + return false; + svgTemplate.ReadTemplate(); + if (!svgTemplate.ParseTemplate()) + return false; + string tmpImageName = svgTemplate.WriteImage(); + return LoadImage(tmpImageName.c_str()); } void cImageCache::Clear(void) { diff --git a/libcore/imagecache.h b/libcore/imagecache.h index e8a0365..e11f295 100644 --- a/libcore/imagecache.h +++ b/libcore/imagecache.h @@ -47,6 +47,7 @@ private: string skinPartsPathSkin; string iconPathTheme; string skinPartsPathTheme; + string svgTemplatePath; map iconCache; map channelLogoCache; map skinPartsCache; diff --git a/libcore/imageloader.c b/libcore/imageloader.c index 046cf68..1f78702 100644 --- a/libcore/imageloader.c +++ b/libcore/imageloader.c @@ -400,3 +400,102 @@ void cImageImporterJPG::GetImageSize(int &width, int &height) { height = cinfo->image_height; } } + +// +// SVG Template class +// + +cSVGTemplate::cSVGTemplate(string imageName, string templatePath) { + this->imageName = imageName; + this->templatePath = templatePath; + startTokenColor = "{sdcol("; + startTokenOpac = "{sdopac("; + endToken = ")}"; + filePath = templatePath; + filePath += imageName + ".svg"; +} + +cSVGTemplate::~cSVGTemplate(void) { +} + +bool cSVGTemplate::Exists(void) { + return FileExists(templatePath, imageName, "svg"); +} + +void cSVGTemplate::ReadTemplate(void) { + string line; + ifstream templatefile(filePath.c_str()); + if (templatefile.is_open()) { + while ( getline (templatefile, line) ) { + svgTemplate.push_back(line); + } + templatefile.close(); + } +} + +bool cSVGTemplate::ParseTemplate(void) { + int i = 0; + for (vector::iterator it = svgTemplate.begin(); it != svgTemplate.end(); it++) { + string line = *it; + size_t hit = line.find(startTokenColor); + if (hit == string::npos) { + i++; + continue; + } + size_t hitEnd = line.find(endToken, hit); + if (hitEnd == string::npos) { + return false; + } + string colorName = GetColorName(line, hit, hitEnd); + tColor replaceColor = 0x0; + if (!config.GetThemeColor(colorName, replaceColor)) { + return false; + } + ReplaceTokens(line, hit, hitEnd, replaceColor); + svgTemplate[i] = line; + i++; + } + return true; +} + +string cSVGTemplate::WriteImage(void) { + string tempPath = *cString::sprintf("/tmp/skindesigner/svg/%s/%s/", Setup.OSDSkin, Setup.OSDTheme); + CreateFolder(tempPath); + string fileName = tempPath + imageName + ".svg"; + ofstream tmpimg; + tmpimg.open (fileName.c_str(), ios::out | ios::trunc); + if (!tmpimg.is_open()) { + return ""; + } + for (vector::iterator it = svgTemplate.begin(); it != svgTemplate.end(); it++) { + tmpimg << (*it) << "\n"; + } + tmpimg.close(); + return fileName; +} + +string cSVGTemplate::GetColorName(string line, size_t tokenStart, size_t tokenEnd) { + string colorName = line.substr(tokenStart + startTokenColor.size(), tokenEnd - tokenStart - startTokenColor.size()); + if (colorName.size() > 0) { + stringstream name; + name << "{" << colorName << "}"; + return name.str(); + } + return ""; +} + +void cSVGTemplate::ReplaceTokens(string &line, size_t tokenStart, size_t tokenEnd, tColor color) { + string rgbColor = *cString::sprintf("%x", color & 0x00FFFFFF); + line.replace(tokenStart, tokenEnd - tokenStart + 2, rgbColor); + size_t hitAlpha = line.find(startTokenOpac); + if (hitAlpha == string::npos) { + return; + } + size_t hitAlphaEnd = line.find(endToken, hitAlpha); + if (hitAlphaEnd == string::npos) { + return; + } + tIndex alpha = (color & 0xFF000000) >> 24; + string svgAlpha = *cString::sprintf("%f", (float)(alpha / (float)255)); + line.replace(hitAlpha, hitAlphaEnd - hitAlpha + 2, svgAlpha); +} diff --git a/libcore/imageloader.h b/libcore/imageloader.h index 93a81ab..12bd8d2 100644 --- a/libcore/imageloader.h +++ b/libcore/imageloader.h @@ -1,6 +1,7 @@ -#ifndef __NOPACITY_IMAGELOADER_H -#define __NOPACITY_IMAGELOADER_H +#ifndef __SKINDESIGNER_IMAGELOADER_H +#define __SKINDESIGNER_IMAGELOADER_H +#include #include #include #ifndef LIBRSVG_CHECK_VERSION // Workaround for librsvg < 2.36.2 @@ -12,6 +13,8 @@ #include #include +using namespace std; + // // Image importers // @@ -85,4 +88,28 @@ public: bool LoadImage(const char *fullpath); }; -#endif //__NOPACITY_IMAGELOADER_H +// +// SVG Template class +// + +class cSVGTemplate { +private: + string imageName; + string templatePath; + string filePath; + string startTokenColor; + string startTokenOpac; + string endToken; + vector svgTemplate; + string GetColorName(string line, size_t tokenStart, size_t tokenEnd); + void ReplaceTokens(string &line, size_t tokenStart, size_t tokenEnd, tColor color); +public: + cSVGTemplate(string imageName, string templatePath); + virtual ~cSVGTemplate(void); + bool Exists(void); + void ReadTemplate(void); + bool ParseTemplate(void); + string WriteImage(void); +}; + +#endif //__SKINDESIGNER_IMAGELOADER_H