Graphviz 13.0.0~dev.20241220.2304
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/cgraph.h>
26#include <gvc/gvcint.h>
27#include <common/geom.h>
28#include <common/geomprocs.h>
29#include <common/render.h>
30#include <gvc/gvcproc.h>
31#include <limits.h>
32#include <stdlib.h>
33#include <util/agxbuf.h>
34#include <util/alloc.h>
35#include <util/strcasecmp.h>
36#include <util/streq.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 strcasecmp(s1, *(char *const *)s2);
180}
181
182/* gvrender_resolve_color:
183 * N.B. strcasecmp 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 * strcasecmp are both char*.
187 */
189 char *name, gvcolor_t * color)
190{
191 int rc;
192
193 color->u.string = name;
194 color->type = COLOR_STRING;
195 if (!features->knowncolors
196 ||
197 (bsearch(name, features->knowncolors, features->sz_knowncolors,
198 sizeof(char *), gvrender_comparestr)) == NULL) {
199 /* if name was not found in known_colors */
200 rc = colorxlate(name, color, features->color_type);
201 if (rc != COLOR_OK) {
202 if (rc == COLOR_UNKNOWN) {
203 agxbuf missedcolor = {0};
204 agxbprint(&missedcolor, "color %s", name);
205 if (emit_once(agxbuse(&missedcolor)))
206 agwarningf("%s is not a known color.\n", name);
207 agxbfree(&missedcolor);
208 } else {
209 agerrorf("error in colorxlate()\n");
210 }
211 }
212 }
213}
214
216 gvrender_engine_t *gvre = job->render.engine;
217
218 if (gvre) {
219 /* render specific init */
220 if (gvre->begin_graph)
221 gvre->begin_graph(job);
222 }
223}
224
226{
227 gvrender_engine_t *gvre = job->render.engine;
228
229 if (gvre) {
230 if (gvre->end_graph)
231 gvre->end_graph(job);
232 }
233 gvdevice_format(job);
234}
235
237{
238 gvrender_engine_t *gvre = job->render.engine;
239
240 if (gvre) {
241 if (gvre->begin_page)
242 gvre->begin_page(job);
243 }
244}
245
247{
248 gvrender_engine_t *gvre = job->render.engine;
249
250 if (gvre) {
251 if (gvre->end_page)
252 gvre->end_page(job);
253 }
254}
255
257{
258 gvrender_engine_t *gvre = job->render.engine;
259
260 if (gvre) {
261 if (gvre->begin_layer)
262 gvre->begin_layer(job, job->gvc->layerIDs[job->layerNum],
263 job->layerNum, job->numLayers);
264 }
265}
266
268{
269 gvrender_engine_t *gvre = job->render.engine;
270
271 if (gvre) {
272 if (gvre->end_layer)
273 gvre->end_layer(job);
274 }
275}
276
278 gvrender_engine_t *gvre = job->render.engine;
279
280 if (gvre) {
281 if (gvre->begin_cluster)
282 gvre->begin_cluster(job);
283 }
284}
285
287 gvrender_engine_t *gvre = job->render.engine;
288
289 if (gvre) {
290 if (gvre->end_cluster)
291 gvre->end_cluster(job);
292 }
293}
294
296{
297 gvrender_engine_t *gvre = job->render.engine;
298
299 if (gvre) {
300 if (gvre->begin_nodes)
301 gvre->begin_nodes(job);
302 }
303}
304
306{
307 gvrender_engine_t *gvre = job->render.engine;
308
309 if (gvre) {
310 if (gvre->end_nodes)
311 gvre->end_nodes(job);
312 }
313}
314
316{
317 gvrender_engine_t *gvre = job->render.engine;
318
319 if (gvre) {
320 if (gvre->begin_edges)
321 gvre->begin_edges(job);
322 }
323}
324
326{
327 gvrender_engine_t *gvre = job->render.engine;
328
329 if (gvre) {
330 if (gvre->end_edges)
331 gvre->end_edges(job);
332 }
333}
334
336 gvrender_engine_t *gvre = job->render.engine;
337
338 if (gvre) {
339 if (gvre->begin_node)
340 gvre->begin_node(job);
341 }
342}
343
345{
346 gvrender_engine_t *gvre = job->render.engine;
347
348 if (gvre) {
349 if (gvre->end_node)
350 gvre->end_node(job);
351 }
352}
353
355 gvrender_engine_t *gvre = job->render.engine;
356
357 if (gvre) {
358 if (gvre->begin_edge)
359 gvre->begin_edge(job);
360 }
361}
362
364{
365 gvrender_engine_t *gvre = job->render.engine;
366
367 if (gvre) {
368 if (gvre->end_edge)
369 gvre->end_edge(job);
370 }
371}
372
373void gvrender_begin_anchor(GVJ_t * job, char *href, char *tooltip,
374 char *target, char *id)
375{
376 gvrender_engine_t *gvre = job->render.engine;
377
378 if (gvre) {
379 if (gvre->begin_anchor)
380 gvre->begin_anchor(job, href, tooltip, target, id);
381 }
382}
383
385{
386 gvrender_engine_t *gvre = job->render.engine;
387
388 if (gvre) {
389 if (gvre->end_anchor)
390 gvre->end_anchor(job);
391 }
392}
393
395{
396 gvrender_engine_t *gvre = job->render.engine;
397
398 if (gvre) {
399 if (gvre->begin_label)
400 gvre->begin_label(job, type);
401 }
402}
403
405{
406 gvrender_engine_t *gvre = job->render.engine;
407
408 if (gvre) {
409 if (gvre->end_label)
410 gvre->end_label(job);
411 }
412}
413
415{
416 gvrender_engine_t *gvre = job->render.engine;
417 pointf PF;
418
419 if (span->str && span->str[0]
420 && (!job->obj /* because of xdgen non-conformity */
421 || job->obj->pen != PEN_NONE)) {
423 PF = p;
424 else
425 PF = gvrender_ptf(job, p);
426 if (gvre) {
427 if (gvre->textspan)
428 gvre->textspan(job, PF, span);
429 }
430 }
431}
432
433void gvrender_set_pencolor(GVJ_t * job, char *name)
434{
435 gvrender_engine_t *gvre = job->render.engine;
436 gvcolor_t *color = &(job->obj->pencolor);
437 char *cp = NULL;
438
439 if ((cp = strchr(name, ':'))) // if it’s a color list, then use only first
440 *cp = '\0';
441 if (gvre) {
443 if (gvre->resolve_color)
444 gvre->resolve_color(job, color);
445 }
446 if (cp) /* restore color list */
447 *cp = ':';
448}
449
450void gvrender_set_fillcolor(GVJ_t * job, char *name)
451{
452 gvrender_engine_t *gvre = job->render.engine;
453 gvcolor_t *color = &(job->obj->fillcolor);
454 char *cp = NULL;
455
456 if ((cp = strchr(name, ':'))) // if it’s a color list, then use only first
457 *cp = '\0';
458 if (gvre) {
460 if (gvre->resolve_color)
461 gvre->resolve_color(job, color);
462 }
463 if (cp)
464 *cp = ':';
465}
466
467void gvrender_set_gradient_vals(GVJ_t *job, char *stopcolor, int angle,
468 double frac) {
469 gvrender_engine_t *gvre = job->render.engine;
470 gvcolor_t *color = &(job->obj->stopcolor);
471
472 if (gvre) {
474 if (gvre->resolve_color)
475 gvre->resolve_color(job, color);
476 }
477 job->obj->gradient_angle = angle;
478 job->obj->gradient_frac = frac;
479}
480
481void gvrender_set_style(GVJ_t * job, char **s)
482{
483 gvrender_engine_t *gvre = job->render.engine;
484 obj_state_t *obj = job->obj;
485 char *line, *p;
486
487 obj->rawstyle = s;
488 if (gvre) {
489 if (s)
490 while ((p = line = *s++)) {
491 if (streq(line, "solid"))
492 obj->pen = PEN_SOLID;
493 else if (streq(line, "dashed"))
494 obj->pen = PEN_DASHED;
495 else if (streq(line, "dotted"))
496 obj->pen = PEN_DOTTED;
497 else if (streq(line, "invis") || streq(line, "invisible"))
498 obj->pen = PEN_NONE;
499 else if (streq(line, "bold"))
500 obj->penwidth = PENWIDTH_BOLD;
501 else if (streq(line, "setlinewidth")) {
502 while (*p)
503 p++;
504 p++;
505 obj->penwidth = atof(p);
506 } else if (streq(line, "filled"))
507 obj->fill = FILL_SOLID;
508 else if (streq(line, "unfilled"))
509 obj->fill = FILL_NONE;
510 else if (streq(line, "tapered"));
511 else {
513 "gvrender_set_style: unsupported style %s - ignoring\n",
514 line);
515 }
516 }
517 }
518}
519
520void gvrender_ellipse(GVJ_t *job, pointf *pf, int filled) {
521 gvrender_engine_t *gvre = job->render.engine;
522
523 if (gvre) {
524 if (gvre->ellipse && job->obj->pen != PEN_NONE) {
525 pointf af[] = {
526 mid_pointf(pf[0], pf[1]), // center
527 pf[1] // corner
528 };
529
530 if (!(job->flags & GVRENDER_DOES_TRANSFORM))
531 gvrender_ptf_A(job, af, af, 2);
532 gvre->ellipse(job, af, filled);
533 }
534 }
535}
536
537void gvrender_polygon(GVJ_t *job, pointf *af, size_t n, int filled) {
538 int noPoly = 0;
539 gvcolor_t save_pencolor;
540
541 gvrender_engine_t *gvre = job->render.engine;
542 if (gvre) {
543 if (gvre->polygon && job->obj->pen != PEN_NONE) {
544 if (filled & NO_POLY) {
545 noPoly = 1;
546 filled &= ~NO_POLY;
547 save_pencolor = job->obj->pencolor;
548 job->obj->pencolor = job->obj->fillcolor;
549 }
551 gvre->polygon(job, af, n, filled);
552 else {
553 pointf *AF = gv_calloc(n, sizeof(pointf));
554 gvrender_ptf_A(job, af, AF, n);
555 gvre->polygon(job, AF, n, filled);
556 free(AF);
557 }
558 if (noPoly)
559 job->obj->pencolor = save_pencolor;
560 }
561 }
562}
563
564
565void gvrender_box(GVJ_t * job, boxf B, int filled)
566{
567 pointf A[4];
568
569 A[0] = B.LL;
570 A[2] = B.UR;
571 A[1].x = A[0].x;
572 A[1].y = A[2].y;
573 A[3].x = A[2].x;
574 A[3].y = A[0].y;
575
576 gvrender_polygon(job, A, 4, filled);
577}
578
579void gvrender_beziercurve(GVJ_t *job, pointf *af, size_t n, int filled) {
580 gvrender_engine_t *gvre = job->render.engine;
581
582 if (gvre) {
583 if (gvre->beziercurve && job->obj->pen != PEN_NONE) {
585 gvre->beziercurve(job, af, n, filled);
586 else {
587 pointf *AF = gv_calloc(n, sizeof(pointf));
588 gvrender_ptf_A(job, af, AF, n);
589 gvre->beziercurve(job, AF, n, filled);
590 free(AF);
591 }
592 }
593 }
594}
595
596void gvrender_polyline(GVJ_t *job, pointf *af, size_t n) {
597 gvrender_engine_t *gvre = job->render.engine;
598
599 if (gvre) {
600 if (gvre->polyline && job->obj->pen != PEN_NONE) {
602 gvre->polyline(job, af, n);
603 else {
604 pointf *AF = gv_calloc(n, sizeof(pointf));
605 gvrender_ptf_A(job, af, AF, n);
606 gvre->polyline(job, AF, n);
607 free(AF);
608 }
609 }
610 }
611}
612
613void gvrender_comment(GVJ_t * job, char *str)
614{
615 gvrender_engine_t *gvre = job->render.engine;
616
617 if (!str || !str[0])
618 return;
619
620 if (gvre) {
621 if (gvre->comment)
622 gvre->comment(job, str);
623 }
624}
625
627{
628 if (*s == '\0')
629 return IMAGESCALE_FALSE;
630 if (!strcasecmp(s, "width"))
631 return IMAGESCALE_WIDTH;
632 if (!strcasecmp(s, "height"))
633 return IMAGESCALE_HEIGHT;
634 if (!strcasecmp(s, "both"))
635 return IMAGESCALE_BOTH;
636 if (mapbool(s))
637 return IMAGESCALE_TRUE;
638 return IMAGESCALE_FALSE;
639}
640
642{
643 if (*s == '\0')
645 if (!strcasecmp(s, "tl"))
646 return IMAGEPOS_TOP_LEFT;
647 if (!strcasecmp(s, "tc"))
648 return IMAGEPOS_TOP_CENTER;
649 if (!strcasecmp(s, "tr"))
650 return IMAGEPOS_TOP_RIGHT;
651 if (!strcasecmp(s, "ml"))
653 if (!strcasecmp(s, "mc"))
655 if (!strcasecmp(s, "mr"))
657 if (!strcasecmp(s, "bl"))
659 if (!strcasecmp(s, "bc"))
661 if (!strcasecmp(s, "br"))
664}
665
666/* gvrender_usershape:
667 * Scale image to fill polygon bounding box according to "imagescale",
668 * positioned at "imagepos"
669 */
670void gvrender_usershape(GVJ_t *job, char *name, pointf *a, size_t n,
671 bool filled, char *imagescale, char *imagepos) {
672 gvrender_engine_t *gvre = job->render.engine;
673 usershape_t *us;
674 double iw, ih, pw, ph;
675 double scalex, scaley; /* scale factors */
676 boxf b; /* target box */
677 point isz;
679
680 assert(job);
681 assert(name);
682 assert(name[0]);
683
684 if (!(us = gvusershape_find(name))) {
685 if (find_user_shape(name)) {
686 if (gvre && gvre->library_shape)
687 gvre->library_shape(job, name, a, n, filled);
688 }
689 return;
690 }
691
692 isz = gvusershape_size_dpi(us, job->dpi);
693 if ((isz.x <= 0) && (isz.y <= 0))
694 return;
695
696 /* compute bb of polygon */
697 b.LL = b.UR = a[0];
698 for (size_t i = 1; i < n; i++) {
699 EXPANDBP(b, a[i]);
700 }
701
702 pw = b.UR.x - b.LL.x;
703 ph = b.UR.y - b.LL.y;
704 ih = (double) isz.y;
705 iw = (double) isz.x;
706
707 scalex = pw / iw;
708 scaley = ph / ih;
709
710 switch (get_imagescale(imagescale)) {
711 case IMAGESCALE_TRUE:
712 /* keep aspect ratio fixed by just using the smaller scale */
713 if (scalex < scaley) {
714 iw *= scalex;
715 ih *= scalex;
716 } else {
717 iw *= scaley;
718 ih *= scaley;
719 }
720 break;
721 case IMAGESCALE_WIDTH:
722 iw *= scalex;
723 break;
725 ih *= scaley;
726 break;
727 case IMAGESCALE_BOTH:
728 iw *= scalex;
729 ih *= scaley;
730 break;
731 case IMAGESCALE_FALSE:
732 default:
733 break;
734 }
735
736 /* if image is smaller in any dimension, apply the specified positioning */
737 position = get_imagepos(imagepos);
738 if (iw < pw) {
739 switch (position) {
743 b.UR.x = b.LL.x + iw;
744 break;
748 b.LL.x += (pw - iw);
749 b.UR.x = b.LL.x + iw;
750 break;
751 default:
752 b.LL.x += (pw - iw) / 2.0;
753 b.UR.x -= (pw - iw) / 2.0;
754 break;
755 }
756 }
757 if (ih < ph) {
758 switch (position) {
762 b.LL.y = b.UR.y - ih;
763 break;
767 b.LL.y += ih;
768 b.UR.y = b.LL.y - ih;
769 break;
770 default:
771 b.LL.y += (ph - ih) / 2.0;
772 b.UR.y -= (ph - ih) / 2.0;
773 break;
774 }
775 }
776
777 /* convert from graph to device coordinates */
778 if (!(job->flags & GVRENDER_DOES_TRANSFORM)) {
779 b.LL = gvrender_ptf(job, b.LL);
780 b.UR = gvrender_ptf(job, b.UR);
781 }
782
783 if (b.LL.x > b.UR.x) {
784 double d = b.LL.x;
785 b.LL.x = b.UR.x;
786 b.UR.x = d;
787 }
788 if (b.LL.y > b.UR.y) {
789 double d = b.LL.y;
790 b.LL.y = b.UR.y;
791 b.UR.y = d;
792 }
793 if (gvre) {
794 gvloadimage(job, us, b, filled, job->render.type);
795 }
796}
797
799{
800 gvrender_engine_t *gvre = job->render.engine;
801
802 if (gvre) {
803 job->obj->penwidth = penwidth;
804 }
805}
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
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
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:46
#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:3430
expr procedure type
Definition exparse.y:208
#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:163
void agwarningf(const char *fmt,...)
Definition agerror.c:173
void agerrorf(const char *fmt,...)
Definition agerror.c:165
static GVC_t * gvc
Definition gv.cpp:23
@ 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:129
void gvdevice_finalize(GVJ_t *job)
Definition gvdevice.c:334
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:116
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:325
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:305
void gvrender_begin_nodes(GVJ_t *job)
Definition gvrender.c:295
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:579
void gvrender_end_label(GVJ_t *job)
Definition gvrender.c:404
void gvrender_usershape(GVJ_t *job, char *name, pointf *a, size_t n, bool filled, char *imagescale, char *imagepos)
Definition gvrender.c:670
void gvrender_comment(GVJ_t *job, char *str)
Definition gvrender.c:613
void gvrender_end_graph(GVJ_t *job)
Definition gvrender.c:225
void gvrender_set_style(GVJ_t *job, char **s)
Definition gvrender.c:481
void gvrender_set_fillcolor(GVJ_t *job, char *name)
Definition gvrender.c:450
void gvrender_begin_edges(GVJ_t *job)
Definition gvrender.c:315
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:537
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:325
void gvrender_begin_graph(GVJ_t *job)
Definition gvrender.c:215
static int gvrender_comparestr(const void *s1, const void *s2)
Definition gvrender.c:177
bool mapbool(const char *s)
Definition utils.c:335
void gvrender_polyline(GVJ_t *job, pointf *af, size_t n)
Definition gvrender.c:596
pointf gvrender_ptf(GVJ_t *job, pointf p)
Definition gvrender.c:133
void gvrender_end_page(GVJ_t *job)
Definition gvrender.c:246
int gvrender_select(GVJ_t *job, const char *str)
Definition gvrender.c:40
static imagescale_t get_imagescale(char *s)
Definition gvrender.c:626
void gvrender_end_layer(GVJ_t *job)
Definition gvrender.c:267
void gvrender_begin_cluster(GVJ_t *job)
Definition gvrender.c:277
void gvrender_ellipse(GVJ_t *job, pointf *pf, int filled)
Definition gvrender.c:520
void gvrender_set_gradient_vals(GVJ_t *job, char *stopcolor, int angle, double frac)
Definition gvrender.c:467
void gvrender_end_edge(GVJ_t *job)
Definition gvrender.c:363
void gvrender_begin_anchor(GVJ_t *job, char *href, char *tooltip, char *target, char *id)
Definition gvrender.c:373
void gvrender_end_anchor(GVJ_t *job)
Definition gvrender.c:384
void gvrender_begin_layer(GVJ_t *job)
Definition gvrender.c:256
void gvrender_begin_page(GVJ_t *job)
Definition gvrender.c:236
static imagepos_t get_imagepos(char *s)
Definition gvrender.c:641
void gvrender_begin_edge(GVJ_t *job)
Definition gvrender.c:354
void gvrender_textspan(GVJ_t *job, pointf p, textspan_t *span)
Definition gvrender.c:414
void gvrender_begin_node(GVJ_t *job)
Definition gvrender.c:335
void gvrender_box(GVJ_t *job, boxf B, int filled)
Definition gvrender.c:565
int gvrender_begin_job(GVJ_t *job)
Definition gvrender.c:103
void gvrender_begin_label(GVJ_t *job, label_type type)
Definition gvrender.c:394
void gvrender_end_cluster(GVJ_t *job)
Definition gvrender.c:286
void gvrender_set_penwidth(GVJ_t *job, double penwidth)
Definition gvrender.c:798
int gvrender_features(GVJ_t *job)
Definition gvrender.c:89
void gvrender_end_node(GVJ_t *job)
Definition gvrender.c:344
void gvrender_set_pencolor(GVJ_t *job, char *name)
Definition gvrender.c:433
static double penwidth[]
#define B
Definition hierarchy.c:117
textitem scanner parser str
Definition htmlparse.y:224
NEATOPROCS_API void s1(graph_t *, node_t *)
Definition stuff.c:671
shape_desc * find_user_shape(const char *)
Definition shapes.c:3962
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
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