Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
gvrender.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 v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11/*
12 * graphics code generator wrapper
13 *
14 * This library forms the socket for run-time loadable render plugins.
15 */
16
17#include "config.h"
18
19#include <assert.h>
20#include <string.h>
21#include <common/const.h>
22#include <common/macros.h>
23#include <common/colorprocs.h>
24#include <gvc/gvplugin_render.h>
25#include <cgraph/agxbuf.h>
26#include <cgraph/alloc.h>
27#include <cgraph/cgraph.h>
28#include <gvc/gvcint.h>
29#include <common/geom.h>
30#include <common/geomprocs.h>
31#include <common/render.h>
32#include <gvc/gvcproc.h>
33#include <cgraph/strcasecmp.h>
34#include <cgraph/streq.h>
35#include <limits.h>
36#include <stdlib.h>
37
38extern bool mapbool(const char *s);
39
40int gvrender_select(GVJ_t * job, const char *str)
41{
42 GVC_t *gvc = job->gvc;
44 gvplugin_installed_t *typeptr;
45
46 gvplugin_load(gvc, API_device, str, NULL);
47
48 /* When job is created, it is zeroed out.
49 * Some flags, such as OUTPUT_NOT_REQUIRED, may already be set,
50 * so don't reset.
51 */
52 /* job->flags = 0; */
53 plugin = gvc->api[API_device];
54 if (plugin) {
55 typeptr = plugin->typeptr;
56 job->device.engine = typeptr->engine;
57 job->device.features = typeptr->features;
58 job->device.id = typeptr->id;
59 job->device.type = plugin->typestr;
60
61 job->flags |= job->device.features->flags;
62 } else
63 return NO_SUPPORT; /* FIXME - should differentiate problem */
64
65 /* The device plugin has a dependency on a render plugin,
66 * so the render plugin should be available as well now */
67 plugin = gvc->api[API_render];
68 if (plugin) {
69 typeptr = plugin->typeptr;
70 job->render.engine = typeptr->engine;
71 job->render.features = typeptr->features;
72 job->render.type = plugin->typestr;
73
74 job->flags |= job->render.features->flags;
75
76 if (job->device.engine)
77 job->render.id = typeptr->id;
78 else
79 /* A null device engine indicates that the device id is also the renderer id
80 * and that the renderer doesn't need "device" functions.
81 * Device "features" settings are still available */
82 job->render.id = job->device.id;
83 return GVRENDER_PLUGIN;
84 }
85 job->render.engine = NULL;
86 return NO_SUPPORT; /* FIXME - should differentiate problem */
87}
88
90{
91 gvrender_engine_t *gvre = job->render.engine;
92 int features = 0;
93
94 if (gvre) {
95 features = job->render.features->flags;
96 }
97 return features;
98}
99
100/* gvrender_begin_job:
101 * Return 0 on success
102 */
104{
105 gvrender_engine_t *gvre = job->render.engine;
106
107 if (gvdevice_initialize(job))
108 return 1;
109 if (gvre) {
110 if (gvre->begin_job)
111 gvre->begin_job(job);
112 }
113 return 0;
114}
115
117{
118 gvrender_engine_t *gvre = job->render.engine;
119
120 if (gvre) {
121 if (gvre->end_job)
122 gvre->end_job(job);
123 }
124 job->gvc->common.lib = NULL; /* FIXME - minimally this doesn't belong here */
126}
127
128/* font modifiers */
129#define REGULAR 0
130#define BOLD 1
131#define ITALIC 2
132
134{
135 pointf rv, translation, scale;
136
137 translation = job->translation;
138 scale.x = job->zoom * job->devscale.x;
139 scale.y = job->zoom * job->devscale.y;
140
141 if (job->rotation) {
142 rv.x = -(p.y + translation.y) * scale.x;
143 rv.y = (p.x + translation.x) * scale.y;
144 } else {
145 rv.x = (p.x + translation.x) * scale.x;
146 rv.y = (p.y + translation.y) * scale.y;
147 }
148 return rv;
149}
150
151/* transform an array of n points */
152/* *AF and *af must be preallocated */
153/* *AF can be the same as *af for inplace transforms */
154pointf *gvrender_ptf_A(GVJ_t *job, pointf *af, pointf *AF, size_t n) {
155 double t;
156 pointf translation, scale;
157
158 translation = job->translation;
159 scale.x = job->zoom * job->devscale.x;
160 scale.y = job->zoom * job->devscale.y;
161
162 if (job->rotation) {
163 for (size_t i = 0; i < n; i++) {
164 t = -(af[i].y + translation.y) * scale.x;
165 AF[i].y = (af[i].x + translation.x) * scale.y;
166 AF[i].x = t;
167 }
168 } else {
169 for (size_t i = 0; i < n; i++) {
170 AF[i].x = (af[i].x + translation.x) * scale.x;
171 AF[i].y = (af[i].y + translation.y) * scale.y;
172 }
173 }
174 return AF;
175}
176
177static int gvrender_comparestr(const void *s1, const void *s2)
178{
179 return strcmp(s1, *(char *const *) s2);
180}
181
182/* gvrender_resolve_color:
183 * N.B. strcmp cannot be used in bsearch, as it will pass a pointer
184 * to an element in the array features->knowncolors (i.e., a char**)
185 * as an argument of the compare function, while the arguments to
186 * strcmp are both char*.
187 */
189 char *name, gvcolor_t * color)
190{
191 char *tok;
192 int rc;
193
194 color->u.string = name;
195 color->type = COLOR_STRING;
196 tok = canontoken(name);
197 if (!features->knowncolors
198 ||
199 (bsearch(tok, features->knowncolors, features->sz_knowncolors,
200 sizeof(char *), gvrender_comparestr)) == NULL) {
201 /* if tok was not found in known_colors */
202 rc = colorxlate(name, color, features->color_type);
203 if (rc != COLOR_OK) {
204 if (rc == COLOR_UNKNOWN) {
205 agxbuf missedcolor = {0};
206 agxbprint(&missedcolor, "color %s", name);
207 if (emit_once(agxbuse(&missedcolor)))
208 agwarningf("%s is not a known color.\n", name);
209 agxbfree(&missedcolor);
210 } else {
211 agerrorf("error in colxlate()\n");
212 }
213 }
214 }
215 free(tok);
216}
217
219 gvrender_engine_t *gvre = job->render.engine;
220
221 if (gvre) {
222 /* render specific init */
223 if (gvre->begin_graph)
224 gvre->begin_graph(job);
225 }
226}
227
229{
230 gvrender_engine_t *gvre = job->render.engine;
231
232 if (gvre) {
233 if (gvre->end_graph)
234 gvre->end_graph(job);
235 }
236 gvdevice_format(job);
237}
238
240{
241 gvrender_engine_t *gvre = job->render.engine;
242
243 if (gvre) {
244 if (gvre->begin_page)
245 gvre->begin_page(job);
246 }
247}
248
250{
251 gvrender_engine_t *gvre = job->render.engine;
252
253 if (gvre) {
254 if (gvre->end_page)
255 gvre->end_page(job);
256 }
257}
258
260{
261 gvrender_engine_t *gvre = job->render.engine;
262
263 if (gvre) {
264 if (gvre->begin_layer)
265 gvre->begin_layer(job, job->gvc->layerIDs[job->layerNum],
266 job->layerNum, job->numLayers);
267 }
268}
269
271{
272 gvrender_engine_t *gvre = job->render.engine;
273
274 if (gvre) {
275 if (gvre->end_layer)
276 gvre->end_layer(job);
277 }
278}
279
281 gvrender_engine_t *gvre = job->render.engine;
282
283 if (gvre) {
284 if (gvre->begin_cluster)
285 gvre->begin_cluster(job);
286 }
287}
288
290 gvrender_engine_t *gvre = job->render.engine;
291
292 if (gvre) {
293 if (gvre->end_cluster)
294 gvre->end_cluster(job);
295 }
296}
297
299{
300 gvrender_engine_t *gvre = job->render.engine;
301
302 if (gvre) {
303 if (gvre->begin_nodes)
304 gvre->begin_nodes(job);
305 }
306}
307
309{
310 gvrender_engine_t *gvre = job->render.engine;
311
312 if (gvre) {
313 if (gvre->end_nodes)
314 gvre->end_nodes(job);
315 }
316}
317
319{
320 gvrender_engine_t *gvre = job->render.engine;
321
322 if (gvre) {
323 if (gvre->begin_edges)
324 gvre->begin_edges(job);
325 }
326}
327
329{
330 gvrender_engine_t *gvre = job->render.engine;
331
332 if (gvre) {
333 if (gvre->end_edges)
334 gvre->end_edges(job);
335 }
336}
337
339 gvrender_engine_t *gvre = job->render.engine;
340
341 if (gvre) {
342 if (gvre->begin_node)
343 gvre->begin_node(job);
344 }
345}
346
348{
349 gvrender_engine_t *gvre = job->render.engine;
350
351 if (gvre) {
352 if (gvre->end_node)
353 gvre->end_node(job);
354 }
355}
356
358 gvrender_engine_t *gvre = job->render.engine;
359
360 if (gvre) {
361 if (gvre->begin_edge)
362 gvre->begin_edge(job);
363 }
364}
365
367{
368 gvrender_engine_t *gvre = job->render.engine;
369
370 if (gvre) {
371 if (gvre->end_edge)
372 gvre->end_edge(job);
373 }
374}
375
376void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip,
377 char *target, char *id)
378{
379 gvrender_engine_t *gvre = job->render.engine;
380
381 if (gvre) {
382 if (gvre->begin_anchor)
383 gvre->begin_anchor(job, href, tooltip, target, id);
384 }
385}
386
388{
389 gvrender_engine_t *gvre = job->render.engine;
390
391 if (gvre) {
392 if (gvre->end_anchor)
393 gvre->end_anchor(job);
394 }
395}
396
398{
399 gvrender_engine_t *gvre = job->render.engine;
400
401 if (gvre) {
402 if (gvre->begin_label)
403 gvre->begin_label(job, type);
404 }
405}
406
408{
409 gvrender_engine_t *gvre = job->render.engine;
410
411 if (gvre) {
412 if (gvre->end_label)
413 gvre->end_label(job);
414 }
415}
416
418{
419 gvrender_engine_t *gvre = job->render.engine;
420 pointf PF;
421
422 if (span->str && span->str[0]
423 && (!job->obj /* because of xdgen non-conformity */
424 || job->obj->pen != PEN_NONE)) {
426 PF = p;
427 else
428 PF = gvrender_ptf(job, p);
429 if (gvre) {
430 if (gvre->textspan)
431 gvre->textspan(job, PF, span);
432 }
433 }
434}
435
436void gvrender_set_pencolor(GVJ_t * job, char *name)
437{
438 gvrender_engine_t *gvre = job->render.engine;
439 gvcolor_t *color = &(job->obj->pencolor);
440 char *cp = NULL;
441
442 if ((cp = strchr(name, ':'))) // if it’s a color list, then use only first
443 *cp = '\0';
444 if (gvre) {
446 if (gvre->resolve_color)
447 gvre->resolve_color(job, color);
448 }
449 if (cp) /* restore color list */
450 *cp = ':';
451}
452
453void gvrender_set_fillcolor(GVJ_t * job, char *name)
454{
455 gvrender_engine_t *gvre = job->render.engine;
456 gvcolor_t *color = &(job->obj->fillcolor);
457 char *cp = NULL;
458
459 if ((cp = strchr(name, ':'))) // if it’s a color list, then use only first
460 *cp = '\0';
461 if (gvre) {
463 if (gvre->resolve_color)
464 gvre->resolve_color(job, color);
465 }
466 if (cp)
467 *cp = ':';
468}
469
470void gvrender_set_gradient_vals(GVJ_t *job, char *stopcolor, int angle,
471 double frac) {
472 gvrender_engine_t *gvre = job->render.engine;
473 gvcolor_t *color = &(job->obj->stopcolor);
474
475 if (gvre) {
477 if (gvre->resolve_color)
478 gvre->resolve_color(job, color);
479 }
480 job->obj->gradient_angle = angle;
481 job->obj->gradient_frac = frac;
482}
483
484void gvrender_set_style(GVJ_t * job, char **s)
485{
486 gvrender_engine_t *gvre = job->render.engine;
487 obj_state_t *obj = job->obj;
488 char *line, *p;
489
490 obj->rawstyle = s;
491 if (gvre) {
492 if (s)
493 while ((p = line = *s++)) {
494 if (streq(line, "solid"))
495 obj->pen = PEN_SOLID;
496 else if (streq(line, "dashed"))
497 obj->pen = PEN_DASHED;
498 else if (streq(line, "dotted"))
499 obj->pen = PEN_DOTTED;
500 else if (streq(line, "invis") || streq(line, "invisible"))
501 obj->pen = PEN_NONE;
502 else if (streq(line, "bold"))
503 obj->penwidth = PENWIDTH_BOLD;
504 else if (streq(line, "setlinewidth")) {
505 while (*p)
506 p++;
507 p++;
508 obj->penwidth = atof(p);
509 } else if (streq(line, "filled"))
510 obj->fill = FILL_SOLID;
511 else if (streq(line, "unfilled"))
512 obj->fill = FILL_NONE;
513 else if (streq(line, "tapered"));
514 else {
516 "gvrender_set_style: unsupported style %s - ignoring\n",
517 line);
518 }
519 }
520 }
521}
522
523void gvrender_ellipse(GVJ_t *job, pointf *pf, int filled) {
524 gvrender_engine_t *gvre = job->render.engine;
525
526 if (gvre) {
527 if (gvre->ellipse && job->obj->pen != PEN_NONE) {
528 pointf af[] = {
529 mid_pointf(pf[0], pf[1]), // center
530 pf[1] // corner
531 };
532
533 if (!(job->flags & GVRENDER_DOES_TRANSFORM))
534 gvrender_ptf_A(job, af, af, 2);
535 gvre->ellipse(job, af, filled);
536 }
537 }
538}
539
540void gvrender_polygon(GVJ_t *job, pointf *af, size_t n, int filled) {
541 int noPoly = 0;
542 gvcolor_t save_pencolor;
543
544 gvrender_engine_t *gvre = job->render.engine;
545 if (gvre) {
546 if (gvre->polygon && job->obj->pen != PEN_NONE) {
547 if (filled & NO_POLY) {
548 noPoly = 1;
549 filled &= ~NO_POLY;
550 save_pencolor = job->obj->pencolor;
551 job->obj->pencolor = job->obj->fillcolor;
552 }
554 gvre->polygon(job, af, n, filled);
555 else {
556 pointf *AF = gv_calloc(n, sizeof(pointf));
557 gvrender_ptf_A(job, af, AF, n);
558 gvre->polygon(job, AF, n, filled);
559 free(AF);
560 }
561 if (noPoly)
562 job->obj->pencolor = save_pencolor;
563 }
564 }
565}
566
567
568void gvrender_box(GVJ_t * job, boxf B, int filled)
569{
570 pointf A[4];
571
572 A[0] = B.LL;
573 A[2] = B.UR;
574 A[1].x = A[0].x;
575 A[1].y = A[2].y;
576 A[3].x = A[2].x;
577 A[3].y = A[0].y;
578
579 gvrender_polygon(job, A, 4, filled);
580}
581
582void gvrender_beziercurve(GVJ_t *job, pointf *af, size_t n, int filled) {
583 gvrender_engine_t *gvre = job->render.engine;
584
585 if (gvre) {
586 if (gvre->beziercurve && job->obj->pen != PEN_NONE) {
588 gvre->beziercurve(job, af, n, filled);
589 else {
590 pointf *AF = gv_calloc(n, sizeof(pointf));
591 gvrender_ptf_A(job, af, AF, n);
592 gvre->beziercurve(job, AF, n, filled);
593 free(AF);
594 }
595 }
596 }
597}
598
599void gvrender_polyline(GVJ_t *job, pointf *af, size_t n) {
600 gvrender_engine_t *gvre = job->render.engine;
601
602 if (gvre) {
603 if (gvre->polyline && job->obj->pen != PEN_NONE) {
605 gvre->polyline(job, af, n);
606 else {
607 pointf *AF = gv_calloc(n, sizeof(pointf));
608 gvrender_ptf_A(job, af, AF, n);
609 gvre->polyline(job, AF, n);
610 free(AF);
611 }
612 }
613 }
614}
615
616void gvrender_comment(GVJ_t * job, char *str)
617{
618 gvrender_engine_t *gvre = job->render.engine;
619
620 if (!str || !str[0])
621 return;
622
623 if (gvre) {
624 if (gvre->comment)
625 gvre->comment(job, str);
626 }
627}
628
630{
631 if (*s == '\0')
632 return IMAGESCALE_FALSE;
633 if (!strcasecmp(s, "width"))
634 return IMAGESCALE_WIDTH;
635 if (!strcasecmp(s, "height"))
636 return IMAGESCALE_HEIGHT;
637 if (!strcasecmp(s, "both"))
638 return IMAGESCALE_BOTH;
639 if (mapbool(s))
640 return IMAGESCALE_TRUE;
641 return IMAGESCALE_FALSE;
642}
643
645{
646 if (*s == '\0')
648 if (!strcasecmp(s, "tl"))
649 return IMAGEPOS_TOP_LEFT;
650 if (!strcasecmp(s, "tc"))
651 return IMAGEPOS_TOP_CENTER;
652 if (!strcasecmp(s, "tr"))
653 return IMAGEPOS_TOP_RIGHT;
654 if (!strcasecmp(s, "ml"))
656 if (!strcasecmp(s, "mc"))
658 if (!strcasecmp(s, "mr"))
660 if (!strcasecmp(s, "bl"))
662 if (!strcasecmp(s, "bc"))
664 if (!strcasecmp(s, "br"))
667}
668
669/* gvrender_usershape:
670 * Scale image to fill polygon bounding box according to "imagescale",
671 * positioned at "imagepos"
672 */
673void gvrender_usershape(GVJ_t *job, char *name, pointf *a, size_t n,
674 bool filled, char *imagescale, char *imagepos) {
675 gvrender_engine_t *gvre = job->render.engine;
676 usershape_t *us;
677 double iw, ih, pw, ph;
678 double scalex, scaley; /* scale factors */
679 boxf b; /* target box */
680 point isz;
682
683 assert(job);
684 assert(name);
685 assert(name[0]);
686
687 if (!(us = gvusershape_find(name))) {
688 if (find_user_shape(name)) {
689 if (gvre && gvre->library_shape)
690 gvre->library_shape(job, name, a, n, filled);
691 }
692 return;
693 }
694
695 isz = gvusershape_size_dpi(us, job->dpi);
696 if ((isz.x <= 0) && (isz.y <= 0))
697 return;
698
699 /* compute bb of polygon */
700 b.LL = b.UR = a[0];
701 for (size_t i = 1; i < n; i++) {
702 EXPANDBP(b, a[i]);
703 }
704
705 pw = b.UR.x - b.LL.x;
706 ph = b.UR.y - b.LL.y;
707 ih = (double) isz.y;
708 iw = (double) isz.x;
709
710 scalex = pw / iw;
711 scaley = ph / ih;
712
713 switch (get_imagescale(imagescale)) {
714 case IMAGESCALE_TRUE:
715 /* keep aspect ratio fixed by just using the smaller scale */
716 if (scalex < scaley) {
717 iw *= scalex;
718 ih *= scalex;
719 } else {
720 iw *= scaley;
721 ih *= scaley;
722 }
723 break;
724 case IMAGESCALE_WIDTH:
725 iw *= scalex;
726 break;
728 ih *= scaley;
729 break;
730 case IMAGESCALE_BOTH:
731 iw *= scalex;
732 ih *= scaley;
733 break;
734 case IMAGESCALE_FALSE:
735 default:
736 break;
737 }
738
739 /* if image is smaller in any dimension, apply the specified positioning */
740 position = get_imagepos(imagepos);
741 if (iw < pw) {
742 switch (position) {
746 b.UR.x = b.LL.x + iw;
747 break;
751 b.LL.x += (pw - iw);
752 b.UR.x = b.LL.x + iw;
753 break;
754 default:
755 b.LL.x += (pw - iw) / 2.0;
756 b.UR.x -= (pw - iw) / 2.0;
757 break;
758 }
759 }
760 if (ih < ph) {
761 switch (position) {
765 b.LL.y = b.UR.y - ih;
766 break;
770 b.LL.y += ih;
771 b.UR.y = b.LL.y - ih;
772 break;
773 default:
774 b.LL.y += (ph - ih) / 2.0;
775 b.UR.y -= (ph - ih) / 2.0;
776 break;
777 }
778 }
779
780 /* convert from graph to device coordinates */
781 if (!(job->flags & GVRENDER_DOES_TRANSFORM)) {
782 b.LL = gvrender_ptf(job, b.LL);
783 b.UR = gvrender_ptf(job, b.UR);
784 }
785
786 if (b.LL.x > b.UR.x) {
787 double d = b.LL.x;
788 b.LL.x = b.UR.x;
789 b.UR.x = d;
790 }
791 if (b.LL.y > b.UR.y) {
792 double d = b.LL.y;
793 b.LL.y = b.UR.y;
794 b.UR.y = d;
795 }
796 if (gvre) {
797 gvloadimage(job, us, b, filled, job->render.type);
798 }
799}
800
802{
803 gvrender_engine_t *gvre = job->render.engine;
804
805 if (gvre) {
806 job->obj->penwidth = penwidth;
807 }
808}
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:77
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:213
static char * agxbuse(agxbuf *xb)
Definition agxbuf.h:286
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
abstract graph C library, Cgraph API
@ COLOR_STRING
Definition color.h:27
#define COLOR_OK
Definition color.h:44
#define COLOR_UNKNOWN
Definition color.h:43
COLORPROCS_API char * canontoken(char *str)
Definition colxlate.c:129
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:48
#define NO_SUPPORT
Definition const.h:147
#define NO_POLY
Definition const.h:234
#define GVRENDER_PLUGIN
Definition const.h:146
bool emit_once(char *str)
Definition emit.c:3449
expr procedure type
Definition exparse.y:211
#define A(n, t)
Definition expr.h:76
geometric types and macros (e.g. points and boxes)
#define EXPANDBP(b, p)
Definition geom.h:54
geometric functions (e.g. on points and boxes)
static pointf mid_pointf(pointf p, pointf q)
Definition geomprocs.h:81
static pointf scale(double c, pointf p)
Definition geomprocs.h:130
void free(void *)
node NULL
Definition grammar.y:149
void agwarningf(const char *fmt,...)
Definition agerror.c:173
void agerrorf(const char *fmt,...)
Definition agerror.c:165
@ PEN_NONE
Definition gvcjob.h:35
@ PEN_SOLID
Definition gvcjob.h:35
@ PEN_DOTTED
Definition gvcjob.h:35
@ PEN_DASHED
Definition gvcjob.h:35
label_type
Definition gvcjob.h:38
@ FILL_NONE
Definition gvcjob.h:36
@ FILL_SOLID
Definition gvcjob.h:36
#define PENWIDTH_BOLD
Definition gvcjob.h:41
#define GVRENDER_DOES_TRANSFORM
Definition gvcjob.h:95
static void color(Agraph_t *g)
Definition gvcolor.c:128
void gvdevice_finalize(GVJ_t *job)
Definition gvdevice.c:333
usershape_t * gvusershape_find(const char *name)
point gvusershape_size_dpi(usershape_t *us, pointf dpi)
int gvdevice_initialize(GVJ_t *job)
Definition gvdevice.c:115
gvplugin_available_t * gvplugin_load(GVC_t *gvc, api_t api, const char *type, FILE *debug)
Definition gvplugin.c:250
void gvdevice_format(GVJ_t *job)
Definition gvdevice.c:324
void gvloadimage(GVJ_t *job, usershape_t *us, boxf b, bool filled, const char *target)
Definition gvloadimage.c:44
void gvrender_end_nodes(GVJ_t *job)
Definition gvrender.c:308
void gvrender_begin_nodes(GVJ_t *job)
Definition gvrender.c:298
void gvrender_end_job(GVJ_t *job)
Definition gvrender.c:116
void gvrender_beziercurve(GVJ_t *job, pointf *af, size_t n, int filled)
Definition gvrender.c:582
void gvrender_end_label(GVJ_t *job)
Definition gvrender.c:407
void gvrender_usershape(GVJ_t *job, char *name, pointf *a, size_t n, bool filled, char *imagescale, char *imagepos)
Definition gvrender.c:673
void gvrender_comment(GVJ_t *job, char *str)
Definition gvrender.c:616
void gvrender_end_graph(GVJ_t *job)
Definition gvrender.c:228
void gvrender_set_style(GVJ_t *job, char **s)
Definition gvrender.c:484
void gvrender_set_fillcolor(GVJ_t *job, char *name)
Definition gvrender.c:453
void gvrender_begin_edges(GVJ_t *job)
Definition gvrender.c:318
pointf * gvrender_ptf_A(GVJ_t *job, pointf *af, pointf *AF, size_t n)
Definition gvrender.c:154
void gvrender_polygon(GVJ_t *job, pointf *af, size_t n, int filled)
Definition gvrender.c:540
static void gvrender_resolve_color(gvrender_features_t *features, char *name, gvcolor_t *color)
Definition gvrender.c:188
void gvrender_end_edges(GVJ_t *job)
Definition gvrender.c:328
void gvrender_begin_graph(GVJ_t *job)
Definition gvrender.c:218
static int gvrender_comparestr(const void *s1, const void *s2)
Definition gvrender.c:177
bool mapbool(const char *s)
Definition utils.c:336
void gvrender_polyline(GVJ_t *job, pointf *af, size_t n)
Definition gvrender.c:599
pointf gvrender_ptf(GVJ_t *job, pointf p)
Definition gvrender.c:133
void gvrender_end_page(GVJ_t *job)
Definition gvrender.c:249
int gvrender_select(GVJ_t *job, const char *str)
Definition gvrender.c:40
static imagescale_t get_imagescale(char *s)
Definition gvrender.c:629
void gvrender_end_layer(GVJ_t *job)
Definition gvrender.c:270
void gvrender_begin_cluster(GVJ_t *job)
Definition gvrender.c:280
void gvrender_ellipse(GVJ_t *job, pointf *pf, int filled)
Definition gvrender.c:523
void gvrender_set_gradient_vals(GVJ_t *job, char *stopcolor, int angle, double frac)
Definition gvrender.c:470
void gvrender_end_edge(GVJ_t *job)
Definition gvrender.c:366
void gvrender_begin_anchor(GVJ_t *job, char *href, char *tooltip, char *target, char *id)
Definition gvrender.c:376
void gvrender_end_anchor(GVJ_t *job)
Definition gvrender.c:387
void gvrender_begin_layer(GVJ_t *job)
Definition gvrender.c:259
void gvrender_begin_page(GVJ_t *job)
Definition gvrender.c:239
static imagepos_t get_imagepos(char *s)
Definition gvrender.c:644
void gvrender_begin_edge(GVJ_t *job)
Definition gvrender.c:357
void gvrender_textspan(GVJ_t *job, pointf p, textspan_t *span)
Definition gvrender.c:417
void gvrender_begin_node(GVJ_t *job)
Definition gvrender.c:338
void gvrender_box(GVJ_t *job, boxf B, int filled)
Definition gvrender.c:568
int gvrender_begin_job(GVJ_t *job)
Definition gvrender.c:103
void gvrender_begin_label(GVJ_t *job, label_type type)
Definition gvrender.c:397
void gvrender_end_cluster(GVJ_t *job)
Definition gvrender.c:289
void gvrender_set_penwidth(GVJ_t *job, double penwidth)
Definition gvrender.c:801
int gvrender_features(GVJ_t *job)
Definition gvrender.c:89
void gvrender_end_node(GVJ_t *job)
Definition gvrender.c:347
void gvrender_set_pencolor(GVJ_t *job, char *name)
Definition gvrender.c:436
static double penwidth[]
#define B
Definition hierarchy.c:117
GVC_t * gvc
Definition htmlparse.c:99
agxbuf * str
Definition htmlparse.c:97
NEATOPROCS_API void s1(graph_t *, node_t *)
Definition stuff.c:671
shape_desc * find_user_shape(const char *)
Definition shapes.c:3972
platform abstraction for case-insensitive string functions
static bool streq(const char *a, const char *b)
are a and b equal?
Definition streq.h:11
const char ** lib
Definition gvcommon.h:26
Definition gvcint.h:80
GVCOMMON_t common
Definition gvcint.h:81
gvplugin_available_t * api[APIS]
Definition gvcint.h:98
char ** layerIDs
Definition gvcint.h:139
int rotation
Definition gvcjob.h:319
int flags
Definition gvcjob.h:299
pointf dpi
Definition gvcjob.h:325
obj_state_t * obj
Definition gvcjob.h:269
gvplugin_active_device_t device
Definition gvcjob.h:286
gvplugin_active_render_t render
Definition gvcjob.h:285
pointf devscale
Definition gvcjob.h:334
double zoom
Definition gvcjob.h:318
GVC_t * gvc
Definition gvcjob.h:263
int layerNum
Definition gvcjob.h:302
int numLayers
Definition gvcjob.h:301
pointf translation
Definition gvcjob.h:333
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
gvdevice_features_t * features
Definition gvcjob.h:130
gvdevice_engine_t * engine
Definition gvcjob.h:128
const char * type
Definition gvcjob.h:131
gvrender_engine_t * engine
Definition gvcjob.h:135
const char * type
Definition gvcjob.h:138
gvrender_features_t * features
Definition gvcjob.h:137
gvplugin_installed_t * typeptr
Definition gvcint.h:65
ingroup plugin_api
Definition gvplugin.h:35
void(* end_label)(GVJ_t *job)
void(* begin_layer)(GVJ_t *job, char *layername, int layerNum, int numLayers)
void(* begin_anchor)(GVJ_t *job, char *href, char *tooltip, char *target, char *id)
void(* begin_cluster)(GVJ_t *job)
void(* begin_page)(GVJ_t *job)
void(* resolve_color)(GVJ_t *job, gvcolor_t *color)
void(* library_shape)(GVJ_t *job, char *name, pointf *A, size_t n, int filled)
void(* end_job)(GVJ_t *job)
void(* begin_node)(GVJ_t *job)
void(* ellipse)(GVJ_t *job, pointf *A, int filled)
void(* end_page)(GVJ_t *job)
void(* polygon)(GVJ_t *job, pointf *A, size_t n, int filled)
void(* textspan)(GVJ_t *job, pointf p, textspan_t *span)
void(* end_edge)(GVJ_t *job)
void(* end_node)(GVJ_t *job)
void(* end_anchor)(GVJ_t *job)
void(* polyline)(GVJ_t *job, pointf *A, size_t n)
void(* begin_edge)(GVJ_t *job)
void(* begin_nodes)(GVJ_t *job)
void(* end_graph)(GVJ_t *job)
void(* end_layer)(GVJ_t *job)
void(* begin_job)(GVJ_t *job)
void(* begin_edges)(GVJ_t *job)
void(* end_edges)(GVJ_t *job)
void(* end_cluster)(GVJ_t *job)
void(* beziercurve)(GVJ_t *job, pointf *A, size_t n, int)
void(* begin_graph)(GVJ_t *job)
void(* begin_label)(GVJ_t *job, label_type type)
void(* end_nodes)(GVJ_t *job)
void(* comment)(GVJ_t *job, char *comment)
char ** knowncolors
Definition gvcjob.h:113
color_type_t color_type
Definition gvcjob.h:115
gvcolor_t fillcolor
Definition gvcjob.h:194
double gradient_frac
Definition gvcjob.h:196
gvcolor_t stopcolor
Definition gvcjob.h:194
pen_type pen
Definition gvcjob.h:197
gvcolor_t pencolor
Definition gvcjob.h:194
char ** rawstyle
Definition gvcjob.h:200
int gradient_angle
Definition gvcjob.h:195
fill_type fill
Definition gvcjob.h:198
double penwidth
Definition gvcjob.h:199
Definition geom.h:27
int y
Definition geom.h:27
int x
Definition geom.h:27
double x
Definition geom.h:29
double y
Definition geom.h:29
char * str
Definition textspan.h:65
static tok_t tok(const char *input, const char *separators)
begin tokenization of a new string
Definition tokenize.h:43
Definition grammar.c:93
imagepos_t
Definition usershape.h:38
@ IMAGEPOS_MIDDLE_CENTER
Definition usershape.h:43
@ IMAGEPOS_BOTTOM_RIGHT
Definition usershape.h:47
@ IMAGEPOS_TOP_RIGHT
Definition usershape.h:41
@ IMAGEPOS_MIDDLE_LEFT
Definition usershape.h:42
@ IMAGEPOS_TOP_CENTER
Definition usershape.h:40
@ IMAGEPOS_BOTTOM_LEFT
Definition usershape.h:45
@ IMAGEPOS_TOP_LEFT
Definition usershape.h:39
@ IMAGEPOS_BOTTOM_CENTER
Definition usershape.h:46
@ IMAGEPOS_MIDDLE_RIGHT
Definition usershape.h:44
imagescale_t
Definition usershape.h:30
@ IMAGESCALE_BOTH
Definition usershape.h:35
@ IMAGESCALE_WIDTH
Definition usershape.h:33
@ IMAGESCALE_FALSE
Definition usershape.h:31
@ IMAGESCALE_TRUE
Definition usershape.h:32
@ IMAGESCALE_HEIGHT
Definition usershape.h:34
int(* pf)(void *, char *,...)
Definition xdot.c:405