Graphviz  2.39.20141222.0545
gvloadimage_core.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #if HAVE_SYS_MMAN_H
22 #include <sys/mman.h>
23 #endif
24 #ifdef _MSC_VER
25 #include <io.h>
26 #endif
27 
28 #include "gvplugin_loadimage.h"
29 #include "agxbuf.h"
30 #include "utils.h"
31 #include "gvio.h"
32 
33 extern void core_loadimage_xdot(GVJ_t*, usershape_t*, boxf, boolean);
34 extern shape_desc *find_user_shape(char *name);
35 
36 typedef enum {
46 } format_type;
47 
48 static void core_loadimage_svg(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
49 {
50 
51  double width = (b.UR.x-b.LL.x);
52  double height = (b.UR.y-b.LL.y);
53  double originx = (b.UR.x+b.LL.x - width)/2;
54  double originy = (b.UR.y+b.LL.y + height)/2;
55  assert(job);
56  assert(us);
57  assert(us->name);
58 
59  gvputs(job, "<image xlink:href=\"");
60  gvputs(job, us->name);
61  if (job->rotation) {
62 
63 // FIXME - this is messed up >>>
64  gvprintf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
65  height, width, originx, -originy);
66  gvprintf (job, " transform=\"rotate(%d %g %g)\"",
67  job->rotation, originx, -originy);
68 // <<<
69  }
70  else {
71  gvprintf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMinYMin meet\" x=\"%g\" y=\"%g\"",
72  width, height, originx, -originy);
73  }
74  gvputs(job, "/>\n");
75 }
76 
77 static void core_loadimage_fig(GVJ_t * job, usershape_t *us, boxf bf, boolean filled)
78 {
79  int object_code = 2; /* always 2 for polyline */
80  int sub_type = 5; /* always 5 for image */
81  int line_style = 0; /* solid, dotted, dashed */
82  int thickness = 0;
83  int pen_color = 0;
84  int fill_color = -1;
85  int depth = 1;
86  int pen_style = -1; /* not used */
87  int area_fill = 0;
88  double style_val = 0.0;
89  int join_style = 0;
90  int cap_style = 0;
91  int radius = 0;
92  int forward_arrow = 0;
93  int backward_arrow = 0;
94  int npoints = 5;
95  int flipped = 0;
96 
97  box b;
98 
99  assert(job);
100  assert(us);
101  assert(us->name);
102 
103  BF2B(bf, b);
104 
105  gvprintf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n %d %s\n",
106  object_code, sub_type, line_style, thickness, pen_color,
107  fill_color, depth, pen_style, area_fill, style_val, join_style,
108  cap_style, radius, forward_arrow, backward_arrow, npoints,
109  flipped, us->name);
110  gvprintf(job," %d %d %d %d %d %d %d %d %d %d\n",
111  b.LL.x, b.LL.y,
112  b.LL.x, b.UR.y,
113  b.UR.x, b.UR.y,
114  b.UR.x, b.LL.y,
115  b.LL.x, b.LL.y);
116 }
117 
118 static void core_loadimage_vrml(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
119 {
120  obj_state_t *obj;
121  node_t *n;
122 
123  assert(job);
124  obj = job->obj;
125  assert(obj);
126  assert(us);
127  assert(us->name);
128 
129  n = job->obj->u.n;
130  assert(n);
131 
132  gvprintf(job, "Shape {\n");
133  gvprintf(job, " appearance Appearance {\n");
134  gvprintf(job, " material Material {\n");
135  gvprintf(job, " ambientIntensity 0.33\n");
136  gvprintf(job, " diffuseColor 1 1 1\n");
137  gvprintf(job, " }\n");
138  gvprintf(job, " texture ImageTexture { url \"%s\" }\n", us->name);
139  gvprintf(job, " }\n");
140  gvprintf(job, "}\n");
141 }
142 
143 static void ps_freeimage(usershape_t *us)
144 {
145 #if HAVE_SYS_MMAN_H
146  munmap(us->data, us->datasize);
147 #else
148  free(us->data);
149 #endif
150 }
151 
152 /* usershape described by a postscript file */
153 static void core_loadimage_ps(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
154 {
155  assert(job);
156  assert(us);
157  assert(us->name);
158 
159  if (us->data) {
160  if (us->datafree != ps_freeimage) {
161  us->datafree(us); /* free incompatible cache data */
162  us->data = NULL;
163  us->datafree = NULL;
164  us->datasize = 0;
165  }
166  }
167 
168  if (!us->data) { /* read file into cache */
169  int fd;
170  struct stat statbuf;
171 
172  if (!gvusershape_file_access(us))
173  return;
174  fd = fileno(us->f);
175  switch (us->type) {
176  case FT_PS:
177  case FT_EPS:
178  fstat(fd, &statbuf);
179  us->datasize = statbuf.st_size;
180 #if HAVE_SYS_MMAN_H
181  us->data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
182 #else
183  us->data = malloc(statbuf.st_size);
184  read(fd, us->data, statbuf.st_size);
185 #endif
186  us->must_inline = TRUE;
187  break;
188  default:
189  break;
190  }
191  if (us->data)
192  us->datafree = ps_freeimage;
194  }
195 
196  if (us->data) {
197  gvprintf(job, "gsave %g %g translate newpath\n",
198  b.LL.x - (double)(us->x), b.LL.y - (double)(us->y));
199  if (us->must_inline)
200  epsf_emit_body(job, us);
201  else
202  gvprintf(job, "user_shape_%d\n", us->macro_id);
203  gvprintf(job, "grestore\n");
204  }
205 }
206 
207 /* usershape described by a member of a postscript library */
208 static void core_loadimage_pslib(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
209 {
210  int i;
211  pointf AF[4];
212  shape_desc *shape;
213 
214  assert(job);
215  assert(us);
216  assert(us->name);
217 
218  if ((shape = (shape_desc*)us->data)) {
219  AF[0] = b.LL;
220  AF[2] = b.UR;
221  AF[1].x = AF[0].x;
222  AF[1].y = AF[2].y;
223  AF[3].x = AF[2].x;
224  AF[3].y = AF[0].y;
225  if (filled) {
226 // ps_begin_context();
227 // ps_set_color(S[SP].fillcolor);
228  gvprintf(job, "[ ");
229  for (i = 0; i < 4; i++)
230  gvprintf(job, "%g %g ", AF[i].x, AF[i].y);
231  gvprintf(job, "%g %g ", AF[0].x, AF[0].y);
232  gvprintf(job, "] %d true %s\n", 4, us->name);
233 // ps_end_context();
234  }
235  gvprintf(job, "[ ");
236  for (i = 0; i < 4; i++)
237  gvprintf(job, "%g %g ", AF[i].x, AF[i].y);
238  gvprintf(job, "%g %g ", AF[0].x, AF[0].y);
239  gvprintf(job, "] %d false %s\n", 4, us->name);
240  }
241 }
242 
243 static void core_loadimage_vml(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
244 {
245  unsigned int graphHeight;
246  graphHeight =(int)(job->bb.UR.y - job->bb.LL.y);
247  gvprintf (job, "<v:image src=\"%s\" style=\" position:absolute; width:%.2f; height:%.2f; left:%.2f ; top:%.2f\"",
248  us->name, b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, graphHeight-b.UR.y);
249  gvputs(job, " />\n");
250 }
251 
252 static void core_loadimage_tk(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
253 {
254  gvprintf (job, "image create photo \"photo_%s\" -file \"%s\"\n",
255  us->name, us->name);
256  gvprintf (job, "$c create image %.2f %.2f -image \"photo_%s\"\n",
257  us->name, (b.UR.x + b.LL.x) / 2, (b.UR.y + b.LL.y) / 2);
258 }
259 
260 void core_loadimage_null(GVJ_t *gvc, usershape_t *us, boxf b, boolean filled)
261 {
262  /* null function - basically suppress the missing loader message */
263 }
264 
265 static gvloadimage_engine_t engine_svg = {
266  core_loadimage_svg
267 };
268 
269 static gvloadimage_engine_t engine_fig = {
270  core_loadimage_fig
271 };
272 
273 static gvloadimage_engine_t engine_vrml = {
274  core_loadimage_vrml
275 };
276 
277 static gvloadimage_engine_t engine_ps = {
278  core_loadimage_ps
279 };
280 
281 static gvloadimage_engine_t engine_pslib = {
282  core_loadimage_pslib
283 };
284 
285 static gvloadimage_engine_t engine_null = {
287 };
288 
289 static gvloadimage_engine_t engine_xdot = {
291 };
292 
293 static gvloadimage_engine_t engine_vml = {
294  core_loadimage_vml
295 };
296 
297 static gvloadimage_engine_t engine_tk = {
298  core_loadimage_tk
299 };
300 
302  {FORMAT_PNG_SVG, "png:svg", 1, &engine_svg, NULL},
303  {FORMAT_GIF_SVG, "gif:svg", 1, &engine_svg, NULL},
304  {FORMAT_JPEG_SVG, "jpeg:svg", 1, &engine_svg, NULL},
305  {FORMAT_JPEG_SVG, "jpe:svg", 1, &engine_svg, NULL},
306  {FORMAT_JPEG_SVG, "jpg:svg", 1, &engine_svg, NULL},
307 
308  {FORMAT_PNG_FIG, "png:fig", 1, &engine_fig, NULL},
309  {FORMAT_GIF_FIG, "gif:fig", 1, &engine_fig, NULL},
310  {FORMAT_JPEG_FIG, "jpeg:fig", 1, &engine_fig, NULL},
311  {FORMAT_JPEG_FIG, "jpe:fig", 1, &engine_fig, NULL},
312  {FORMAT_JPEG_FIG, "jpg:fig", 1, &engine_fig, NULL},
313 
314  {FORMAT_PNG_VRML, "png:vrml", 1, &engine_vrml, NULL},
315  {FORMAT_GIF_VRML, "gif:vrml", 1, &engine_vrml, NULL},
316  {FORMAT_JPEG_VRML, "jpeg:vrml", 1, &engine_vrml, NULL},
317  {FORMAT_JPEG_VRML, "jpe:vrml", 1, &engine_vrml, NULL},
318  {FORMAT_JPEG_VRML, "jpg:vrml", 1, &engine_vrml, NULL},
319 
320  {FORMAT_PS_PS, "eps:ps", 1, &engine_ps, NULL},
321  {FORMAT_PS_PS, "ps:ps", 1, &engine_ps, NULL},
322  {FORMAT_PSLIB_PS, "(lib):ps", 1, &engine_pslib, NULL}, /* for pslib */
323 
324  {FORMAT_PNG_MAP, "png:map", 1, &engine_null, NULL},
325  {FORMAT_GIF_MAP, "gif:map", 1, &engine_null, NULL},
326  {FORMAT_JPEG_MAP, "jpeg:map", 1, &engine_null, NULL},
327  {FORMAT_JPEG_MAP, "jpe:map", 1, &engine_null, NULL},
328  {FORMAT_JPEG_MAP, "jpg:map", 1, &engine_null, NULL},
329  {FORMAT_PS_MAP, "ps:map", 1, &engine_null, NULL},
330  {FORMAT_PS_MAP, "eps:map", 1, &engine_null, NULL},
331  {FORMAT_SVG_MAP, "svg:map", 1, &engine_null, NULL},
332 
333  {FORMAT_PNG_DOT, "png:dot", 1, &engine_null, NULL},
334  {FORMAT_GIF_DOT, "gif:dot", 1, &engine_null, NULL},
335  {FORMAT_JPEG_DOT, "jpeg:dot", 1, &engine_null, NULL},
336  {FORMAT_JPEG_DOT, "jpe:dot", 1, &engine_null, NULL},
337  {FORMAT_JPEG_DOT, "jpg:dot", 1, &engine_null, NULL},
338  {FORMAT_PS_DOT, "ps:dot", 1, &engine_null, NULL},
339  {FORMAT_PS_DOT, "eps:dot", 1, &engine_null, NULL},
340  {FORMAT_SVG_DOT, "svg:dot", 1, &engine_null, NULL},
341 
342  {FORMAT_PNG_XDOT, "png:xdot", 1, &engine_xdot, NULL},
343  {FORMAT_GIF_XDOT, "gif:xdot", 1, &engine_xdot, NULL},
344  {FORMAT_JPEG_XDOT, "jpeg:xdot", 1, &engine_xdot, NULL},
345  {FORMAT_JPEG_XDOT, "jpe:xdot", 1, &engine_xdot, NULL},
346  {FORMAT_JPEG_XDOT, "jpg:xdot", 1, &engine_xdot, NULL},
347  {FORMAT_PS_XDOT, "ps:xdot", 1, &engine_xdot, NULL},
348  {FORMAT_PS_XDOT, "eps:xdot", 1, &engine_xdot, NULL},
349  {FORMAT_SVG_XDOT, "svg:xdot", 1, &engine_xdot, NULL},
350 
351  {FORMAT_SVG_SVG, "svg:svg", 1, &engine_svg, NULL},
352 
353  {FORMAT_PNG_VML, "png:vml", 1, &engine_vml, NULL},
354  {FORMAT_GIF_VML, "gif:vml", 1, &engine_vml, NULL},
355  {FORMAT_JPEG_VML, "jpeg:vml", 1, &engine_vml, NULL},
356  {FORMAT_JPEG_VML, "jpe:vml", 1, &engine_vml, NULL},
357  {FORMAT_JPEG_VML, "jpg:vml", 1, &engine_vml, NULL},
358 
359  {FORMAT_GIF_TK, "gif:tk", 1, &engine_tk, NULL},
360 
361  {0, NULL, 0, NULL, NULL}
362 };
int rotation
Definition: gvcjob.h:328
void(* datafree)(usershape_t *us)
Definition: usershape.h:51
shape_desc * find_user_shape(char *name)
#define assert(x)
Definition: cghdr.h:48
void * data
Definition: usershape.h:49
Definition: geom.h:30
boolean must_inline
Definition: usershape.h:43
Definition: gvcjob.h:271
point UR
Definition: geom.h:35
int x
Definition: geom.h:28
unsigned int graphHeight
obj_state_t * obj
Definition: gvcjob.h:278
int macro_id
Definition: usershape.h:42
void core_loadimage_null(GVJ_t *gvc, usershape_t *us, boxf b, boolean filled)
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:274
char * malloc()
boolean gvusershape_file_access(usershape_t *us)
Definition: gvusershape.c:588
void free()
int i
Definition: gvdevice.c:448
gvplugin_installed_t gvloadimage_core_types[]
FILE * f
Definition: usershape.h:45
double y
Definition: geom.h:30
size_t datasize
Definition: usershape.h:50
imagetype_t type
Definition: usershape.h:46
void gvusershape_file_release(usershape_t *us)
Definition: gvusershape.c:622
point LL
Definition: geom.h:35
boxf bb
Definition: gvcjob.h:320
void epsf_emit_body(GVJ_t *job, usershape_t *us)
Definition: psusershape.c:185
format_type
#define NULL
Definition: logic.h:50
double x
Definition: geom.h:30
GVC_t * gvc
Definition: htmlparse.c:87
pointf LL
Definition: geom.h:37
union obj_state_s::@23 u
node_t * n
Definition: gvcjob.h:197
void core_loadimage_xdot(GVJ_t *, usershape_t *, boxf, boolean)
int y
Definition: geom.h:28
const char * name
Definition: usershape.h:41
pointf UR
Definition: geom.h:37
Definition: geom.h:37
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:393
Agraph_t * read(FILE *f)
Definition: gv.cpp:73
Definition: geom.h:35
#define TRUE
Definition: cgraph.h:27