|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 #ifdef HAVE_CONFIG_H 00015 #include "config.h" 00016 #endif 00017 00018 #include <stdlib.h> 00019 00020 #include "gvplugin_loadimage.h" 00021 #include "gvio.h" 00022 00023 #ifdef HAVE_PANGOCAIRO 00024 #include <cairo.h> 00025 00026 #ifdef WIN32 //*dependencies 00027 #pragma comment( lib, "gvc.lib" ) 00028 #pragma comment( lib, "glib-2.0.lib" ) 00029 #pragma comment( lib, "pango-1.0.lib" ) 00030 #pragma comment( lib, "pangocairo-1.0.lib" ) 00031 #pragma comment( lib, "cairo.lib" ) 00032 #pragma comment( lib, "gobject-2.0.lib" ) 00033 #pragma comment( lib, "graph.lib" ) 00034 #endif 00035 00036 00037 00038 00039 typedef enum { 00040 FORMAT_PNG_CAIRO, FORMAT_PNG_PS, 00041 } format_type; 00042 00043 static cairo_status_t 00044 reader (void *closure, unsigned char *data, unsigned int length) 00045 { 00046 if (length == fread(data, 1, length, (FILE *)closure) 00047 || feof((FILE *)closure)) 00048 return CAIRO_STATUS_SUCCESS; 00049 return CAIRO_STATUS_READ_ERROR; 00050 } 00051 00052 static void cairo_freeimage(usershape_t *us) 00053 { 00054 cairo_surface_destroy((cairo_surface_t*)(us->data)); 00055 } 00056 00057 static cairo_surface_t* cairo_loadimage(GVJ_t * job, usershape_t *us) 00058 { 00059 cairo_surface_t *surface = NULL; /* source surface */ 00060 00061 assert(job); 00062 assert(us); 00063 assert(us->name); 00064 00065 if (us->data) { 00066 if (us->datafree == cairo_freeimage) 00067 surface = (cairo_surface_t*)(us->data); /* use cached data */ 00068 else { 00069 us->datafree(us); /* free incompatible cache data */ 00070 us->datafree = NULL; 00071 us->data = NULL; 00072 } 00073 } 00074 if (!surface) { /* read file into cache */ 00075 if (!gvusershape_file_access(us)) 00076 return NULL; 00077 switch (us->type) { 00078 #ifdef CAIRO_HAS_PNG_FUNCTIONS 00079 case FT_PNG: 00080 surface = cairo_image_surface_create_from_png_stream(reader, us->f); 00081 cairo_surface_reference(surface); 00082 break; 00083 #endif 00084 default: 00085 surface = NULL; 00086 } 00087 if (surface) { 00088 us->data = (void*)surface; 00089 us->datafree = cairo_freeimage; 00090 } 00091 gvusershape_file_release(us); 00092 } 00093 return surface; 00094 } 00095 00096 static void pango_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled) 00097 { 00098 cairo_t *cr = (cairo_t *) job->context; /* target context */ 00099 cairo_surface_t *surface; /* source surface */ 00100 00101 surface = cairo_loadimage(job, us); 00102 if (surface) { 00103 cairo_save(cr); 00104 cairo_translate(cr, 00105 (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.), 00106 (-b.UR.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.)); 00107 cairo_scale(cr, 00108 ((b.UR.x - b.LL.x) * (job->dpi.x) / (96. * us->w)), 00109 ((b.UR.y - b.LL.y) * (job->dpi.y) / (96. * us->h))); 00110 cairo_set_source_surface (cr, surface, 0, 0); 00111 cairo_paint (cr); 00112 cairo_restore(cr); 00113 } 00114 } 00115 00116 static void pango_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled) 00117 { 00118 cairo_surface_t *surface; /* source surface */ 00119 cairo_format_t format; 00120 int X, Y, x, y, stride; 00121 unsigned char *data, *ix, alpha, red, green, blue; 00122 00123 surface = cairo_loadimage(job, us); 00124 if (surface) { 00125 format = cairo_image_surface_get_format(surface); 00126 if ((format != CAIRO_FORMAT_ARGB32) && (format != CAIRO_FORMAT_RGB24)) 00127 return; 00128 00129 X = cairo_image_surface_get_width(surface); 00130 Y = cairo_image_surface_get_height(surface); 00131 stride = cairo_image_surface_get_stride(surface); 00132 data = cairo_image_surface_get_data(surface); 00133 00134 gvputs(job, "save\n"); 00135 00136 /* define image data as string array (one per raster line) */ 00137 /* see parallel code in gd_loadimage_ps(). FIXME: refactor... */ 00138 gvputs(job, "/myctr 0 def\n"); 00139 gvputs(job, "/myarray [\n"); 00140 for (y = 0; y < Y; y++) { 00141 gvputs(job, "<"); 00142 ix = data + y * stride; 00143 for (x = 0; x < X; x++) { 00144 /* FIXME - this code may have endian problems */ 00145 blue = *ix++; 00146 green = *ix++; 00147 red = *ix++; 00148 alpha = *ix++; 00149 if (alpha < 0x7f) 00150 gvputs(job, "ffffff"); 00151 else 00152 gvprintf(job, "%02x%02x%02x", red, green, blue); 00153 } 00154 gvputs(job, ">\n"); 00155 } 00156 gvputs(job, "] def\n"); 00157 gvputs(job,"/myproc { myarray myctr get /myctr myctr 1 add def } def\n"); 00158 00159 /* this sets the position of the image */ 00160 gvprintf(job, "%g %g translate\n", 00161 (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.), 00162 (b.LL.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.)); 00163 00164 /* this sets the rendered size to fit the box */ 00165 gvprintf(job,"%g %g scale\n", 00166 ((b.UR.x - b.LL.x) * 72. / 96.), 00167 ((b.UR.y - b.LL.y) * 72. / 96.)); 00168 00169 /* xsize ysize bits-per-sample [matrix] */ 00170 gvprintf(job, "%d %d 8 [%d 0 0 %d 0 %d]\n", X, Y, X, -Y, Y); 00171 00172 gvputs(job, "{myproc} false 3 colorimage\n"); 00173 00174 gvputs(job, "restore\n"); 00175 } 00176 } 00177 00178 static gvloadimage_engine_t engine_cairo = { 00179 pango_loadimage_cairo 00180 }; 00181 00182 static gvloadimage_engine_t engine_ps = { 00183 pango_loadimage_ps 00184 }; 00185 #endif 00186 00187 gvplugin_installed_t gvloadimage_pango_types[] = { 00188 #ifdef HAVE_PANGOCAIRO 00189 {FORMAT_PNG_CAIRO, "png:cairo", 1, &engine_cairo, NULL}, 00190 {FORMAT_PNG_PS, "png:lasi", 2, &engine_ps, NULL}, 00191 {FORMAT_PNG_PS, "png:ps", 2, &engine_ps, NULL}, 00192 #endif 00193 {0, NULL, 0, NULL, NULL} 00194 };
1.7.5