Graphviz  2.41.20171026.1811
gvrender_lasi.cpp
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #include "config.h"
15 
16 #include <iostream>
17 #include <fstream>
18 #include <stdexcept>
19 #include <LASi.h>
20 
21 #include "gvplugin_render.h"
22 #include "gvplugin_device.h"
23 #include "gvio.h"
24 #include "gvcint.h"
25 #include "agxbuf.h"
26 #include "const.h"
27 #include "utils.h"
28 #include "ps.h"
29 
30 using namespace LASi;
31 using namespace std;
32 
33 /* for CHAR_LATIN1 */
34 // #include "const.h"
35 
36 /*
37  * J$: added `pdfmark' URL embedding. PostScript rendered from
38  * dot files with URL attributes will get active PDF links
39  * from Adobe's Distiller.
40  */
41 #define PDFMAX 14400 /* Maximum size of PDF page */
42 
44 
45 //static int isLatin1;
46 //static char setupLatin1;
47 
48 PostscriptDocument *doc;
49 size_t (*save_write_fn) (GVJ_t *job, const char *s, size_t len);
50 
51 static size_t lasi_head_writer(GVJ_t * job, const char *s, size_t len)
52 {
53  doc->osHeader() << s;
54  return len;
55 }
56 
57 static size_t lasi_body_writer(GVJ_t * job, const char *s, size_t len)
58 {
59  doc->osBody() << s;
60  return len;
61 }
62 
63 static size_t lasi_footer_writer(GVJ_t * job, const char *s, size_t len)
64 {
65  doc->osFooter() << s;
66  return len;
67 }
68 
69 static void lasi_begin_job(GVJ_t * job)
70 {
71  doc = new PostscriptDocument;
72  save_write_fn = job->gvc->write_fn;
73  job->gvc->write_fn = lasi_head_writer;
74 
75 // gvputs(job, "%!PS-Adobe-3.0 EPSF-3.0\n");
76  gvprintf(job, "%%%%Creator: %s version %s (%s)\n",
77  job->common->info[0], job->common->info[1], job->common->info[2]);
78 }
79 
80 static void lasi_end_job(GVJ_t * job)
81 {
82  job->gvc->write_fn = lasi_footer_writer;
83 
84 // gvputs(job, "%%Trailer\n");
85  if (job->render.id != FORMAT_EPS)
86  gvprintf(job, "%%%%Pages: %d\n", job->common->viewNum);
87  if (job->common->show_boxes == NULL)
88  if (job->render.id != FORMAT_EPS)
89  gvprintf(job, "%%%%BoundingBox: %d %d %d %d\n",
90  job->boundingBox.LL.x, job->boundingBox.LL.y,
91  job->boundingBox.UR.x, job->boundingBox.UR.y);
92  gvputs(job, "end\nrestore\n");
93 // gvputs(job, "%%EOF\n");
94 
95  {
96  // create the new stream to "redirect" cout's output to
97  ostringstream output;
98 
99  // smart class that will swap streambufs and replace them
100  // when object goes out of scope.
101  class StreamBuf_Swapper
102  {
103  public:
104  StreamBuf_Swapper(ostream & orig, ostream & replacement)
105  : buf_(orig.rdbuf()), str_(orig)
106  {
107  orig.rdbuf(replacement.rdbuf());
108  }
109  ~StreamBuf_Swapper()
110  {
111  str_.rdbuf(buf_);
112  }
113  private:
114  std::streambuf * buf_;
115  std::ostream & str_;
116  } swapper(cout, output);
117 
118  doc->write(cout);
119 
120  job->gvc->write_fn = save_write_fn;
121  gvputs(job, output.str().c_str());
122 
123  delete doc;
124  }
125 }
126 
127 static void lasi_begin_graph(GVJ_t * job)
128 {
129  obj_state_t *obj = job->obj;
130 
131  job->gvc->write_fn = lasi_body_writer;
132 
133 // setupLatin1 = FALSE;
134 
135  if (job->common->viewNum == 0) {
136  gvprintf(job, "%%%%Title: %s\n", agnameof(obj->u.g));
137  if (job->render.id != FORMAT_EPS)
138  gvputs(job, "%%Pages: (atend)\n");
139  else
140  gvputs(job, "%%Pages: 1\n");
141  if (job->common->show_boxes == NULL) {
142  if (job->render.id != FORMAT_EPS)
143  gvputs(job, "%%BoundingBox: (atend)\n");
144  else
145  gvprintf(job, "%%%%BoundingBox: %d %d %d %d\n",
146  job->pageBoundingBox.LL.x, job->pageBoundingBox.LL.y,
147  job->pageBoundingBox.UR.x, job->pageBoundingBox.UR.y);
148  }
149  gvputs(job, "%%EndComments\nsave\n");
150  /* include shape library */
151  cat_libfile(job, job->common->lib, ps_txt);
152  /* include epsf */
153  epsf_define(job);
154  if (job->common->show_boxes) {
155  const char* args[2];
156  args[0] = job->common->show_boxes[0];
157  args[1] = NULL;
158  cat_libfile(job, NULL, args);
159  }
160  }
161 // isLatin1 = (GD_charset(obj->u.g) == CHAR_LATIN1);
162  /* We always setup Latin1. The charset info is always output,
163  * and installing it is cheap. With it installed, we can then
164  * rely on ps_string to convert UTF-8 characters whose encoding
165  * is in the range of Latin-1 into the Latin-1 equivalent and
166  * get the expected PostScript output.
167  */
168 // if (!setupLatin1) {
169 // gvputs(job, "setupLatin1\n"); /* as defined in ps header */
170 // setupLatin1 = TRUE;
171 // }
172  /* Set base URL for relative links (for Distiller >= 3.0) */
173  if (obj->url)
174  gvprintf(job, "[ {Catalog} << /URI << /Base %s >> >>\n"
175  "/PUT pdfmark\n", ps_string(obj->url, CHAR_UTF8));
176 }
177 
178 static void lasi_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers)
179 {
180  gvprintf(job, "%d %d setlayer\n", layerNum, numLayers);
181 }
182 
183 static void lasi_begin_page(GVJ_t * job)
184 {
185  box pbr = job->pageBoundingBox;
186 
187  gvprintf(job, "%%%%Page: %d %d\n",
188  job->common->viewNum + 1, job->common->viewNum + 1);
189  if (job->common->show_boxes == NULL)
190  gvprintf(job, "%%%%PageBoundingBox: %d %d %d %d\n",
191  pbr.LL.x, pbr.LL.y, pbr.UR.x, pbr.UR.y);
192  gvprintf(job, "%%%%PageOrientation: %s\n",
193  (job->rotation ? "Landscape" : "Portrait"));
194  if (job->render.id == FORMAT_PS2)
195  gvprintf(job, "<< /PageSize [%d %d] >> setpagedevice\n",
196  pbr.UR.x, pbr.UR.y);
197  gvprintf(job, "%d %d %d beginpage\n",
198  job->pagesArrayElem.x, job->pagesArrayElem.y, job->numPages);
199  if (job->common->show_boxes == NULL)
200  gvprintf(job, "gsave\n%d %d %d %d boxprim clip newpath\n",
201  pbr.LL.x, pbr.LL.y, pbr.UR.x-pbr.LL.x, pbr.UR.y-pbr.LL.y);
202  gvprintf(job, "%g %g set_scale %d rotate %g %g translate\n",
203  job->scale.x, job->scale.y,
204  job->rotation,
205  job->translation.x, job->translation.y);
206 
207  /* Define the size of the PS canvas */
208  if (job->render.id == FORMAT_PS2) {
209  if (pbr.UR.x >= PDFMAX || pbr.UR.y >= PDFMAX)
210  job->common->errorfn("canvas size (%d,%d) exceeds PDF limit (%d)\n"
211  "\t(suggest setting a bounding box size, see dot(1))\n",
212  pbr.UR.x, pbr.UR.y, PDFMAX);
213  gvprintf(job, "[ /CropBox [%d %d %d %d] /PAGES pdfmark\n",
214  pbr.LL.x, pbr.LL.y, pbr.UR.x, pbr.UR.y);
215  }
216 }
217 
218 static void lasi_end_page(GVJ_t * job)
219 {
220  if (job->common->show_boxes) {
221  gvputs(job, "0 0 0 edgecolor\n");
222  cat_libfile(job, NULL, job->common->show_boxes + 1);
223  }
224  /* the showpage is really a no-op, but at least one PS processor
225  * out there needs to see this literal token. endpage does the real work.
226  */
227  gvputs(job, "endpage\nshowpage\ngrestore\n");
228  gvputs(job, "%%PageTrailer\n");
229  gvprintf(job, "%%%%EndPage: %d\n", job->common->viewNum);
230 }
231 
232 static void lasi_begin_cluster(GVJ_t * job)
233 {
234  obj_state_t *obj = job->obj;
235 
236  gvprintf(job, "%% %s\n", agnameof(obj->u.sg));
237  gvputs(job, "gsave\n");
238 }
239 
240 static void lasi_end_cluster(GVJ_t * job)
241 {
242  gvputs(job, "grestore\n");
243 }
244 
245 static void lasi_begin_node(GVJ_t * job)
246 {
247  gvputs(job, "gsave\n");
248 }
249 
250 static void lasi_end_node(GVJ_t * job)
251 {
252  gvputs(job, "grestore\n");
253 }
254 
255 static void
256 lasi_begin_edge(GVJ_t * job)
257 {
258  gvputs(job, "gsave\n");
259 }
260 
261 static void lasi_end_edge(GVJ_t * job)
262 {
263  gvputs(job, "grestore\n");
264 }
265 
266 static void lasi_begin_anchor(GVJ_t *job, char *url, char *tooltip, char *target, char *id)
267 {
268  obj_state_t *obj = job->obj;
269 
270  if (url && obj->url_map_p) {
271  gvputs(job, "[ /Rect [ ");
272  gvprintpointflist(job, obj->url_map_p, 2);
273  gvputs(job, " ]\n");
274  gvprintf(job, " /Border [ 0 0 0 ]\n"
275  " /Action << /Subtype /URI /URI %s >>\n"
276  " /Subtype /Link\n"
277  "/ANN pdfmark\n",
278  ps_string(url, CHAR_UTF8));
279  }
280 }
281 
282 static void ps_set_pen_style(GVJ_t *job)
283 {
284  double penwidth = job->obj->penwidth;
285  char *p, *line, **s = job->obj->rawstyle;
286 
287  gvprintdouble(job, penwidth);
288  gvputs(job," setlinewidth\n");
289 
290  while (s && (p = line = *s++)) {
291  if (strcmp(line, "setlinewidth") == 0)
292  continue;
293  while (*p)
294  p++;
295  p++;
296  while (*p) {
297  gvprintf(job,"%s ", p);
298  while (*p)
299  p++;
300  p++;
301  }
302  if (strcmp(line, "invis") == 0)
303  job->obj->penwidth = 0;
304  gvprintf(job, "%s\n", line);
305  }
306 }
307 
308 static void ps_set_color(GVJ_t *job, gvcolor_t *color)
309 {
310  const char *objtype;
311 
312  if (color) {
313  switch (job->obj->type) {
314  case ROOTGRAPH_OBJTYPE:
315  case CLUSTER_OBJTYPE:
316  objtype = "graph";
317  break;
318  case NODE_OBJTYPE:
319  objtype = "node";
320  break;
321  case EDGE_OBJTYPE:
322  objtype = "edge";
323  break;
324  default:
325  objtype = "sethsb";
326  break;
327  }
328  gvprintf(job, "%.3g %.3g %.3g %scolor\n",
329  color->u.HSVA[0], color->u.HSVA[1], color->u.HSVA[2], objtype);
330  }
331 }
332 
333 static void lasi_textspan(GVJ_t * job, pointf p, textspan_t * span)
334 {
335  char *str;
336  const char *font;
337  const PangoFontDescription *pango_font;
338  FontStretch stretch;
339  FontStyle style;
340  FontVariant variant;
341  FontWeight weight;
342  PostscriptAlias *pA;
343 
344  if (job->obj->pencolor.u.HSVA[3] < .5)
345  return; /* skip transparent text */
346 
347  if (span->layout) {
348  pango_font = pango_layout_get_font_description((PangoLayout*)(span->layout));
349  font = pango_font_description_get_family(pango_font);
350  switch (pango_font_description_get_stretch(pango_font)) {
351  case PANGO_STRETCH_ULTRA_CONDENSED: stretch = ULTRACONDENSED; break;
352  case PANGO_STRETCH_EXTRA_CONDENSED: stretch = EXTRACONDENSED; break;
353  case PANGO_STRETCH_CONDENSED: stretch = CONDENSED; break;
354  case PANGO_STRETCH_SEMI_CONDENSED: stretch = SEMICONDENSED; break;
355  case PANGO_STRETCH_NORMAL: stretch = NORMAL_STRETCH; break;
356  case PANGO_STRETCH_SEMI_EXPANDED: stretch = SEMIEXPANDED; break;
357  case PANGO_STRETCH_EXPANDED: stretch = EXPANDED; break;
358  case PANGO_STRETCH_EXTRA_EXPANDED: stretch = EXTRAEXPANDED; break;
359  case PANGO_STRETCH_ULTRA_EXPANDED: stretch = ULTRAEXPANDED; break;
360  }
361  switch (pango_font_description_get_style(pango_font)) {
362  case PANGO_STYLE_NORMAL: style = NORMAL_STYLE; break;
363  case PANGO_STYLE_OBLIQUE: style = OBLIQUE; break;
364  case PANGO_STYLE_ITALIC: style = ITALIC; break;
365  }
366  switch (pango_font_description_get_variant(pango_font)) {
367  case PANGO_VARIANT_NORMAL: variant = NORMAL_VARIANT; break;
368  case PANGO_VARIANT_SMALL_CAPS: variant = SMALLCAPS; break;
369  }
370  switch (pango_font_description_get_weight(pango_font)) {
371  case PANGO_WEIGHT_ULTRALIGHT: weight = ULTRALIGHT; break;
372  case PANGO_WEIGHT_LIGHT: weight = LIGHT; break;
373  case PANGO_WEIGHT_NORMAL: weight = NORMAL_WEIGHT; break;
374  case PANGO_WEIGHT_SEMIBOLD: weight = BOLD; break; /* no exact match in lasi */
375  case PANGO_WEIGHT_BOLD: weight = BOLD; break;
376  case PANGO_WEIGHT_ULTRABOLD: weight = ULTRABOLD; break;
377  case PANGO_WEIGHT_HEAVY: weight = HEAVY; break;
378  }
379  }
380  else {
381  pA = span->font->postscript_alias;
382  font = pA->svg_font_family;
383  stretch = NORMAL_STRETCH;
384  if (pA->svg_font_style
385  && strcmp(pA->svg_font_style, "italic") == 0)
386  style = ITALIC;
387  else
388  style = NORMAL_STYLE;
389  variant = NORMAL_VARIANT;
390  if (pA->svg_font_weight
391  && strcmp(pA->svg_font_weight, "bold") == 0)
392  weight = BOLD;
393  else
394  weight = NORMAL_WEIGHT;
395  }
396 
397  ps_set_color(job, &(job->obj->pencolor));
398 // gvprintdouble(job, span->font->size);
399 // gvprintf(job, " /%s set_font\n", span->font->name);
400  doc->osBody() << setFont(font, style, weight, variant, stretch) << setFontSize(span->font->size) << endl;
401  switch (span->just) {
402  case 'r':
403  p.x -= span->size.x;
404  break;
405  case 'l':
406  p.x -= 0.0;
407  break;
408  case 'n':
409  default:
410  p.x -= span->size.x / 2.0;
411  break;
412  }
413  p.y += span->yoffset_centerline;
414  gvprintpointf(job, p);
415  gvputs(job, " moveto ");
416 // gvprintdouble(job, span->size.x);
417 // str = ps_string(span->str,isLatin1);
418 // gvprintf(job, " %s alignedtext\n", str);
419  doc->osBody() << show(span->str) << endl;
420 
421 }
422 
423 static void lasi_ellipse(GVJ_t * job, pointf * A, int filled)
424 {
425  /* A[] contains 2 points: the center and corner. */
426  pointf AA[2];
427 
428  AA[0] = A[0];
429  AA[1].x = A[1].x - A[0].x;
430  AA[1].y = A[1].y - A[0].y;
431 
432  if (filled && job->obj->fillcolor.u.HSVA[3] > .5) {
433  ps_set_color(job, &(job->obj->fillcolor));
434  gvprintpointflist(job, AA, 2);
435  gvputs(job, " ellipse_path fill\n");
436  }
437  if (job->obj->pencolor.u.HSVA[3] > .5) {
438  ps_set_pen_style(job);
439  ps_set_color(job, &(job->obj->pencolor));
440  gvprintpointflist(job, AA, 2);
441  gvputs(job, " ellipse_path stroke\n");
442  }
443 }
444 
445 static void
446 lasi_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
447  int arrow_at_end, int filled)
448 {
449  int j;
450 
451  if (filled && job->obj->fillcolor.u.HSVA[3] > .5) {
452  ps_set_color(job, &(job->obj->fillcolor));
453  gvputs(job, "newpath ");
454  gvprintpointf(job, A[0]);
455  gvputs(job, " moveto\n");
456  for (j = 1; j < n; j += 3) {
457  gvprintpointflist(job, &A[j], 3);
458  gvputs(job, " curveto\n");
459  }
460  gvputs(job, "closepath fill\n");
461  }
462  if (job->obj->pencolor.u.HSVA[3] > .5) {
463  ps_set_pen_style(job);
464  ps_set_color(job, &(job->obj->pencolor));
465  gvputs(job, "newpath ");
466  gvprintpointf(job, A[0]);
467  gvputs(job, " moveto\n");
468  for (j = 1; j < n; j += 3) {
469  gvprintpointflist(job, &A[j], 3);
470  gvputs(job, " curveto\n");
471  }
472  gvputs(job, "stroke\n");
473  }
474 }
475 
476 static void lasi_polygon(GVJ_t * job, pointf * A, int n, int filled)
477 {
478  int j;
479 
480  if (filled && job->obj->fillcolor.u.HSVA[3] > .5) {
481  ps_set_color(job, &(job->obj->fillcolor));
482  gvputs(job, "newpath ");
483  gvprintpointf(job, A[0]);
484  gvputs(job, " moveto\n");
485  for (j = 1; j < n; j++) {
486  gvprintpointf(job, A[j]);
487  gvputs(job, " lineto\n");
488  }
489  gvputs(job, "closepath fill\n");
490  }
491  if (job->obj->pencolor.u.HSVA[3] > .5) {
492  ps_set_pen_style(job);
493  ps_set_color(job, &(job->obj->pencolor));
494  gvputs(job, "newpath ");
495  gvprintpointf(job, A[0]);
496  gvputs(job, " moveto\n");
497  for (j = 1; j < n; j++) {
498  gvprintpointf(job, A[j]);
499  gvputs(job, " lineto\n");
500  }
501  gvputs(job, "closepath stroke\n");
502  }
503 }
504 
505 static void lasi_polyline(GVJ_t * job, pointf * A, int n)
506 {
507  int j;
508 
509  if (job->obj->pencolor.u.HSVA[3] > .5) {
510  ps_set_pen_style(job);
511  ps_set_color(job, &(job->obj->pencolor));
512  gvputs(job, "newpath ");
513  gvprintpointf(job, A[0]);
514  gvputs(job, " moveto\n");
515  for (j = 1; j < n; j++) {
516  gvprintpointf(job, A[j]);
517  gvputs(job, " lineto\n");
518  }
519  gvputs(job, "stroke\n");
520  }
521 }
522 
523 static void lasi_comment(GVJ_t * job, char *str)
524 {
525  gvputs(job, "% ");
526  gvputs(job, str);
527  gvputs(job, "\n");
528 }
529 
530 static void lasi_library_shape(GVJ_t * job, char *name, pointf * A, int n, int filled)
531 {
532  if (filled && job->obj->fillcolor.u.HSVA[3] > .5) {
533  ps_set_color(job, &(job->obj->fillcolor));
534  gvputs(job, "[ ");
535  gvprintpointflist(job, A, n);
536  gvputs(job, " ");
537  gvprintpointf(job, A[0]);
538  gvprintf(job, " ] %d true %s\n", n, name);
539  }
540  if (job->obj->pencolor.u.HSVA[3] > .5) {
541  ps_set_pen_style(job);
542  ps_set_color(job, &(job->obj->pencolor));
543  gvputs(job, "[ ");
544  gvprintpointflist(job, A, n);
545  gvputs(job, " ");
546  gvprintpointf(job, A[0]);
547  gvprintf(job, " ] %d false %s\n", n, name);
548  }
549 }
550 
551 static gvrender_engine_t lasi_engine = {
552  lasi_begin_job,
553  lasi_end_job,
554  lasi_begin_graph,
555  0, /* lasi_end_graph */
556  lasi_begin_layer,
557  0, /* lasi_end_layer */
558  lasi_begin_page,
559  lasi_end_page,
560  lasi_begin_cluster,
561  lasi_end_cluster,
562  0, /* lasi_begin_nodes */
563  0, /* lasi_end_nodes */
564  0, /* lasi_begin_edges */
565  0, /* lasi_end_edges */
566  lasi_begin_node,
567  lasi_end_node,
568  lasi_begin_edge,
569  lasi_end_edge,
570  lasi_begin_anchor,
571  0, /* lasi_end_anchor */
572  0, /* lasi_begin_label */
573  0, /* lasi_end_label */
574  lasi_textspan,
575  0, /* lasi_resolve_color */
576  lasi_ellipse,
577  lasi_polygon,
578  lasi_bezier,
579  lasi_polyline,
580  lasi_comment,
581  lasi_library_shape,
582 };
583 
584 static gvrender_features_t render_features_lasi = {
589  4., /* default pad - graph units */
590  NULL, /* knowncolors */
591  0, /* sizeof knowncolors */
592  HSVA_DOUBLE, /* color_type */
593 };
594 
595 static gvdevice_features_t device_features_ps = {
597  | GVDEVICE_DOES_LAYERS, /* flags */
598  {36.,36.}, /* default margin - points */
599  {612.,792.}, /* default page width, height - points */
600  {72.,72.}, /* default dpi */
601 };
602 
603 static gvdevice_features_t device_features_eps = {
604  0, /* flags */
605  {36.,36.}, /* default margin - points */
606  {612.,792.}, /* default page width, height - points */
607  {72.,72.}, /* default dpi */
608 };
609 
611  {FORMAT_PS, "lasi", -5, &lasi_engine, &render_features_lasi},
612  {0, NULL, 0, NULL, NULL}
613 };
614 
616  {FORMAT_PS, "ps:lasi", -5, NULL, &device_features_ps},
617  {FORMAT_PS2, "ps2:lasi", -5, NULL, &device_features_ps},
618  {FORMAT_EPS, "eps:lasi", -5, NULL, &device_features_eps},
619  {0, NULL, 0, NULL, NULL}
620 };
char ** rawstyle
Definition: gvcjob.h:209
pointf size
Definition: textspan.h:64
#define BOLD
Definition: diagen.c:28
int rotation
Definition: gvcjob.h:328
box boundingBox
Definition: gvcjob.h:339
union color_s::@10 u
#define GVDEVICE_DOES_PAGES
Definition: gvcjob.h:89
void gvprintpointflist(GVJ_t *job, pointf *p, int n)
Definition: gvdevice.c:585
#define PDFMAX
double size
Definition: textspan.h:52
Definition: geom.h:28
gvplugin_installed_t gvrender_lasi_types[]
const char ** lib
Definition: gvcommon.h:28
char * svg_font_style
Definition: textspan.h:41
Definition: color.h:34
gvcolor_t pencolor
Definition: gvcjob.h:203
Definition: gvcjob.h:271
point UR
Definition: geom.h:33
char * ps_string(char *ins, int chset)
Definition: psusershape.c:269
int x
Definition: geom.h:26
#define GVRENDER_DOES_MAP_RECTANGLE
Definition: gvcjob.h:101
#define GVRENDER_DOES_TRANSFORM
Definition: gvcjob.h:97
PostscriptDocument * doc
obj_state_t * obj
Definition: gvcjob.h:278
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:270
box pageBoundingBox
Definition: gvcjob.h:338
char * str
Definition: textspan.h:59
int viewNum
Definition: gvcommon.h:31
gvplugin_active_render_t render
Definition: gvcjob.h:294
#define GVDEVICE_DOES_LAYERS
Definition: gvcjob.h:90
void epsf_define(GVJ_t *job)
Definition: psusershape.c:221
#define CHAR_UTF8
Definition: const.h:204
double y
Definition: geom.h:28
const char ** show_boxes
Definition: gvcommon.h:27
void cat_libfile(GVJ_t *job, const char **arglib, const char **stdlib)
Definition: psusershape.c:139
pointf * url_map_p
Definition: gvcjob.h:249
CGRAPH_API char * agnameof(void *)
Definition: id.c:143
obj_type type
Definition: gvcjob.h:193
char * url
Definition: gvcjob.h:219
pointf scale
Definition: gvcjob.h:341
GVCOMMON_t * common
Definition: gvcjob.h:276
char ** info
Definition: gvcommon.h:22
point pagesArrayElem
Definition: gvcjob.h:317
void gvprintpointf(GVJ_t *job, pointf p)
Definition: gvdevice.c:573
double yoffset_centerline
Definition: textspan.h:63
PostscriptAlias * postscript_alias
Definition: textspan.h:51
point LL
Definition: geom.h:33
char * svg_font_weight
Definition: textspan.h:40
GVC_t * gvc
Definition: gvcjob.h:272
#define ITALIC
Definition: diagen.c:29
Definition: grammar.c:79
graph_t * g
Definition: gvcjob.h:195
void(* errorfn)(const char *fmt,...)
Definition: gvcommon.h:26
double HSVA[4]
Definition: color.h:37
#define GVRENDER_NO_WHITE_BG
Definition: gvcjob.h:109
void gvprintdouble(GVJ_t *job, double num)
Definition: gvdevice.c:557
format_type
#define GVRENDER_DOES_MAPS
Definition: gvcjob.h:100
#define NULL
Definition: logic.h:39
pointf translation
Definition: gvcjob.h:342
graph_t * sg
Definition: gvcjob.h:196
double x
Definition: geom.h:28
size_t(* save_write_fn)(GVJ_t *job, const char *s, size_t len)
int numPages
Definition: gvcjob.h:318
char just
Definition: textspan.h:65
union obj_state_s::@23 u
char * svg_font_family
Definition: textspan.h:39
agxbuf * str
Definition: htmlparse.c:85
gvcolor_t fillcolor
Definition: gvcjob.h:203
double penwidth
Definition: gvcjob.h:208
int y
Definition: geom.h:26
gvplugin_installed_t gvdevice_lasi_types[]
size_t(* write_fn)(GVJ_t *job, const char *s, size_t len)
Definition: gvcint.h:92
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:389
textfont_t * font
Definition: textspan.h:60
Definition: geom.h:33
void * layout
Definition: textspan.h:61