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