#include <stddef.h>
#include <string.h>
+#ifdef HAVE_PANGOCAIRO
+#include <cairo.h>
+#endif
+
#include "gvplugin_loadimage.h"
#include "gvio.h"
typedef enum {
FORMAT_PNG_GD, FORMAT_GIF_GD, FORMAT_JPG_GD, FORMAT_GD_GD, FORMAT_GD2_GD, FORMAT_XPM_GD, FORMAT_WBMP_GD, FORMAT_XBM_GD,
FORMAT_PNG_PS, FORMAT_GIF_PS, FORMAT_JPG_PS, FORMAT_GD_PS, FORMAT_GD2_PS, FORMAT_XPM_PS, FORMAT_WBMP_PS, FORMAT_XBM_PS,
+ FORMAT_PNG_CAIRO, FORMAT_GIF_CAIRO, FORMAT_JPG_CAIRO, FORMAT_GD_CAIRO, FORMAT_GD2_CAIRO, FORMAT_XPM_CAIRO, FORMAT_WBMP_CAIRO, FORMAT_XBM_CAIRO,
} format_type;
return (gdImagePtr)(us->data);
}
+static gdImagePtr gd_rotateimage(gdImagePtr im, int rotation)
+{
+ gdImagePtr im2 = gdImageCreate(im->sy, im->sx);
+
+ gdImageCopyRotated(im2, im, im2->sx / 2., im2->sy / 2.,
+ 0, 0, im->sx, im->sy, rotation);
+ gdImageDestroy(im);
+ return im2;
+}
+
static void gd_loadimage_gd(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
{
- gdImagePtr im3, im2 = NULL, im = (gdImagePtr) job->context;
+ gdImagePtr im2, im = (gdImagePtr) job->context;
if ((im2 = gd_loadimage(job, us))) {
- if (job->rotation) {
- im3 = gdImageCreate(im2->sy, im2->sx); /* scratch image for rotation */
- gdImageCopyRotated(im3, im2, im3->sx / 2., im3->sy / 2.,
- 0, 0, im2->sx, im2->sy, job->rotation);
- gdImageCopyResized(im, im3, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
- ROUND(b.UR.y - b.LL.y), ROUND(b.UR.x - b.LL.x), im3->sx, im3->sy);
- gdImageDestroy(im3);
- }
- else {
- gdImageCopyResized(im, im2, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
+ if (job->rotation)
+ im2 = gd_rotateimage(im2, job->rotation);
+ gdImageCopyResized(im, im2, ROUND(b.LL.x), ROUND(b.LL.y), 0, 0,
ROUND(b.UR.x - b.LL.x), ROUND(b.UR.y - b.LL.y), im2->sx, im2->sy);
- }
}
}
+#ifdef HAVE_PANGOCAIRO
+static void gd_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
+{
+ cairo_t *cr = (cairo_t *) job->context; /* target context */
+ unsigned int x, y, stride, width, height, px;
+ unsigned char *data;
+ cairo_surface_t *surface; /* source surface */
+ gdImagePtr im;
+
+ if ((im = gd_loadimage(job, us))) {
+ width = im->sx;
+ height = im->sy;
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
+ data = malloc (stride * height);
+ surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
+ width, height, stride);
+
+ if (im->trueColor) {
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ px = gdImageTrueColorPixel(im, x, y);
+ *data++ = gdTrueColorGetBlue(px);
+ *data++ = gdTrueColorGetGreen(px);
+ *data++ = gdTrueColorGetRed(px);
+ *data++ = (0x7F-gdTrueColorGetAlpha(px)) << 1;
+ }
+ }
+ }
+ else {
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ px = gdImagePalettePixel(im, x, y);
+ *data++ = im->blue[px];
+ *data++ = im->green[px];
+ *data++ = im->red[px];
+ *data++ = (px==im->transparent)?0x00:0xff;
+ }
+ }
+ }
+
+ cairo_save(cr);
+ cairo_translate(cr,
+ (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.),
+ (-b.UR.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.));
+ cairo_scale(cr,
+ ((b.UR.x - b.LL.x) * (job->dpi.x) / (96. * us->w)),
+ ((b.UR.y - b.LL.y) * (job->dpi.y) / (96. * us->h)));
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_restore(cr);
+
+ cairo_surface_destroy(surface);
+ }
+}
+#endif
+
static void gd_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
{
gdImagePtr im = NULL;
gd_loadimage_ps
};
+static gvloadimage_engine_t engine_cairo = {
+ gd_loadimage_cairo
+};
+
#endif
gvplugin_installed_t gvloadimage_gd_types[] = {
#ifdef HAVE_LIBGD
+
{FORMAT_GD_GD, "gd:gd", 1, &engine, NULL},
{FORMAT_GD2_GD, "gd2:gd", 1, &engine, NULL},
#ifdef HAVE_GD_GIF
#ifdef HAVE_GD_XPM
{FORMAT_XBM_GD, "xbm:gd", 1, &engine, NULL},
#endif
+
{FORMAT_GD_PS, "gd:ps", 1, &engine_ps, NULL},
{FORMAT_GD_PS, "gd:lasi", 1, &engine_ps, NULL},
{FORMAT_GD2_PS, "gd2:ps", 1, &engine_ps, NULL},
{FORMAT_XBM_PS, "xbm:ps", 1, &engine_ps, NULL},
{FORMAT_XBM_PS, "xbm:lasi", 1, &engine_ps, NULL},
#endif
+
+#ifdef HAVE_PANGOCAIRO
+ {FORMAT_GD_CAIRO, "gd:cairo", 1, &engine_cairo, NULL},
+ {FORMAT_GD2_CAIRO, "gd2:cairo", 1, &engine_cairo, NULL},
+#ifdef HAVE_GD_GIF
+ {FORMAT_GIF_CAIRO, "gif:cairo", 1, &engine_cairo, NULL},
#endif
+#ifdef HAVE_GD_JPEG
+ {FORMAT_JPG_CAIRO, "jpeg:cairo", 1, &engine_cairo, NULL},
+ {FORMAT_JPG_CAIRO, "jpg:cairo", 1, &engine_cairo, NULL},
+ {FORMAT_JPG_CAIRO, "jpe:cairo", 1, &engine_cairo, NULL},
+#endif
+#ifdef HAVE_GD_PNG
+ {FORMAT_PNG_CAIRO, "png:cairo", -1, &engine_cairo, NULL},
+#endif
+#ifdef HAVE_GD_WBMP
+ {FORMAT_WBMP_CAIRO, "wbmp:cairo", 1, &engine_cairo, NULL},
+#endif
+#ifdef HAVE_GD_XPM
+ {FORMAT_XBM_CAIRO, "xbm:cairo", 1, &engine_cairo, NULL},
+#endif
+#endif /* HAVE_PANGOCAIRO */
+
+#endif /* HAVE_LIBGD */
{0, NULL, 0, NULL, NULL}
};