diff --git a/Makefile b/Makefile index 8277229..e3c9144 100644 --- a/Makefile +++ b/Makefile @@ -44,8 +44,8 @@ DEFINES += $(shell xml2-config --cflags) INCLUDES += $(shell pkg-config --cflags freetype2 fontconfig) -INCLUDES += $(shell pkg-config --cflags cairo-png) -LIBS += $(shell pkg-config --libs cairo-png) +INCLUDES += $(shell pkg-config --cflags librsvg-2.0 cairo-png) +LIBS += $(shell pkg-config --libs librsvg-2.0 cairo-png) LIBS += $(shell xml2-config --libs) diff --git a/libcore/imagecache.c b/libcore/imagecache.c index 7c96438..62691e6 100644 --- a/libcore/imagecache.c +++ b/libcore/imagecache.c @@ -311,18 +311,17 @@ cImage *cImageCache::GetSkinpart(string name, int width, int height) { } bool cImageCache::LoadIcon(eImageType type, string name) { - bool success = false; cString subdir(""); if (type == itMenuIcon) subdir = "menuicons"; else if (type == itIcon) subdir = "icons"; cString subIconPath = cString::sprintf("%s%s/", iconPath.c_str(), *subdir); - success = LoadImage(name, *subIconPath, "png"); - if (success) { - return true; - } - return false; + + if (FileExists(*subIconPath, name, "svg")) + return LoadImage(*subIconPath, name, "svg"); + else + return LoadImage(*subIconPath, name, "png"); } bool cImageCache::LoadLogo(const cChannel *channel) { @@ -331,32 +330,27 @@ bool cImageCache::LoadLogo(const cChannel *channel) { string channelID = StrToLowerCase(*(channel->GetChannelID().ToString())); string logoLower = StrToLowerCase(channel->Name()); bool success = false; - success = LoadImage(channelID.c_str(), logoPath.c_str(), *config.logoExtension); - if (success) - return true; - success = LoadImage(logoLower.c_str(), logoPath.c_str(), *config.logoExtension); - if (success) - return true; + + if (FileExists(logoPath.c_str(), channelID.c_str(), *config.logoExtension)) + return LoadImage(logoPath.c_str(), channelID.c_str(), *config.logoExtension); + + if (FileExists(logoPath.c_str(), logoLower.c_str(), *config.logoExtension)) + return LoadImage(logoPath.c_str(), logoLower.c_str(), *config.logoExtension); + return false; } bool cImageCache::LoadSeparatorLogo(string name) { cString separatorPath = cString::sprintf("%sseparatorlogos/", logoPath.c_str()); string nameLower = StrToLowerCase(name.c_str()); - bool success = false; - success = LoadImage(nameLower.c_str(), *separatorPath, *config.logoExtension); - if (success) - return true; - return false; + return LoadImage(*separatorPath, nameLower.c_str(), *config.logoExtension); } bool cImageCache::LoadSkinpart(string name) { - bool success = false; - success = LoadImage(name, skinPartsPath.c_str(), "png"); - if (success) { - return true; - } - return false; + if (FileExists(skinPartsPath.c_str(), name, "svg")) + return LoadImage(skinPartsPath.c_str(), name, "svg"); + else + return LoadImage(skinPartsPath.c_str(), name, "png"); } void cImageCache::Clear(void) { diff --git a/libcore/imageloader.c b/libcore/imageloader.c index 0c20fda..bb88b70 100644 --- a/libcore/imageloader.c +++ b/libcore/imageloader.c @@ -41,7 +41,6 @@ cImage *cImageLoader::CreateImage(int width, int height, bool preserveAspect) { cairo_scale(cr, sx, sy); importer->DrawToCairo(cr); - cairo_paint(cr); cairo_status_t status = cairo_status(cr); if (status) @@ -51,6 +50,7 @@ cImage *cImageLoader::CreateImage(int width, int height, bool preserveAspect) { cImage *image = new cImage(cSize(width, height), (tColor*)data); cairo_destroy(cr); + cairo_surface_destroy(surface); return image; } @@ -67,6 +67,8 @@ bool cImageLoader::LoadImage(const char *fullpath) { if (endswith(fullpath, ".png")) importer = new cImageImporterPNG; + else if (endswith(fullpath, ".svg")) + importer = new cImageImporterSVG; else return false; @@ -74,7 +76,7 @@ bool cImageLoader::LoadImage(const char *fullpath) { } // Just a different way to call LoadImage. Calls the above one. -bool cImageLoader::LoadImage(std::string FileName, std::string Path, std::string Extension) { +bool cImageLoader::LoadImage(std::string Path, std::string FileName, std::string Extension) { std::stringstream sstrImgFile; sstrImgFile << Path << FileName << "." << Extension; std::string imgFile = sstrImgFile.str(); @@ -147,8 +149,10 @@ bool cImageImporterPNG::LoadImage(const char *path) { } void cImageImporterPNG::DrawToCairo(cairo_t *cr) { - if (surface) + if (surface) { cairo_set_source_surface(cr, surface, 0, 0); + cairo_paint(cr); + } } void cImageImporterPNG::GetImageSize(int &width, int &height) { @@ -157,3 +161,51 @@ void cImageImporterPNG::GetImageSize(int &width, int &height) { height = cairo_image_surface_get_height(surface); } } + +// +// Image importer for SVG +// + +cImageImporterSVG::cImageImporterSVG() { + handle = NULL; +} + +cImageImporterSVG::~cImageImporterSVG() { + if (handle) { + rsvg_handle_close(handle, NULL); + g_object_unref(handle); + } +} + +bool cImageImporterSVG::LoadImage(const char *path) { + if (handle) { + rsvg_handle_close(handle, NULL); + g_object_unref(handle); + } + + GError *error = NULL; + handle = rsvg_handle_new_from_file(path, &error); + if (!handle) { + if (config.debugImageLoading) + dsyslog("skindesigner: RSVG Error: %s", error->message); + return false; + } + + rsvg_handle_set_dpi(handle, 90); + + return true; +} + +void cImageImporterSVG::DrawToCairo(cairo_t *cr) { + if (handle) + rsvg_handle_render_cairo(handle, cr); +} + +void cImageImporterSVG::GetImageSize(int &width, int &height) { + if (handle) { + RsvgDimensionData dim; + rsvg_handle_get_dimensions(handle, &dim); + width = dim.width; + height = dim.height; + } +} diff --git a/libcore/imageloader.h b/libcore/imageloader.h index 30e47b7..6caf19f 100644 --- a/libcore/imageloader.h +++ b/libcore/imageloader.h @@ -4,6 +4,7 @@ #define X_DISPLAY_MISSING #include +#include #include #include @@ -32,16 +33,17 @@ private: }; // Image importer for SVG -/* class cImageImporterSVG : public cImageImporter { public: + cImageImporterSVG(); ~cImageImporterSVG(); bool LoadImage(const char *path); - bool RenderToCairo(cairo_t *cr); + void DrawToCairo(cairo_t *cr); void GetImageSize(int &width, int &height); private: - RsvgHandle *handle = NULL; -}*/ + RsvgHandle *handle; +}; + class cImageLoader { private: @@ -50,7 +52,7 @@ public: cImageLoader(); virtual ~cImageLoader(); cImage *CreateImage(int width, int height, bool preserveAspect = true); - bool LoadImage(std::string FileName, std::string Path, std::string Extension); + bool LoadImage(std::string Path, std::string FileName, std::string Extension); bool LoadImage(const char *fullpath); void DeterminateChannelLogoSize(int &width, int &height); };