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