Graphviz  2.31.20130618.0446
plugin/core/gvloadimage_core.c
Go to the documentation of this file.
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 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #if HAVE_SYS_MMAN_H
00022 #include <sys/mman.h>
00023 #endif
00024 #ifdef _MSC_VER
00025 #include <io.h>
00026 #endif
00027 
00028 #include "gvplugin_loadimage.h"
00029 #include "agxbuf.h"
00030 #include "utils.h"
00031 #include "gvio.h"
00032 
00033 extern void core_loadimage_xdot(GVJ_t*, usershape_t*, boxf, boolean);
00034 extern shape_desc *find_user_shape(char *name);
00035 
00036 typedef enum {
00037     FORMAT_PNG_XDOT, FORMAT_GIF_XDOT, FORMAT_JPEG_XDOT, FORMAT_SVG_XDOT, FORMAT_PS_XDOT,
00038     FORMAT_PNG_DOT,  FORMAT_GIF_DOT,  FORMAT_JPEG_DOT,  FORMAT_SVG_DOT,  FORMAT_PS_DOT,
00039     FORMAT_PNG_MAP,  FORMAT_GIF_MAP,  FORMAT_JPEG_MAP,  FORMAT_SVG_MAP,  FORMAT_PS_MAP,
00040     FORMAT_PNG_SVG,  FORMAT_GIF_SVG,  FORMAT_JPEG_SVG,  FORMAT_SVG_SVG,
00041     FORMAT_PNG_FIG,  FORMAT_GIF_FIG,  FORMAT_JPEG_FIG,
00042     FORMAT_PNG_VRML, FORMAT_GIF_VRML, FORMAT_JPEG_VRML,
00043     FORMAT_PS_PS, FORMAT_PSLIB_PS, 
00044     FORMAT_PNG_VML, FORMAT_GIF_VML, FORMAT_JPEG_VML, 
00045 } format_type;
00046 
00047 static void core_loadimage_svg(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00048 {
00049     assert(job);
00050     assert(us);
00051     assert(us->name);
00052 
00053     gvputs(job, "<image xlink:href=\"");
00054     gvputs(job, us->name);
00055     if (job->rotation) {
00056         gvprintf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
00057             b.UR.y - b.LL.y, b.UR.x - b.LL.x, b.LL.x, b.UR.y);
00058         gvprintf (job, " transform=\"rotate(%d %g %g)\"",
00059             job->rotation, b.LL.x, b.UR.y);
00060     }
00061     else {
00062         gvprintf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMinYMin meet\" x=\"%g\" y=\"%g\"",
00063             b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, -b.UR.y);
00064     }
00065     gvputs(job, "/>\n");
00066 }
00067 
00068 static void core_loadimage_fig(GVJ_t * job, usershape_t *us, boxf bf, boolean filled)
00069 {
00070     int object_code = 2;        /* always 2 for polyline */
00071     int sub_type = 5;           /* always 5 for image */
00072     int line_style = 0;         /* solid, dotted, dashed */
00073     int thickness = 0;
00074     int pen_color = 0;
00075     int fill_color = -1;
00076     int depth = 1;
00077     int pen_style = -1;         /* not used */
00078     int area_fill = 0;
00079     double style_val = 0.0;
00080     int join_style = 0;
00081     int cap_style = 0;
00082     int radius = 0;
00083     int forward_arrow = 0;
00084     int backward_arrow = 0;
00085     int npoints = 5;
00086     int flipped = 0;
00087 
00088     box b;
00089 
00090     assert(job);
00091     assert(us);
00092     assert(us->name);
00093 
00094     BF2B(bf, b);
00095 
00096     gvprintf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n %d %s\n",
00097             object_code, sub_type, line_style, thickness, pen_color,
00098             fill_color, depth, pen_style, area_fill, style_val, join_style,
00099             cap_style, radius, forward_arrow, backward_arrow, npoints,
00100             flipped, us->name);
00101     gvprintf(job," %d %d %d %d %d %d %d %d %d %d\n",
00102             b.LL.x, b.LL.y,
00103             b.LL.x, b.UR.y,
00104             b.UR.x, b.UR.y,
00105             b.UR.x, b.LL.y,
00106             b.LL.x, b.LL.y);
00107 }
00108 
00109 static void core_loadimage_vrml(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00110 {
00111     obj_state_t *obj;
00112     node_t *n;
00113 
00114     assert(job);
00115     obj = job->obj;
00116     assert(obj);
00117     assert(us);
00118     assert(us->name);
00119 
00120     n = job->obj->u.n;
00121     assert(n);
00122 
00123     gvprintf(job, "Shape {\n");
00124     gvprintf(job, "  appearance Appearance {\n");
00125     gvprintf(job, "    material Material {\n");
00126     gvprintf(job, "      ambientIntensity 0.33\n");
00127     gvprintf(job, "        diffuseColor 1 1 1\n");
00128     gvprintf(job, "    }\n");
00129     gvprintf(job, "    texture ImageTexture { url \"%s\" }\n", us->name);
00130     gvprintf(job, "  }\n");
00131     gvprintf(job, "}\n");
00132 }
00133 
00134 static void ps_freeimage(usershape_t *us)
00135 {
00136 #if HAVE_SYS_MMAN_H
00137     munmap(us->data, us->datasize);
00138 #else
00139     free(us->data);
00140 #endif
00141 }
00142 
00143 /* usershape described by a postscript file */
00144 static void core_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00145 {
00146     assert(job);
00147     assert(us);
00148     assert(us->name);
00149 
00150     if (us->data) {
00151         if (us->datafree != ps_freeimage) {
00152             us->datafree(us);        /* free incompatible cache data */
00153             us->data = NULL;
00154             us->datafree = NULL;
00155             us->datasize = 0;
00156         }
00157     }
00158 
00159     if (!us->data) { /* read file into cache */
00160         int fd;
00161         struct stat statbuf;
00162 
00163         if (!gvusershape_file_access(us))
00164             return;
00165         fd = fileno(us->f);
00166         switch (us->type) {
00167             case FT_PS:
00168             case FT_EPS:
00169                 fstat(fd, &statbuf);
00170                 us->datasize = statbuf.st_size;
00171 #if HAVE_SYS_MMAN_H
00172                 us->data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
00173 #else
00174                 us->data = malloc(statbuf.st_size);
00175                 read(fd, us->data, statbuf.st_size);
00176 #endif
00177                 us->must_inline = TRUE;
00178                 break;
00179             default:
00180                 break;
00181         }
00182         if (us->data)
00183             us->datafree = ps_freeimage;
00184         gvusershape_file_release(us);
00185     }
00186 
00187     if (us->data) {
00188         gvprintf(job, "gsave %g %g translate newpath\n",
00189                 b.LL.x - (double)(us->x), b.LL.y - (double)(us->y));
00190         if (us->must_inline)
00191             epsf_emit_body(job, us);
00192         else
00193             gvprintf(job, "user_shape_%d\n", us->macro_id);
00194         gvprintf(job, "grestore\n");
00195     }
00196 }
00197 
00198 /* usershape described by a member of a postscript library */
00199 static void core_loadimage_pslib(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00200 {
00201     int i;
00202     pointf AF[4];
00203     shape_desc *shape;
00204 
00205     assert(job);
00206     assert(us);
00207     assert(us->name);
00208 
00209     if ((shape = (shape_desc*)us->data)) {
00210         AF[0] = b.LL;
00211         AF[2] = b.UR;
00212         AF[1].x = AF[0].x;
00213         AF[1].y = AF[2].y;
00214         AF[3].x = AF[2].x;
00215         AF[3].y = AF[0].y;
00216         if (filled) {
00217 //            ps_begin_context();
00218 //            ps_set_color(S[SP].fillcolor);
00219             gvprintf(job, "[ ");
00220             for (i = 0; i < 4; i++)
00221                 gvprintf(job, "%g %g ", AF[i].x, AF[i].y);
00222             gvprintf(job, "%g %g ", AF[0].x, AF[0].y);
00223             gvprintf(job, "]  %d true %s\n", 4, us->name);
00224 //            ps_end_context();
00225         }
00226         gvprintf(job, "[ ");
00227         for (i = 0; i < 4; i++)
00228             gvprintf(job, "%g %g ", AF[i].x, AF[i].y);
00229         gvprintf(job, "%g %g ", AF[0].x, AF[0].y);
00230         gvprintf(job, "]  %d false %s\n", 4, us->name);
00231     }
00232 }
00233 
00234 static void core_loadimage_vml(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
00235 {
00236     unsigned int  graphHeight;
00237     graphHeight =(int)(job->bb.UR.y - job->bb.LL.y);
00238     gvprintf (job, "<v:image src=\"%s\" style=\" position:absolute; width:%.2f; height:%.2f; left:%.2f ; top:%.2f\"",
00239            us->name,  b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, graphHeight-b.UR.y);
00240     gvputs(job, " />\n");
00241 }
00242 
00243 void core_loadimage_null(GVJ_t *gvc, usershape_t *us, boxf b, boolean filled)
00244 {
00245     /* null function - basically suppress the missing loader message */
00246 }
00247 
00248 static gvloadimage_engine_t engine_svg = {
00249     core_loadimage_svg
00250 };
00251 
00252 static gvloadimage_engine_t engine_fig = {
00253     core_loadimage_fig
00254 };
00255 
00256 static gvloadimage_engine_t engine_vrml = {
00257     core_loadimage_vrml
00258 };
00259 
00260 static gvloadimage_engine_t engine_ps = {
00261     core_loadimage_ps
00262 };
00263 
00264 static gvloadimage_engine_t engine_pslib = {
00265     core_loadimage_pslib
00266 };
00267 
00268 static gvloadimage_engine_t engine_null = {
00269     core_loadimage_null
00270 };
00271 
00272 static gvloadimage_engine_t engine_xdot = {
00273     core_loadimage_xdot
00274 };
00275 
00276 static gvloadimage_engine_t engine_vml = {
00277     core_loadimage_vml
00278 };
00279 
00280 gvplugin_installed_t gvloadimage_core_types[] = {
00281     {FORMAT_PNG_SVG, "png:svg", 1, &engine_svg, NULL},
00282     {FORMAT_GIF_SVG, "gif:svg", 1, &engine_svg, NULL},
00283     {FORMAT_JPEG_SVG, "jpeg:svg", 1, &engine_svg, NULL},
00284     {FORMAT_JPEG_SVG, "jpe:svg", 1, &engine_svg, NULL},
00285     {FORMAT_JPEG_SVG, "jpg:svg", 1, &engine_svg, NULL},
00286 
00287     {FORMAT_PNG_FIG, "png:fig", 1, &engine_fig, NULL},
00288     {FORMAT_GIF_FIG, "gif:fig", 1, &engine_fig, NULL},
00289     {FORMAT_JPEG_FIG, "jpeg:fig", 1, &engine_fig, NULL},
00290     {FORMAT_JPEG_FIG, "jpe:fig", 1, &engine_fig, NULL},
00291     {FORMAT_JPEG_FIG, "jpg:fig", 1, &engine_fig, NULL},
00292 
00293     {FORMAT_PNG_VRML, "png:vrml", 1, &engine_vrml, NULL},
00294     {FORMAT_GIF_VRML, "gif:vrml", 1, &engine_vrml, NULL},
00295     {FORMAT_JPEG_VRML, "jpeg:vrml", 1, &engine_vrml, NULL},
00296     {FORMAT_JPEG_VRML, "jpe:vrml", 1, &engine_vrml, NULL},
00297     {FORMAT_JPEG_VRML, "jpg:vrml", 1, &engine_vrml, NULL},
00298 
00299     {FORMAT_PS_PS, "eps:ps", 1, &engine_ps, NULL},
00300     {FORMAT_PS_PS, "ps:ps", 1, &engine_ps, NULL},
00301     {FORMAT_PSLIB_PS, "(lib):ps", 1, &engine_pslib, NULL},  /* for pslib */
00302 
00303     {FORMAT_PNG_MAP, "png:map", 1, &engine_null, NULL},
00304     {FORMAT_GIF_MAP, "gif:map", 1, &engine_null, NULL},
00305     {FORMAT_JPEG_MAP, "jpeg:map", 1, &engine_null, NULL},
00306     {FORMAT_JPEG_MAP, "jpe:map", 1, &engine_null, NULL},
00307     {FORMAT_JPEG_MAP, "jpg:map", 1, &engine_null, NULL},
00308     {FORMAT_PS_MAP, "ps:map", 1, &engine_null, NULL},
00309     {FORMAT_PS_MAP, "eps:map", 1, &engine_null, NULL},
00310     {FORMAT_SVG_MAP, "svg:map", 1, &engine_null, NULL},
00311 
00312     {FORMAT_PNG_DOT, "png:dot", 1, &engine_null, NULL},
00313     {FORMAT_GIF_DOT, "gif:dot", 1, &engine_null, NULL},
00314     {FORMAT_JPEG_DOT, "jpeg:dot", 1, &engine_null, NULL},
00315     {FORMAT_JPEG_DOT, "jpe:dot", 1, &engine_null, NULL},
00316     {FORMAT_JPEG_DOT, "jpg:dot", 1, &engine_null, NULL},
00317     {FORMAT_PS_DOT, "ps:dot", 1, &engine_null, NULL},
00318     {FORMAT_PS_DOT, "eps:dot", 1, &engine_null, NULL},
00319     {FORMAT_SVG_DOT, "svg:dot", 1, &engine_null, NULL},
00320 
00321     {FORMAT_PNG_XDOT, "png:xdot", 1, &engine_xdot, NULL},
00322     {FORMAT_GIF_XDOT, "gif:xdot", 1, &engine_xdot, NULL},
00323     {FORMAT_JPEG_XDOT, "jpeg:xdot", 1, &engine_xdot, NULL},
00324     {FORMAT_JPEG_XDOT, "jpe:xdot", 1, &engine_xdot, NULL},
00325     {FORMAT_JPEG_XDOT, "jpg:xdot", 1, &engine_xdot, NULL},
00326     {FORMAT_PS_XDOT, "ps:xdot", 1, &engine_xdot, NULL},
00327     {FORMAT_PS_XDOT, "eps:xdot", 1, &engine_xdot, NULL},
00328     {FORMAT_SVG_XDOT, "svg:xdot", 1, &engine_xdot, NULL},
00329 
00330     {FORMAT_SVG_SVG, "svg:svg", 1, &engine_svg, NULL},
00331 
00332     {FORMAT_PNG_VML, "png:vml", 1, &engine_vml, NULL},
00333     {FORMAT_GIF_VML, "gif:vml", 1, &engine_vml, NULL},
00334     {FORMAT_JPEG_VML, "jpeg:vml", 1, &engine_vml, NULL},
00335     {FORMAT_JPEG_VML, "jpe:vml", 1, &engine_vml, NULL},
00336     {FORMAT_JPEG_VML, "jpg:vml", 1, &engine_vml, NULL},
00337 
00338     {0, NULL, 0, NULL, NULL}
00339 };