vdr-plugin-skindesigner/libcore/imagecreator.c
2014-12-03 18:12:37 +01:00

203 lines
4.3 KiB
C

#include "imagecreator.h"
cImageCreator::cImageCreator(void) {
surface = NULL;
cr = NULL;
}
cImageCreator::~cImageCreator() {
if (cr)
cairo_destroy (cr);
if (surface)
cairo_surface_destroy (surface);
}
bool cImageCreator::InitCairoImage(int width, int height) {
this->width = width;
this->height = height;
if (width < 1 || height < 1 || width > 1920 || height > 1080)
return false;
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cr = cairo_create(surface);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
return true;
}
/**********************************************************************************
* Public Functions
**********************************************************************************/
///< 0 draws the entire ellipse
///< 1..4 draws only the first, second, third or fourth quadrant, respectively
///< 5..8 draws the right, top, left or bottom half, respectively
///< -1..-4 draws the inverted part of the given quadrant
///< If Quadrants is not 0, the coordinates are those of the actual area, not
///< the full circle!
void cImageCreator::DrawEllipse(tColor color, int quadrants) {
if (!cr || !surface)
return;
//center of the ellipse
double x, y;
//radius
double radius;
//start and stop angle (radian)
double arcStart, arcStop;
//scaling factors
double scaleX, scaleY;
//draw inverted ellipse
bool inverted;
scaleX = width;
scaleY = height;
inverted = false;
switch (quadrants) {
case 0:
x = 0.5;
y = 0.5;
radius = 0.5;
arcStart = 0.0;
arcStop = 2 * M_PI;
break;
case 1:
x = 0.0;
y = 1.0;
radius = 1.0;
arcStart = M_PI;
arcStop = 2 * M_PI;
break;
case 2:
x = 1.0;
y = 1.0;
radius = 1.0;
arcStart = M_PI;
arcStop = 2 * M_PI;
break;
case 3:
x = 1.0;
y = 0.0;
radius = 1.0;
arcStart = 0;
arcStop = M_PI;
break;
case 4:
x = 0.0;
y = 0.0;
radius = 1.0;
arcStart = 0;
arcStop = M_PI;
break;
case 5:
scaleX = 2 * width;
x = 0.0;
y = 0.5;
radius = 0.5;
arcStart = 0;
arcStop = 2* M_PI;
break;
case 6:
scaleY = 2 * height;
x = 0.5;
y = 0.5;
radius = 0.5;
arcStart = 0;
arcStop = 2* M_PI;
break;
case 7:
scaleX = 2 * width;
x = 0.5;
y = 0.5;
radius = 0.5;
arcStart = 0;
arcStop = 2* M_PI;
break;
case 8:
scaleY = 2 * height;
x = 0.5;
y = 0.0;
radius = 0.5;
arcStart = 0;
arcStop = 2* M_PI;
break;
case -1:
x = 0.0;
y = 1.0;
radius = 1.0;
arcStart = M_PI;
arcStop = 2* M_PI;
inverted = true;
break;
case -2:
x = 1.0;
y = 1.0;
radius = 1.0;
arcStart = M_PI;
arcStop = 2 * M_PI;
inverted = true;
break;
case -3:
x = 1.0;
y = 0.0;
radius = 1.0;
arcStart = 0;
arcStop = M_PI;
inverted = true;
break;
case -4:
x = 0.0;
y = 0.0;
radius = 1.0;
arcStart = 0;
arcStop = M_PI;
inverted = true;
break;
default:
x = 0.5;
y = 0.5;
radius = 0.5;
arcStart = 0.0;
arcStop = 2 * M_PI;
break;
}
SetColor(color);
//Draw Background for inverted ellipses
if (inverted) {
cairo_rectangle(cr, 0.0, 0.0, width, height);
cairo_fill (cr);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
}
//Draw Ellipse
cairo_scale(cr, scaleX, scaleY);
cairo_arc(cr, x, y, radius, arcStart, arcStop);
cairo_fill(cr);
}
cImage *cImageCreator::GetImage(void) {
if (!cr || !surface)
NULL;
unsigned char *data = cairo_image_surface_get_data(surface);
cImage *image = new cImage(cSize(width, height), (tColor*)data);
return image;
}
/**********************************************************************************
* Private Functions
**********************************************************************************/
void cImageCreator::SetColor(tColor color) {
if (!cr || !surface)
return;
tIndex tAlpha = (color & 0xFF000000) >> 24;
tIndex tRed = (color & 0x00FF0000) >> 16;
tIndex tGreen = (color & 0x0000FF00) >> 8;
tIndex tBlue = (color & 0x000000FF);
double a = (int)tAlpha / (double)255;
double r = (int)tRed / (double)255;
double g = (int)tGreen / (double)255;
double b = (int)tBlue / (double)255;
cairo_set_source_rgba(cr, r, g, b, a);
}