00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020
00021 #include <stdlib.h>
00022
00023 #include "gvplugin_loadimage.h"
00024
00025 #ifdef HAVE_PANGOCAIRO
00026 #include <cairo.h>
00027
00028 typedef enum {
00029 FORMAT_PNG_CAIRO, FORMAT_PNG_PS,
00030 } format_type;
00031
00032 static cairo_status_t
00033 reader (void *closure, unsigned char *data, unsigned int length)
00034 {
00035 if (length == fread(data, 1, length, (FILE *)closure)
00036 || feof((FILE *)closure))
00037 return CAIRO_STATUS_SUCCESS;
00038 return CAIRO_STATUS_READ_ERROR;
00039 }
00040
00041 static void cairo_freeimage(usershape_t *us)
00042 {
00043 cairo_destroy((cairo_t*)us->data);
00044 }
00045
00046 static cairo_surface_t* cairo_loadimage(GVJ_t * job, usershape_t *us)
00047 {
00048 cairo_surface_t *surface = NULL;
00049
00050 assert(job);
00051 assert(us);
00052 assert(us->name);
00053 assert(us->f);
00054
00055 if (us->data) {
00056 if (us->datafree == cairo_freeimage)
00057 surface = (cairo_surface_t*)(us->data);
00058 else {
00059 us->datafree(us);
00060 us->data = NULL;
00061 }
00062 }
00063 if (!surface) {
00064 fseek(us->f, 0, SEEK_SET);
00065 switch (us->type) {
00066 #ifdef CAIRO_HAS_PNG_FUNCTIONS
00067 case FT_PNG:
00068 surface = cairo_image_surface_create_from_png_stream(reader, us->f);
00069 cairo_surface_reference(surface);
00070 break;
00071 #endif
00072 default:
00073 surface = NULL;
00074 }
00075 if (surface) {
00076 us->data = (void*)surface;
00077 us->datafree = cairo_freeimage;
00078 }
00079 }
00080 return surface;
00081 }
00082
00083 static void pango_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00084 {
00085 cairo_t *cr = (cairo_t *) job->context;
00086 cairo_surface_t *surface;
00087
00088 surface = cairo_loadimage(job, us);
00089 if (surface) {
00090 cairo_save(cr);
00091 cairo_translate(cr, ROUND(b.LL.x), ROUND(-b.UR.y));
00092 cairo_scale(cr, (b.UR.x - b.LL.x) / us->w,
00093 (b.UR.y - b.LL.y) / us->h);
00094 cairo_set_source_surface (cr, surface, 0, 0);
00095 cairo_paint (cr);
00096 cairo_restore(cr);
00097 }
00098 }
00099
00100 static void pango_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00101 {
00102 cairo_surface_t *surface;
00103 FILE *out = job->output_file;
00104 int X, Y, x, y, stride;
00105 unsigned char *data, *ix, alpha, red, green, blue;
00106
00107 surface = cairo_loadimage(job, us);
00108 if (surface && (cairo_image_surface_get_format(surface) == CAIRO_FORMAT_ARGB32)) {
00109 X = cairo_image_surface_get_width(surface);
00110 Y = cairo_image_surface_get_height(surface);
00111 stride = cairo_image_surface_get_stride(surface);
00112 data = cairo_image_surface_get_data(surface);
00113
00114 fprintf(out, "save\n");
00115
00116
00117
00118 fprintf(out, "/myctr 0 def\n");
00119 fprintf(out, "/myarray [\n");
00120 for (y = 0; y < Y; y++) {
00121 fprintf(out, "<");
00122 ix = data + y * stride;
00123 for (x = 0; x < X; x++) {
00124
00125 blue = *ix++;
00126 green = *ix++;
00127 red = *ix++;
00128 alpha = *ix++;
00129 fprintf(out, "%02x%02x%02x", red, green, blue);
00130 }
00131 fprintf(out, ">\n");
00132 }
00133 fprintf(out, "] def\n");
00134 fprintf(out,"/myproc { myarray myctr get /myctr myctr 1 add def } def\n");
00135
00136
00137 fprintf(out, "%g %g translate %% lower-left coordinate\n", b.LL.x, b.LL.y);
00138
00139
00140 fprintf(out,"%g %g scale\n", b.UR.x - b.LL.x, b.UR.y - b.LL.y);
00141
00142
00143 fprintf(out, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y);
00144
00145 fprintf(out, "{myproc} false 3 colorimage\n");
00146
00147 fprintf(out, "restore\n");
00148 }
00149 }
00150
00151 static gvloadimage_engine_t engine_cairo = {
00152 pango_loadimage_cairo
00153 };
00154
00155 static gvloadimage_engine_t engine_ps = {
00156 pango_loadimage_ps
00157 };
00158 #endif
00159
00160 gvplugin_installed_t gvloadimage_pango_types[] = {
00161 #ifdef HAVE_PANGOCAIRO
00162 {FORMAT_PNG_CAIRO, "png:cairo", 1, &engine_cairo, NULL},
00163 {FORMAT_PNG_PS, "png:ps", 2, &engine_ps, NULL},
00164 #endif
00165 {0, NULL, 0, NULL, NULL}
00166 };