mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-18 02:55:12 +00:00
Split cairo_draw_image into two functions
In some cases you are already working with a cairo_t and know your destination image size, this adds an API that allows you to handle these cases more easily. Along with now being able to draw images with an alpha level. It also leaves the original API unchanged.
This commit is contained in:
parent
2ade1e292b
commit
96337be28f
@ -1,5 +1,11 @@
|
|||||||
$#include <cairo.h>
|
$#include <cairo.h>
|
||||||
$#include <libcairo_imlib2_helper.h>
|
$#include <libcairo_imlib2_helper.h>
|
||||||
|
|
||||||
void cairo_draw_image(const char *, cairo_surface_t *, int, int, double, double,
|
/* Paints the image onto the cairo_surface_t */
|
||||||
|
void cairo_draw_image(const char *, cairo_surface_t *, int, int,
|
||||||
|
double scale_x=1.0, double scale_y=1.0,
|
||||||
double * return_scale_w, double * return_scale_h);
|
double * return_scale_w, double * return_scale_h);
|
||||||
|
|
||||||
|
/* Places an image onto a cairo_t but doesn't call cairo_paint */
|
||||||
|
void cairo_place_image(const char *file, cairo_t *cr, int x, int y,
|
||||||
|
int width, int height, double alpha=1.0);
|
||||||
|
@ -30,14 +30,84 @@
|
|||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
void cairo_place_image(const char *file, cairo_t *cr, int x, int y,
|
||||||
|
int width, int height, double alpha) {
|
||||||
|
int w, h, stride;
|
||||||
|
Imlib_Image alpha_image, image, premul;
|
||||||
|
cairo_surface_t *result;
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
NORM_ERR("cairoimagehelper: File is NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cr) {
|
||||||
|
NORM_ERR("cairoimagehelper: cairo_t is NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = imlib_load_image(file);
|
||||||
|
if (!image) {
|
||||||
|
NORM_ERR("cairoimagehelper: Couldn't load %s\n", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
w = imlib_image_get_width();
|
||||||
|
h = imlib_image_get_height();
|
||||||
|
|
||||||
|
if ((w <= 0) && (h <= 0)) {
|
||||||
|
NORM_ERR("cairoimagehelper: %s has 0 size\n", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create scaled version of image to later extract the alpha channel */
|
||||||
|
alpha_image = imlib_create_cropped_scaled_image (0, 0, w, h, width, height);
|
||||||
|
|
||||||
|
/* create temporary image */
|
||||||
|
premul = imlib_create_image(width, height);
|
||||||
|
if (!premul) {
|
||||||
|
NORM_ERR("cairoimagehelper: Couldn't create premul image for %s\n", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill with opaque black */
|
||||||
|
imlib_context_set_image(premul);
|
||||||
|
imlib_context_set_color(0, 0, 0, 255);
|
||||||
|
imlib_image_fill_rectangle(0, 0, width, height);
|
||||||
|
|
||||||
|
/* blend source image on top -
|
||||||
|
* in effect this multiplies the rgb values by alpha */
|
||||||
|
imlib_blend_image_onto_image(image, 0, 0, 0, w, h, 0, 0, width, height);
|
||||||
|
|
||||||
|
/* and use the alpha channel of the source image */
|
||||||
|
imlib_image_copy_alpha_to_image(alpha_image, 0, 0);
|
||||||
|
|
||||||
|
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
|
||||||
|
|
||||||
|
/* now pass the result to cairo */
|
||||||
|
result = cairo_image_surface_create_for_data(
|
||||||
|
(void *)imlib_image_get_data_for_reading_only(), CAIRO_FORMAT_ARGB32,
|
||||||
|
width, height, stride);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cr, result, x, y);
|
||||||
|
cairo_paint_with_alpha(cr, alpha);
|
||||||
|
|
||||||
|
imlib_context_set_image(image);
|
||||||
|
imlib_free_image();
|
||||||
|
imlib_context_set_image(premul);
|
||||||
|
imlib_free_image();
|
||||||
|
|
||||||
|
cairo_surface_destroy(result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void cairo_draw_image(const char *file, cairo_surface_t *cs, int x, int y,
|
void cairo_draw_image(const char *file, cairo_surface_t *cs, int x, int y,
|
||||||
double scale_x, double scale_y, double *return_scale_w,
|
double scale_x, double scale_y, double *return_scale_w,
|
||||||
double *return_scale_h) {
|
double *return_scale_h) {
|
||||||
int w, h, stride;
|
|
||||||
double scaled_w, scaled_h;
|
|
||||||
Imlib_Image alpha, premul;
|
|
||||||
cairo_surface_t *result;
|
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
int w, h;
|
||||||
|
double scaled_w, scaled_h;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
NORM_ERR("cairoimagehelper: File is NULL\n");
|
NORM_ERR("cairoimagehelper: File is NULL\n");
|
||||||
@ -49,14 +119,14 @@ void cairo_draw_image(const char *file, cairo_surface_t *cs, int x, int y,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Imlib_Image *image = imlib_load_image(file);
|
if ((scale_x <= 0.0) && (scale_y <= 0.0)) {
|
||||||
if (!image) {
|
NORM_ERR("cairoimagehelper: Image Scale is 0, %s\n", file);
|
||||||
NORM_ERR("cairoimagehelper: Couldn't load %s\n", file);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scale_x <= 0.0) && (scale_y <= 0.0)) {
|
Imlib_Image *image = imlib_load_image(file);
|
||||||
NORM_ERR("cairoimagehelper: Image Scale is 0, %s\n", file);
|
if (!image) {
|
||||||
|
NORM_ERR("cairoimagehelper: Couldn't load %s\n", file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,46 +147,10 @@ void cairo_draw_image(const char *file, cairo_surface_t *cs, int x, int y,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create scaled version of image to later extract the alpha channel */
|
|
||||||
alpha = imlib_create_cropped_scaled_image (0, 0, w, h, scaled_w, scaled_h);
|
|
||||||
|
|
||||||
/* create temporary image */
|
|
||||||
premul = imlib_create_image(scaled_w, scaled_h);
|
|
||||||
if (!premul) {
|
|
||||||
NORM_ERR("cairoimagehelper: Couldn't create premul image for %s\n", file);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill with opaque black */
|
|
||||||
imlib_context_set_image(premul);
|
|
||||||
imlib_context_set_color(0, 0, 0, 255);
|
|
||||||
imlib_image_fill_rectangle(0, 0, scaled_w, scaled_h);
|
|
||||||
|
|
||||||
/* blend source image on top -
|
|
||||||
* in effect this multiplies the rgb values by alpha */
|
|
||||||
imlib_blend_image_onto_image(image, 0, 0, 0, w, h, 0, 0, scaled_w, scaled_h);
|
|
||||||
|
|
||||||
/* and use the alpha channel of the source image */
|
|
||||||
imlib_image_copy_alpha_to_image(alpha, 0, 0);
|
|
||||||
|
|
||||||
stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, scaled_w);
|
|
||||||
|
|
||||||
/* now pass the result to cairo */
|
|
||||||
result = cairo_image_surface_create_for_data(
|
|
||||||
(void *)imlib_image_get_data_for_reading_only(), CAIRO_FORMAT_ARGB32,
|
|
||||||
scaled_w, scaled_h, stride);
|
|
||||||
|
|
||||||
cr = cairo_create(cs);
|
cr = cairo_create(cs);
|
||||||
cairo_set_source_surface(cr, result, x, y);
|
cairo_place_image(file, cr, x, y, scaled_w, scaled_h, 1.0);
|
||||||
cairo_paint(cr);
|
|
||||||
|
|
||||||
imlib_context_set_image(image);
|
|
||||||
imlib_free_image();
|
|
||||||
imlib_context_set_image(premul);
|
|
||||||
imlib_free_image();
|
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
cairo_surface_destroy(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _LIBCAIRO_IMAGE_HELPER_H_ */
|
#endif /* _LIBCAIRO_IMAGE_HELPER_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user