/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/plugin/pango/gvloadimage_pango.c

Go to the documentation of this file.
00001 /* $Id: gvloadimage_pango.c,v 1.10 2007/09/07 20:28:24 ellson Exp $ $Revision: 1.10 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
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; /* source surface */
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); /* use cached data */
00058         else {
00059              us->datafree(us);        /* free incompatible cache data */
00060              us->data = NULL;
00061         }
00062     }
00063     if (!surface) { /* read file into cache */
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; /* target context */
00086     cairo_surface_t *surface;    /* source 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;   /* source 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         /* define image data as string array (one per raster line) */
00117         /* see parallel code in gd_loadimage_ps().  FIXME: refactor... */
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                 /* FIXME - this code may have endian problems */
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         /* this sets the position of the image */
00137         fprintf(out, "%g %g translate %% lower-left coordinate\n", b.LL.x, b.LL.y);
00138 
00139         /* this sets the rendered size to fit the box */
00140         fprintf(out,"%g %g scale\n", b.UR.x - b.LL.x, b.UR.y - b.LL.y);
00141 
00142         /* xsize ysize bits-per-sample [matrix] */
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 };

Generated on Mon Mar 31 19:03:28 2008 for Graphviz by  doxygen 1.5.1