Graphviz 15.1.1~dev.20260628.0906
Loading...
Searching...
No Matches
gvloadimage_core.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "config.h"
12
13#include <stdbool.h>
14#include <stdlib.h>
15#include <sys/stat.h>
16#include <sys/types.h>
17#ifdef HAVE_SYS_MMAN_H
18#include <sys/mman.h>
19#endif
20
21#include "core_loadimage_xdot.h"
22#include <common/utils.h>
23#include <gvc/gvio.h>
25#include <util/agxbuf.h>
26
27extern shape_desc *find_user_shape(char *name);
28
29enum {
58};
59
60static void core_loadimage_svg(GVJ_t *job, usershape_t *us, boxf b,
61 bool filled) {
62 (void)filled;
63
64 double width = (b.UR.x - b.LL.x);
65 double height = (b.UR.y - b.LL.y);
66 double originx = (b.UR.x + b.LL.x - width) / 2;
67 double originy = (b.UR.y + b.LL.y + height) / 2;
68 assert(job);
69 assert(us);
70 assert(us->name);
71
72 gvputs(job, "<image xlink:href=\"");
73 gvputs(job, us->name);
74 if (job->rotation) {
75
76 // FIXME - this is messed up >>>
77 gvprintf(job,
78 "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid "
79 "meet\" x=\"%g\" y=\"%g\"",
80 height, width, originx, -originy);
81 gvprintf(job, " transform=\"rotate(%d %g %g)\"", job->rotation, originx,
82 -originy);
83 // <<<
84 } else {
85 gvprintf(job,
86 "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMinYMin "
87 "meet\" x=\"%g\" y=\"%g\"",
88 width, height, originx, -originy);
89 }
90 gvputs(job, "/>\n");
91}
92
93static void core_loadimage_fig(GVJ_t *job, usershape_t *us, boxf bf,
94 bool filled) {
95 (void)filled;
96
97 int object_code = 2; /* always 2 for polyline */
98 int sub_type = 5; /* always 5 for image */
99 int line_style = 0; /* solid, dotted, dashed */
100 int thickness = 0;
101 int pen_color = 0;
102 int fill_color = -1;
103 int depth = 1;
104 int pen_style = -1; /* not used */
105 int area_fill = 0;
106 double style_val = 0.0;
107 int join_style = 0;
108 int cap_style = 0;
109 int radius = 0;
110 int forward_arrow = 0;
111 int backward_arrow = 0;
112 int npoints = 5;
113 int flipped = 0;
114
115 assert(job);
116 assert(us);
117 assert(us->name);
118
119 gvprintf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n %d %s\n",
120 object_code, sub_type, line_style, thickness, pen_color, fill_color,
121 depth, pen_style, area_fill, style_val, join_style, cap_style,
122 radius, forward_arrow, backward_arrow, npoints, flipped, us->name);
123 gvprintf(job, " %.0f %.0f %.0f %.0f %.0f %.0f %.0f %.0f %.0f %.0f\n", bf.LL.x,
124 bf.LL.y, bf.LL.x, bf.UR.y, bf.UR.x, bf.UR.y, bf.UR.x, bf.LL.y,
125 bf.LL.x, bf.LL.y);
126}
127
128static void core_loadimage_vrml(GVJ_t *job, usershape_t *us, boxf b,
129 bool filled) {
130 (void)b;
131 (void)filled;
132
133 assert(job);
134 assert(job->obj);
135 assert(us);
136 assert(us->name);
137
138 assert(job->obj->u.n);
139
140 gvprintf(job, "Shape {\n");
141 gvprintf(job, " appearance Appearance {\n");
142 gvprintf(job, " material Material {\n");
143 gvprintf(job, " ambientIntensity 0.33\n");
144 gvprintf(job, " diffuseColor 1 1 1\n");
145 gvprintf(job, " }\n");
146 gvprintf(job, " texture ImageTexture { url \"%s\" }\n", us->name);
147 gvprintf(job, " }\n");
148 gvprintf(job, "}\n");
149}
150
151static void ps_freeimage(usershape_t *us) {
152#ifdef HAVE_SYS_MMAN_H
153 munmap(us->data, us->datasize);
154#else
155 free(us->data);
156#endif
157}
158
159/* usershape described by a postscript file */
160static void core_loadimage_ps(GVJ_t *job, usershape_t *us, boxf b,
161 bool filled) {
162 (void)filled;
163
164 assert(job);
165 assert(us);
166 assert(us->name);
167
168 if (us->data) {
169 if (us->datafree != ps_freeimage) {
170 us->datafree(us); /* free incompatible cache data */
171 us->data = NULL;
172 us->datafree = NULL;
173 us->datasize = 0;
174 }
175 }
176
177 if (!us->data) { /* read file into cache */
178 int fd;
179 struct stat statbuf;
180
182 return;
183 fd = fileno(us->f);
184 switch (us->type) {
185 case FT_PS:
186 case FT_EPS:
187 if (fstat(fd, &statbuf) < 0) {
188 us->must_inline = true;
189 break;
190 }
191 us->datasize = (size_t)statbuf.st_size;
192#ifdef HAVE_SYS_MMAN_H
193 us->data = mmap(0, us->datasize, PROT_READ, MAP_PRIVATE, fd, 0);
194 if (us->data == MAP_FAILED)
195 us->data = NULL;
196#else
197 us->data = malloc(statbuf.st_size);
198 if (us->data != NULL)
199 read(fd, us->data, statbuf.st_size);
200#endif
201 us->must_inline = true;
202 break;
203 default:
204 break;
205 }
206 if (us->data)
209 }
210
211 if (us->data) {
212 gvprintf(job, "gsave %g %g translate newpath\n", b.LL.x - us->x,
213 b.LL.y - us->y);
214 if (us->must_inline)
215 epsf_emit_body(job, us);
216 else
217 gvprintf(job, "user_shape_%d\n", us->macro_id);
218 gvprintf(job, "grestore\n");
219 }
220}
221
222/* usershape described by a member of a postscript library */
224 bool filled) {
225 assert(job);
226 assert(us);
227 assert(us->name);
228
229 if (us->data) {
230 const pointf AF[] = {
231 b.LL, {.x = b.LL.x, .y = b.UR.y}, b.UR, {.x = b.UR.x, .y = b.LL.y}};
232 if (filled) {
233 gvprintf(job, "[ ");
234 for (size_t i = 0; i < sizeof(AF) / sizeof(AF[0]); 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 true %s\n", 4, us->name);
238 }
239 gvprintf(job, "[ ");
240 for (size_t i = 0; i < sizeof(AF) / sizeof(AF[0]); i++)
241 gvprintf(job, "%g %g ", AF[i].x, AF[i].y);
242 gvprintf(job, "%g %g ", AF[0].x, AF[0].y);
243 gvprintf(job, "] %d false %s\n", 4, us->name);
244 }
245}
246
247static void core_loadimage_tk(GVJ_t *job, usershape_t *us, boxf b,
248 bool filled) {
249 (void)filled;
250
251 gvprintf(job, "image create photo \"photo_%s\" -file \"%s\"\n", us->name,
252 us->name);
253 gvprintf(job, "$c create image %.2f %.2f -image \"photo_%s\"\n",
254 (b.UR.x + b.LL.x) / 2, (b.UR.y + b.LL.y) / 2, us->name);
255}
256
258 bool filled) {
259 /* null function - basically suppress the missing loader message */
260 (void)gvc;
261 (void)us;
262 (void)b;
263 (void)filled;
264}
265
267
269
271
273
275
277
279
281
283 {FORMAT_PNG_SVG, "png:svg", 1, &engine_svg, NULL},
284 {FORMAT_GIF_SVG, "gif:svg", 1, &engine_svg, NULL},
285 {FORMAT_JPEG_SVG, "jpeg:svg", 1, &engine_svg, NULL},
286 {FORMAT_JPEG_SVG, "jpe:svg", 1, &engine_svg, NULL},
287 {FORMAT_JPEG_SVG, "jpg:svg", 1, &engine_svg, NULL},
288
289 {FORMAT_PNG_FIG, "png:fig", 1, &engine_fig, NULL},
290 {FORMAT_GIF_FIG, "gif:fig", 1, &engine_fig, NULL},
291 {FORMAT_JPEG_FIG, "jpeg:fig", 1, &engine_fig, NULL},
292 {FORMAT_JPEG_FIG, "jpe:fig", 1, &engine_fig, NULL},
293 {FORMAT_JPEG_FIG, "jpg:fig", 1, &engine_fig, NULL},
294
295 {FORMAT_PNG_VRML, "png:vrml", 1, &engine_vrml, NULL},
296 {FORMAT_GIF_VRML, "gif:vrml", 1, &engine_vrml, NULL},
297 {FORMAT_JPEG_VRML, "jpeg:vrml", 1, &engine_vrml, NULL},
298 {FORMAT_JPEG_VRML, "jpe:vrml", 1, &engine_vrml, NULL},
299 {FORMAT_JPEG_VRML, "jpg:vrml", 1, &engine_vrml, NULL},
300
301 {FORMAT_PS_PS, "eps:ps", 1, &engine_ps, NULL},
302 {FORMAT_PS_PS, "ps:ps", 1, &engine_ps, NULL},
303 {FORMAT_PSLIB_PS, "(lib):ps", 1, &engine_pslib, NULL}, /* for pslib */
304
305 {FORMAT_PNG_MAP, "png:map", 1, &engine_null, NULL},
306 {FORMAT_GIF_MAP, "gif:map", 1, &engine_null, NULL},
307 {FORMAT_JPEG_MAP, "jpeg:map", 1, &engine_null, NULL},
308 {FORMAT_JPEG_MAP, "jpe:map", 1, &engine_null, NULL},
309 {FORMAT_JPEG_MAP, "jpg:map", 1, &engine_null, NULL},
310 {FORMAT_PS_MAP, "ps:map", 1, &engine_null, NULL},
311 {FORMAT_PS_MAP, "eps:map", 1, &engine_null, NULL},
312 {FORMAT_SVG_MAP, "svg:map", 1, &engine_null, NULL},
313
314 {FORMAT_PNG_DOT, "png:dot", 1, &engine_null, NULL},
315 {FORMAT_GIF_DOT, "gif:dot", 1, &engine_null, NULL},
316 {FORMAT_JPEG_DOT, "jpeg:dot", 1, &engine_null, NULL},
317 {FORMAT_JPEG_DOT, "jpe:dot", 1, &engine_null, NULL},
318 {FORMAT_JPEG_DOT, "jpg:dot", 1, &engine_null, NULL},
319 {FORMAT_PS_DOT, "ps:dot", 1, &engine_null, NULL},
320 {FORMAT_PS_DOT, "eps:dot", 1, &engine_null, NULL},
321 {FORMAT_SVG_DOT, "svg:dot", 1, &engine_null, NULL},
322
323 {FORMAT_PNG_XDOT, "png:xdot", 1, &engine_xdot, NULL},
324 {FORMAT_GIF_XDOT, "gif:xdot", 1, &engine_xdot, NULL},
325 {FORMAT_JPEG_XDOT, "jpeg:xdot", 1, &engine_xdot, NULL},
326 {FORMAT_JPEG_XDOT, "jpe:xdot", 1, &engine_xdot, NULL},
327 {FORMAT_JPEG_XDOT, "jpg:xdot", 1, &engine_xdot, NULL},
328 {FORMAT_PS_XDOT, "ps:xdot", 1, &engine_xdot, NULL},
329 {FORMAT_PS_XDOT, "eps:xdot", 1, &engine_xdot, NULL},
330 {FORMAT_SVG_XDOT, "svg:xdot", 1, &engine_xdot, NULL},
331
332 {FORMAT_SVG_SVG, "svg:svg", 1, &engine_svg, NULL},
333
334 {FORMAT_GIF_TK, "gif:tk", 1, &engine_tk, NULL},
335
336 {0, NULL, 0, NULL, NULL}};
Dynamically expanding string buffers.
void core_loadimage_xdot(GVJ_t *, usershape_t *, boxf, bool)
void * malloc(YYSIZE_T)
void free(void *)
node NULL
Definition grammar.y:181
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
Agraph_t * read(FILE *f)
Definition gv.cpp:64
static GVC_t * gvc
Definition gv.cpp:27
int gvputs(GVJ_t *job, const char *s)
Definition gvdevice.c:266
void gvprintf(GVJ_t *job, const char *format,...)
Definition gvdevice.c:402
static void core_loadimage_ps(GVJ_t *job, usershape_t *us, boxf b, bool filled)
static gvloadimage_engine_t engine_ps
@ FORMAT_SVG_XDOT
@ FORMAT_PS_MAP
@ FORMAT_GIF_FIG
@ FORMAT_JPEG_SVG
@ FORMAT_PNG_SVG
@ FORMAT_PNG_DOT
@ FORMAT_GIF_MAP
@ FORMAT_SVG_SVG
@ FORMAT_PNG_VRML
@ FORMAT_PS_DOT
@ FORMAT_GIF_XDOT
@ FORMAT_SVG_MAP
@ FORMAT_JPEG_MAP
@ FORMAT_GIF_SVG
@ FORMAT_GIF_DOT
@ FORMAT_PSLIB_PS
@ FORMAT_JPEG_DOT
@ FORMAT_GIF_VRML
@ FORMAT_SVG_DOT
@ FORMAT_PNG_MAP
@ FORMAT_PS_XDOT
@ FORMAT_PNG_FIG
@ FORMAT_JPEG_FIG
@ FORMAT_JPEG_VRML
@ FORMAT_JPEG_XDOT
@ FORMAT_GIF_TK
@ FORMAT_PNG_XDOT
@ FORMAT_PS_PS
static void core_loadimage_pslib(GVJ_t *job, usershape_t *us, boxf b, bool filled)
static gvloadimage_engine_t engine_null
static gvloadimage_engine_t engine_pslib
static void ps_freeimage(usershape_t *us)
static void core_loadimage_svg(GVJ_t *job, usershape_t *us, boxf b, bool filled)
static gvloadimage_engine_t engine_svg
static gvloadimage_engine_t engine_vrml
static gvloadimage_engine_t engine_xdot
static void core_loadimage_fig(GVJ_t *job, usershape_t *us, boxf bf, bool filled)
static gvloadimage_engine_t engine_fig
gvplugin_installed_t gvloadimage_core_types[]
static void core_loadimage_tk(GVJ_t *job, usershape_t *us, boxf b, bool filled)
shape_desc * find_user_shape(char *name)
static gvloadimage_engine_t engine_tk
static void core_loadimage_null(GVJ_t *gvc, usershape_t *us, boxf b, bool filled)
static void core_loadimage_vrml(GVJ_t *job, usershape_t *us, boxf b, bool filled)
void epsf_emit_body(GVJ_t *job, usershape_t *us)
int rotation
Definition gvcjob.h:319
obj_state_t * obj
Definition gvcjob.h:269
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
ingroup plugin_api
Definition gvplugin.h:35
node_t * n
Definition gvcjob.h:188
union obj_state_s::@65 u
double x
Definition geom.h:29
double y
Definition geom.h:29
const char * name
Definition usershape.h:54
FILE * f
Definition usershape.h:58
void(* datafree)(usershape_t *us)
Definition usershape.h:65
size_t datasize
Definition usershape.h:64
bool must_inline
Definition usershape.h:56
void * data
Definition usershape.h:63
imagetype_t type
Definition usershape.h:59
double x
Definition usershape.h:61
double y
Definition usershape.h:61
@ FT_PS
Definition usershape.h:26
@ FT_EPS
Definition usershape.h:26