2014-09-27 09:25:14 +02:00
|
|
|
#include "../config.h"
|
|
|
|
#include "helpers.h"
|
|
|
|
#include "imageloader.h"
|
2014-10-30 16:41:06 +01:00
|
|
|
//#include <math.h>
|
2014-09-27 09:25:14 +02:00
|
|
|
#include <string>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <iostream>
|
|
|
|
|
2014-10-30 16:41:06 +01:00
|
|
|
cImageLoader::cImageLoader() {
|
|
|
|
importer = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cImageLoader::~cImageLoader() {
|
2014-10-30 16:41:06 +01:00
|
|
|
delete(importer);
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
2014-10-30 16:41:06 +01:00
|
|
|
cImage *cImageLoader::CreateImage(int width, int height, bool preserveAspect) {
|
|
|
|
if (!importer) return NULL;
|
|
|
|
|
|
|
|
int w, h;
|
|
|
|
importer->GetImageSize(w, h);
|
|
|
|
if (width == 0)
|
|
|
|
width = w;
|
|
|
|
if (height == 0)
|
|
|
|
height = h;
|
|
|
|
|
|
|
|
cairo_surface_t *surface;
|
|
|
|
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
|
|
|
|
|
|
|
cairo_t *cr;
|
|
|
|
cr = cairo_create(surface);
|
|
|
|
|
|
|
|
double sx = width / (double)w;
|
|
|
|
double sy = height / (double)h;
|
|
|
|
if (preserveAspect) {
|
|
|
|
if (sx < sy)
|
|
|
|
sy = sx;
|
|
|
|
if (sy < sx)
|
|
|
|
sx = sy;
|
|
|
|
}
|
|
|
|
cairo_scale(cr, sx, sy);
|
|
|
|
|
|
|
|
importer->DrawToCairo(cr);
|
|
|
|
|
|
|
|
cairo_status_t status = cairo_status(cr);
|
|
|
|
if (status)
|
|
|
|
dsyslog("skindesigner: Cairo CreateImage Error %s", cairo_status_to_string(status));
|
|
|
|
|
|
|
|
unsigned char *data = cairo_image_surface_get_data(surface);
|
|
|
|
cImage *image = new cImage(cSize(width, height), (tColor*)data);
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
2014-10-30 21:07:26 +01:00
|
|
|
cairo_surface_destroy(surface);
|
2014-10-30 16:41:06 +01:00
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cImageLoader::LoadImage(const char *fullpath) {
|
|
|
|
if ((fullpath == NULL) || (strlen(fullpath) < 5))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (config.debugImageLoading)
|
|
|
|
dsyslog("skindesigner: trying to load: %s", fullpath);
|
|
|
|
|
|
|
|
delete(importer);
|
|
|
|
importer = NULL;
|
|
|
|
|
|
|
|
if (endswith(fullpath, ".png"))
|
|
|
|
importer = new cImageImporterPNG;
|
2014-10-30 21:07:26 +01:00
|
|
|
else if (endswith(fullpath, ".svg"))
|
|
|
|
importer = new cImageImporterSVG;
|
2014-10-30 16:41:06 +01:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return importer->LoadImage(fullpath);
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
2014-10-30 16:41:06 +01:00
|
|
|
// Just a different way to call LoadImage. Calls the above one.
|
2014-10-30 21:07:26 +01:00
|
|
|
bool cImageLoader::LoadImage(std::string Path, std::string FileName, std::string Extension) {
|
2014-10-30 16:41:06 +01:00
|
|
|
std::stringstream sstrImgFile;
|
|
|
|
sstrImgFile << Path << FileName << "." << Extension;
|
|
|
|
std::string imgFile = sstrImgFile.str();
|
|
|
|
return LoadImage(imgFile.c_str());
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cImageLoader::DeterminateChannelLogoSize(int &width, int &height) {
|
2014-10-03 15:54:23 +02:00
|
|
|
cString logoPath;
|
|
|
|
cString logoPathSkin = cString::sprintf("%s%s/themes/%s/logos/", *config.skinPath, Setup.OSDSkin, Setup.OSDTheme);
|
|
|
|
if (FolderExists(*logoPathSkin)) {
|
|
|
|
logoPath = logoPathSkin;
|
|
|
|
} else {
|
|
|
|
logoPath = config.logoPath;
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cString logoExt = config.logoExtension;
|
|
|
|
DIR *folder = NULL;
|
|
|
|
struct dirent *file;
|
|
|
|
folder = opendir(logoPath);
|
|
|
|
if (!folder) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (file = readdir(folder)) {
|
|
|
|
if (endswith(file->d_name, *logoExt)) {
|
|
|
|
std::stringstream filePath;
|
|
|
|
filePath << *logoPath << file->d_name;
|
2014-10-30 16:41:06 +01:00
|
|
|
if (LoadImage(filePath.str().c_str())) {
|
|
|
|
int logoWidth = 0;
|
|
|
|
int logoHeight = 0;
|
|
|
|
importer->GetImageSize(logoWidth, logoHeight);
|
2014-09-27 09:25:14 +02:00
|
|
|
if (logoWidth > 0 && logoHeight > 0) {
|
|
|
|
width = logoWidth;
|
|
|
|
height = logoHeight;
|
2014-10-30 16:41:06 +01:00
|
|
|
delete(importer);
|
|
|
|
importer = NULL;
|
2014-09-27 09:25:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-10-30 16:41:06 +01:00
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-10-30 16:41:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Image importer for PNG
|
|
|
|
//
|
|
|
|
|
|
|
|
cImageImporterPNG::cImageImporterPNG() {
|
|
|
|
surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cImageImporterPNG::~cImageImporterPNG() {
|
|
|
|
if (surface)
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cImageImporterPNG::LoadImage(const char *path) {
|
|
|
|
if (surface)
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
|
|
|
|
surface = cairo_image_surface_create_from_png(path);
|
|
|
|
|
|
|
|
if (cairo_surface_status(surface)) {
|
|
|
|
if (config.debugImageLoading)
|
|
|
|
dsyslog("skindesigner: Cairo LoadImage Error: %s", cairo_status_to_string(cairo_surface_status(surface)));
|
|
|
|
surface = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cImageImporterPNG::DrawToCairo(cairo_t *cr) {
|
2014-10-30 21:07:26 +01:00
|
|
|
if (surface) {
|
2014-10-30 16:41:06 +01:00
|
|
|
cairo_set_source_surface(cr, surface, 0, 0);
|
2014-10-30 21:07:26 +01:00
|
|
|
cairo_paint(cr);
|
|
|
|
}
|
2014-10-30 16:41:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void cImageImporterPNG::GetImageSize(int &width, int &height) {
|
|
|
|
if (surface) {
|
|
|
|
width = cairo_image_surface_get_width(surface);
|
|
|
|
height = cairo_image_surface_get_height(surface);
|
|
|
|
}
|
|
|
|
}
|
2014-10-30 21:07:26 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|