Graphviz  2.41.20171026.1811
gvrender_core_dia.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 /* FIXME - incomplete replacement for codegen */
15 
16 #include "config.h"
17 
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 
23 #include "macros.h"
24 #include "const.h"
25 
26 #include "gvplugin_render.h"
27 #include "gvplugin_device.h"
28 #include "gvio.h"
29 #include "gvcint.h"
30 
31 typedef enum { FORMAT_DIA, } format_type;
32 
33 extern char *xml_string(char *str);
34 
35 /* DIA font modifiers */
36 #define REGULAR 0
37 #define BOLD 1
38 #define ITALIC 2
39 
40 /* DIA patterns */
41 #define P_SOLID 0
42 #define P_NONE 15
43 #define P_DOTTED 4 /* i wasn't sure about this */
44 #define P_DASHED 11 /* or this */
45 
46 /* DIA bold line constant */
47 #define WIDTH_NORMAL 1
48 #define WIDTH_BOLD 3
49 
50 #define DIA_RESOLUTION 1.0
51 #define SCALE (DIA_RESOLUTION/15.0)
52 
53 static double Scale;
54 static pointf Offset;
55 static int Rot;
56 static box PB;
57 static int onetime = TRUE;
58 
59 typedef struct context_t {
62  double fontsz;
63 } context_t;
64 
65 #define MAXNEST 4
66 static context_t cstk[MAXNEST];
67 static int SP;
68 
69 #define SVG_COLORS_P 0
70 
71 static int dia_comparestr(const void *s1, const void *s2)
72 {
73  return strcmp(*(char **) s1, *(char **) s2);
74 }
75 
76 static char *dia_resolve_color(char *name)
77 {
78 /* color names from http://www.w3.org/TR/SVG/types.html */
79 /* NB. List must be LANG_C sorted */
80  static char *svg_known_colors[] = {
81  "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
82  "beige", "bisque", "black", "blanchedalmond", "blue",
83  "blueviolet", "brown", "burlywood",
84  "cadetblue", "chartreuse", "chocolate", "coral",
85  "cornflowerblue", "cornsilk", "crimson", "cyan",
86  "darkblue", "darkcyan", "darkgoldenrod", "darkgray",
87  "darkgreen", "darkgrey", "darkkhaki", "darkmagenta",
88  "darkolivegreen", "darkorange", "darkorchid", "darkred",
89  "darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
90  "darkslategrey", "darkturquoise", "darkviolet", "deeppink",
91  "deepskyblue", "dimgray", "dimgrey", "dodgerblue",
92  "firebrick", "floralwhite", "forestgreen", "fuchsia",
93  "gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
94  "green", "greenyellow", "grey",
95  "honeydew", "hotpink", "indianred",
96  "indigo", "ivory", "khaki",
97  "lavender", "lavenderblush", "lawngreen", "lemonchiffon",
98  "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow",
99  "lightgray", "lightgreen", "lightgrey", "lightpink",
100  "lightsalmon", "lightseagreen", "lightskyblue",
101  "lightslategray", "lightslategrey", "lightsteelblue",
102  "lightyellow", "lime", "limegreen", "linen",
103  "magenta", "maroon", "mediumaquamarine", "mediumblue",
104  "mediumorchid", "mediumpurple", "mediumseagreen",
105  "mediumslateblue", "mediumspringgreen", "mediumturquoise",
106  "mediumvioletred", "midnightblue", "mintcream",
107  "mistyrose", "moccasin",
108  "navajowhite", "navy", "oldlace",
109  "olive", "olivedrab", "orange", "orangered", "orchid",
110  "palegoldenrod", "palegreen", "paleturquoise",
111  "palevioletred", "papayawhip", "peachpuff", "peru", "pink",
112  "plum", "powderblue", "purple",
113  "red", "rosybrown", "royalblue",
114  "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell",
115  "sienna", "silver", "skyblue", "slateblue", "slategray",
116  "slategrey", "snow", "springgreen", "steelblue",
117  "tan", "teal", "thistle", "tomato", "turquoise",
118  "violet",
119  "wheat", "white", "whitesmoke",
120  "yellow", "yellowgreen",
121  };
122 
123  static char buf[SMALLBUF];
124  char *tok;
125  gvcolor_t color;
126 
127 // tok = canontoken(name);
128 tok = name;
129  if (!SVG_COLORS_P || (bsearch(&tok, svg_known_colors,
130  sizeof(svg_known_colors) / sizeof(char *),
131  sizeof(char *), dia_comparestr) == NULL)) {
132  /* if tok was not found in known_colors */
133  if (streq(tok, "transparent")) {
134  tok = "none";
135  } else {
136 // colorxlate(name, &color, RGBA_BYTE);
137  sprintf(buf, "#%02x%02x%02x",
138  color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]);
139  tok = buf;
140  }
141  }
142  return tok;
143 }
144 
145 
146 static void dia_reset(void)
147 {
148  onetime = TRUE;
149 }
150 
151 
152 static void init_dia(void)
153 {
154  SP = 0;
155  cstk[0].pencolor = DEFAULT_COLOR; /* DIA pencolor */
156  cstk[0].fillcolor = ""; /* DIA fillcolor */
157  cstk[0].fontfam = DEFAULT_FONTNAME; /* font family name */
158  cstk[0].fontsz = DEFAULT_FONTSIZE; /* font size */
159  cstk[0].fontopt = REGULAR; /* modifier: REGULAR, BOLD or ITALIC */
160  cstk[0].pen = P_SOLID; /* pen pattern style, default is solid */
161  cstk[0].fill = P_NONE;
162  cstk[0].penwidth = WIDTH_NORMAL;
163 }
164 
165 static pointf dia_pt(pointf p)
166 {
167  pointf rv;
168 
169  if (Rot == 0) {
170  rv.x = PB.LL.x + p.x * Scale + Offset.x;
171  rv.y = PB.UR.y - 1 - p.y * Scale - Offset.y;
172  } else {
173  rv.x = PB.UR.x - 1 - p.y * Scale - Offset.x;
174  rv.y = PB.UR.y - 1 - p.x * Scale - Offset.y;
175  }
176  return rv;
177 }
178 
179 static void dia_style(GVJ_t * job, context_t * cp)
180 {
181  if (cp->pencolor != DEFAULT_COLOR) {
182  gvputs(job, " <dia:attribute name=\"border_color\">\n");
183  gvprintf(job, " <dia:color val=\"%s\"/>\n",
184  dia_resolve_color(cp->pencolor));
185  gvputs(job, " </dia:attribute>\n");
186  }
187  if (cp->penwidth != WIDTH_NORMAL) {
188  gvputs(job, " <dia:attribute name=\"line_width\">\n");
189  gvprintf(job, " <dia:real val=\"%g\"/>\n",
190  Scale * (cp->penwidth));
191  gvputs(job, " </dia:attribute>\n");
192  }
193  if (cp->pen == P_DASHED) {
194  gvputs(job, " <dia:attribute name=\"line_style\">\n");
195  gvprintf(job, " <dia:real val=\"%d\"/>\n", 1);
196  gvputs(job, " </dia:attribute>\n");
197 #if 0
198  } else if (cp->pen == P_DOTTED) {
199  gvprintf(job, "stroke-dasharray:%s;", sdotarray);
200 #endif
201  }
202 }
203 
204 static void dia_stylefill(GVJ_t * job, context_t * cp, int filled)
205 {
206  if (filled) {
207  gvputs(job, " <dia:attribute name=\"inner_color\">\n");
208  gvprintf(job, " <dia:color val=\"%s\"/>\n",
209  dia_resolve_color(cp->fillcolor));
210  gvputs(job, " </dia:attribute>\n");
211  } else {
212  gvputs(job, " <dia:attribute name=\"show_background\">\n");
213  gvprintf(job, " <dia:boolean val=\"%s\"/>\n", "true");
214  gvputs(job, " </dia:attribute>\n");
215  }
216 }
217 
218 static void dia_comment(GVJ_t * job, char *str)
219 {
220  gvputs(job, "<!-- ");
221  gvputs(job, xml_string(str));
222  gvputs(job, " -->\n");
223 }
224 
225 static void
226 dia_begin_job(GVJ_t *job)
227 {
228  gvprintf(job, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
229 }
230 
231 static void dia_end_job(GVJ_t *job)
232 {
233 }
234 
235 static void dia_begin_graph(GVJ_t * job)
236 {
237  gvprintf(job, "<dia:diagram xmlns:dia=\"http://www.lysator.liu.se/~alla/dia/\">\n");
238 #if 0
239  Rootgraph = g;
240  PB.LL.x = PB.LL.y = 0;
241  PB.UR.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * SCALE;
242  PB.UR.y = (bb.UR.y - bb.LL.y + 2 * GD_drawing(g)->margin.y) * SCALE;
243  Offset.x = GD_drawing(g)->margin.x * SCALE;
244  Offset.y = GD_drawing(g)->margin.y * SCALE;
245  if (onetime) {
246  init_dia();
247  onetime = FALSE;
248  }
249 #endif
250  gvputs(job, " <dia:diagramdata>\n");
251 
252  gvputs(job, " <dia:attribute name=\"background\">\n");
253  gvputs(job, " <dia:color val=\"#ffffff\"/>\n");
254  gvputs(job, " </dia:attribute>\n");
255 
256  gvputs(job, " <dia:attribute name=\"paper\">\n");
257  gvputs(job, " <dia:composite type=\"paper\">\n");
258  gvputs(job, " <dia:attribute name=\"name\">\n");
259  gvputs(job, " <dia:string>#A4#</dia:string>\n");
260  gvputs(job, " </dia:attribute>\n");
261  gvputs(job, " <dia:attribute name=\"tmargin\">\n");
262  gvputs(job, " <dia:real val=\"2.8222\"/>\n");
263  gvputs(job, " </dia:attribute>\n");
264  gvputs(job, " <dia:attribute name=\"bmargin\">\n");
265  gvputs(job, " <dia:real val=\"2.8222\"/>\n");
266  gvputs(job, " </dia:attribute>\n");
267  gvputs(job, " <dia:attribute name=\"lmargin\">\n");
268  gvputs(job, " <dia:real val=\"2.8222\"/>\n");
269  gvputs(job, " </dia:attribute>\n");
270  gvputs(job, " <dia:attribute name=\"rmargin\">\n");
271  gvputs(job, " <dia:real val=\"2.8222\"/>\n");
272  gvputs(job, " </dia:attribute>\n");
273  gvputs(job, " <dia:attribute name=\"is_portrait\">\n");
274  gvputs(job, " <dia:boolean val=\"true\"/>\n");
275  gvputs(job, " </dia:attribute>\n");
276  gvputs(job, " <dia:attribute name=\"scaling\">\n");
277  gvputs(job, " <dia:real val=\"1\"/>\n");
278  gvputs(job, " </dia:attribute>\n");
279  gvputs(job, " <dia:attribute name=\"fitto\">\n");
280  gvputs(job, " <dia:boolean val=\"false\"/>\n");
281  gvputs(job, " </dia:attribute>\n");
282  gvputs(job, " </dia:composite>\n");
283  gvputs(job, " </dia:attribute>\n");
284 
285  gvputs(job, " <dia:attribute name=\"grid\">\n");
286  gvputs(job, " <dia:composite type=\"grid\">\n");
287  gvputs(job, " <dia:attribute name=\"width_x\">\n");
288  gvputs(job, " <dia:real val=\"1\"/>\n");
289  gvputs(job, " </dia:attribute>\n");
290  gvputs(job, " <dia:attribute name=\"width_y\">\n");
291  gvputs(job, " <dia:real val=\"1\"/>\n");
292  gvputs(job, " </dia:attribute>\n");
293  gvputs(job, " <dia:attribute name=\"visible_x\">\n");
294  gvputs(job, " <dia:int val=\"1\"/>\n");
295  gvputs(job, " </dia:attribute>\n");
296  gvputs(job, " <dia:attribute name=\"visible_y\">\n");
297  gvputs(job, " <dia:int val=\"1\"/>\n");
298  gvputs(job, " </dia:attribute>\n");
299  gvputs(job, " </dia:composite>\n");
300  gvputs(job, " </dia:attribute>\n");
301 
302  gvputs(job, " <dia:attribute name=\"guides\">\n");
303  gvputs(job, " <dia:composite type=\"guides\">\n");
304  gvputs(job, " <dia:attribute name=\"hguides\"/>\n");
305  gvputs(job, " <dia:attribute name=\"vguides\"/>\n");
306  gvputs(job, " </dia:composite>\n");
307  gvputs(job, " </dia:attribute>\n");
308 
309  gvputs(job, " </dia:diagramdata>\n");
310 }
311 
312 static void dia_end_graph(GVJ_t * job)
313 {
314  gvprintf(job, "</dia:diagram>\n");
315 }
316 
317 static void
318 dia_begin_page(GVJ_t * job)
319 {
320  gvprintf(job, " <dia:layer name=\"Background\" visible=\"true\">\n");
321 }
322 
323 static void dia_end_page(GVJ_t * job)
324 {
325  gvputs(job, " </dia:layer>\n");
326 }
327 
328 static void dia_begin_cluster(GVJ_t * job)
329 {
330 // obj_state_t *obj = job->obj;
331 
332  gvprintf(job, " <dia:group>\n");
333 }
334 
335 static void dia_end_cluster(GVJ_t * job)
336 {
337  gvprintf(job, " </dia:group>\n");
338 }
339 
340 static void dia_begin_node(GVJ_t * job)
341 {
342  gvprintf(job, " <dia:group>\n");
343 }
344 
345 static void dia_end_node(GVJ_t * job)
346 {
347  gvprintf(job, " </dia:group>\n");
348 }
349 
350 static void dia_begin_edge(GVJ_t * job)
351 {
352  gvprintf(job, " <dia:group>\n");
353 }
354 
355 static void dia_end_edge(GVJ_t * job)
356 {
357  gvprintf(job, " </dia:group>\n");
358 }
359 
360 static void dia_begin_context(void)
361 {
362  assert(SP + 1 < MAXNEST);
363  cstk[SP + 1] = cstk[SP];
364  SP++;
365 }
366 
367 static void dia_end_context(void)
368 {
369  int psp = SP - 1;
370  assert(SP > 0);
371  /*free(cstk[psp].fontfam); */
372  SP = psp;
373 }
374 
375 static void dia_set_font(char *name, double size)
376 {
377  char *p;
378  context_t *cp;
379 
380  cp = &(cstk[SP]);
381  cp->font_was_set = TRUE;
382  cp->fontsz = size;
383  p = strdup(name);
384  cp->fontfam = p;
385 }
386 
387 static void dia_set_pencolor(char *name)
388 {
389  cstk[SP].pencolor = name;
390 }
391 
392 static void dia_set_fillcolor(char *name)
393 {
394  cstk[SP].fillcolor = name;
395 }
396 
397 static void dia_set_style(char **s)
398 {
399 #if 0
400  char *line, *p;
401  context_t *cp;
402 
403  cp = &(cstk[SP]);
404  while ((p = line = *s++)) {
405  if (streq(line, "solid"))
406  cp->pen = P_SOLID;
407  else if (streq(line, "dashed"))
408  cp->pen = P_DASHED;
409  else if (streq(line, "dotted"))
410  cp->pen = P_DOTTED;
411  else if (streq(line, "invis"))
412  cp->pen = P_NONE;
413  else if (streq(line, "bold"))
414  cp->penwidth = WIDTH_BOLD;
415  else if (streq(line, "setlinewidth")) {
416  while (*p)
417  p++;
418  p++;
419  cp->penwidth = atol(p);
420  } else if (streq(line, "filled"))
421  cp->fill = P_SOLID;
422  else if (streq(line, "unfilled"))
423  cp->fill = P_NONE;
424  else {
425  agwarn("dia_set_style: unsupported style %s - ignoring\n",
426  line);
427  }
428  cp->style_was_set = TRUE;
429  }
430  /* if (cp->style_was_set) dia_style(cp); */
431 #endif
432 }
433 
434 static void dia_textspan(GVJ_t * job, pointf p, textspan_t * span)
435 {
436  obj_state_t *obj = job->obj;
437  PostscriptAlias *pA;
438  int anchor;
439  double size;
440  char *family=NULL, *weight=NULL, *stretch=NULL, *style=NULL;
441 
442  switch (span->just) {
443  case 'l':
444  anchor = 0;
445  break;
446  case 'r':
447  anchor = 2;
448  break;
449  default:
450  case 'n':
451  anchor = 1;
452  break;
453  }
454  p.y += span->yoffset_centerline;
455 
456  pA = span->font->postscript_alias;
457  if (pA) {
458  switch(GD_fontnames(job->gvc->g)) {
459  case PSFONTS:
460  family = pA->name;
461  weight = pA->weight;
462  style = pA->style;
463  break;
464  case SVGFONTS:
465  family = pA->svg_font_family;
466  weight = pA->svg_font_weight;
467  style = pA->svg_font_style;
468  break;
469  default:
470  case NATIVEFONTS:
471  family = pA->family;
472  weight = pA->weight;
473  style = pA->style;
474  break;
475  }
476  stretch = pA->stretch;
477 #if 0
478  gvprintf(job, " font-family=\"%s", family);
479  if (pA->svg_font_family) gvprintf(job, ",%s", pA->svg_font_family);
480  gvputs(job, "\"");
481  if (weight) gvprintf(job, " font-weight=\"%s\"", weight);
482  if (stretch) gvprintf(job, " font-stretch=\"%s\"", stretch);
483  if (style) gvprintf(job, " font-style=\"%s\"", style);
484 #endif
485  }
486  else
487  family = span->fontname;
488  size = span->fontsize;
489 
490 #if 0
491  switch (obj->pencolor.type) {
492  case COLOR_STRING:
493  if (strcasecmp(obj->pencolor.u.string, "black"))
494  gvprintf(job, " fill=\"%s\"", obj->pencolor.u.string);
495  break;
496  case RGBA_BYTE:
497  gvprintf(job, " fill=\"#%02x%02x%02x\"",
498  obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1], obj->pencolor.u.rgba[2]);
499  break;
500  default:
501  assert(0); /* internal error */
502  }
503 #endif
504 
505  gvprintf(job,
506  " <dia:object type=\"Standard - Text\" version=\"0\" id=\"%s\">\n",
507  "0");
508  gvputs(job, " <dia:attribute name=\"text\">\n");
509  gvputs(job, " <dia:composite type=\"text\">\n");
510  gvputs(job, " <dia:attribute name=\"string\">\n");
511  gvputs(job, " <dia:string>#");
512  gvputs(job, xml_string(span->str));
513  gvputs(job, "#</dia:string>\n");
514  gvputs(job, " </dia:attribute>\n");
515  gvputs(job, " <dia:attribute name=\"font\">\n");
516  gvprintf(job, " <dia:font name=\"%s\"/>\n", family);
517  gvputs(job, " </dia:attribute>\n");
518  gvputs(job, " <dia:attribute name=\"height\">\n");
519  gvprintf(job, " <dia:real val=\"%g\"/>\n", size);
520  gvputs(job, " </dia:attribute>\n");
521  gvputs(job, " <dia:attribute name=\"pos\">\n");
522  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
523  gvputs(job, " </dia:attribute>\n");
524  gvputs(job, " <dia:attribute name=\"color\">\n");
525 #if 0
526  gvprintf(job, " <dia:color val=\"%s\"/>\n",
527  dia_resolve_color(cp->pencolor));
528 #else
529  gvprintf(job, " <dia:color val=\"%s\"/>\n",
530  "black");
531 #endif
532  gvputs(job, " </dia:attribute>\n");
533  gvputs(job, " <dia:attribute name=\"alignment\">\n");
534  gvprintf(job, " <dia:enum val=\"%d\"/>\n", anchor);
535  gvputs(job, " </dia:attribute>\n");
536  gvputs(job, " </dia:composite>\n");
537  gvputs(job, " </dia:attribute>\n");
538  gvputs(job, " <dia:attribute name=\"obj_pos\">\n");
539  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
540  gvputs(job, " </dia:attribute>\n");
541 #if 0
542  gvputs(job, " <dia:attribute name=\"obj_bb\">\n");
543  gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
544  p.x - (Scale * (span->size.x) / 2.), p.y - 0.4,
545  p.x + (Scale * (span->size.x) / 2.), p.y + 0.4);
546  gvputs(job, " </dia:attribute>\n");
547 #endif
548  gvputs(job, " </dia:object>\n");
549 }
550 
551 static void dia_ellipse(GVJ_t * job, pointf *A, int filled)
552 {
553 #if 0
554  pointf cp, rp;
555  int nodeId;
556 
557  switch (Obj) {
558  case NODE:
559  nodeId = Curnode->id;
560  break;
561  default:
562  nodeId = -1;
563  break;
564  }
565 
566  if (cstk[SP].pen == P_NONE) {
567  /* its invisible, don't draw */
568  return;
569  }
570  cp = dia_pt(p);
571 
572  if (Rot) {
573  int t;
574  t = rx;
575  rx = ry;
576  ry = t;
577  }
578  rp.x = Scale * rx;
579  rp.y = Scale * ry;
580 
581  gvprintf(job,
582  " <dia:object type=\"Standard - Ellipse\" version=\"0\" id=\"%d\">\n",
583  nodeId);
584  gvputs(job, " <dia:attribute name=\"elem_corner\">\n");
585  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x,
586  cp.y - rp.y);
587  gvputs(job, " </dia:attribute>\n");
588  gvputs(job, " <dia:attribute name=\"elem_width\">\n");
589  gvprintf(job, " <dia:real val=\"%g\"/>\n", rp.x + rp.x);
590  gvputs(job, " </dia:attribute>\n");
591  gvputs(job, " <dia:attribute name=\"elem_height\">\n");
592  gvprintf(job, " <dia:real val=\"%g\"/>\n", rp.y + rp.y);
593  gvputs(job, " </dia:attribute>\n");
594  gvputs(job, " <dia:attribute name=\"obj_pos\">\n");
595  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x,
596  cp.y - rp.y);
597  gvputs(job, " </dia:attribute>\n");
598  gvputs(job, " <dia:attribute name=\"obj_bb\">\n");
599  gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
600  cp.x - rp.x - .11, cp.y - rp.y - .11, cp.x + rp.x + .11,
601  cp.y + rp.y + .11);
602  gvputs(job, " </dia:attribute>\n");
603  dia_style(job, &cstk[SP]);
604  dia_stylefill(job, &cstk[SP], filled);
605  gvputs(job, " </dia:object>\n");
606 #endif
607 }
608 
609 
611 {
612  int conn = 0;
613 #if 0
614  if (cp.x == p.x) {
615  if (cp.y > p.y)
616  conn = 1;
617  else
618  conn = 6;
619  } else if (cp.y == p.y) {
620  if (cp.x > p.x)
621  conn = 3;
622  else
623  conn = 4;
624  } else if (cp.x < p.x) {
625  if (cp.y < p.y)
626  conn = 7;
627  else
628  conn = 2;
629  } else if (cp.x > p.x) {
630  if (cp.y < p.y)
631  conn = 5;
632  else
633  conn = 0;
634  }
635 #endif
636  return conn;
637 }
638 
639 
641 {
642  int conn = 0;
643 #if 0
644  int i = 0, j, sides, conn = 0, peripheries, z;
645  double xsize, ysize, mindist2 = 0.0, dist2;
646  polygon_t *poly;
647  pointf P, *vertices;
648  static point *A;
649  static int A_size;
650 
651  poly = (polygon_t *) ND_shape_info(n);
652  vertices = poly->vertices;
653  sides = poly->sides;
654  peripheries = poly->peripheries;
655 
656  if (A_size < sides) {
657  A_size = sides + 5;
658  A = malloc(A_size*sizeof(pointf));
659  }
660 
661  xsize = ((ND_lw(n) + ND_rw(n)) / POINTS(ND_width(n))) * 16.0;
662  ysize = ((ND_ht(n)) / POINTS(ND_height(n))) * 16.0;
663 
664  for (j = 0; j < peripheries; j++) {
665  for (i = 0; i < sides; i++) {
666  P = vertices[i + j * sides];
667 /* simple rounding produces random results around .5
668  * this trick should clip off the random part.
669  * (note xsize/ysize prescaled by 16.0 above) */
670  A[i].x = ROUND(P.x * xsize) / 16;
671  A[i].y = ROUND(P.y * ysize) / 16;
672  if (sides > 2) {
673  A[i].x += ND_coord_i(n).x;
674  A[i].y += ND_coord_i(n).y;
675  }
676  }
677  }
678 
679  z = 0;
680  while (z < i) {
681  dist2 = DIST2(p, dia_pt(A[z]));
682  if (z == 0) {
683  mindist2 = dist2;
684  conn = 0;
685  }
686  if (dist2 < mindist2) {
687  mindist2 = dist2;
688  conn = 2 * z;
689  }
690  z++;
691  }
692 
693  z = 0;
694  while (z < i) {
695  P.x = (dia_pt(A[z]).x + dia_pt(A[z + 1]).x) / 2;
696  P.y = (dia_pt(A[z]).y + dia_pt(A[z + 1]).y) / 2;
697  dist2 = DIST2(p, P);
698  if (dist2 < mindist2) {
699  mindist2 = dist2;
700  conn = 2 * z + 1;
701  }
702  z++;
703  }
704 #endif
705  return conn;
706 }
707 
708 
709 static void
710 dia_bezier(GVJ_t *job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled)
711 {
712 #if 0
713  int i, conn_h, conn_t;
714  pointf p, firstp = { 0, 0 }, llp = {
715  0, 0}, urp = {
716  0, 0};
717  node_t *head, *tail;
718  char *shape_t;
719  pointf cp_h, cp_t;
720 
721  if (cstk[SP].pen == P_NONE) {
722  /* its invisible, don't draw */
723  return;
724  }
725 
726  gvprintf(job,
727  " <dia:object type=\"Standard - BezierLine\" version=\"0\" id=\"%s\">\n",
728  "00");
729  gvputs(job, " <dia:attribute name=\"bez_points\">\n");
730  for (i = 0; i < n; i++) {
731  p = dia_pt(A[i]);
732  if (!i)
733  llp = urp = firstp = p;
734  if (p.x < llp.x || p.y < llp.y)
735  llp = p;
736  if (p.x > urp.x || p.y > urp.y)
737  urp = p;
738  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
739  }
740  gvputs(job, " </dia:attribute>\n");
741  dia_style(job, &cstk[SP]);
742  gvputs(job, " <dia:attribute name=\"obj_pos\">\n");
743  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
744  gvputs(job, " </dia:attribute>\n");
745  gvputs(job, " <dia:attribute name=\"obj_bb\">\n");
746  gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
747  llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
748  gvputs(job, " </dia:attribute>\n");
749  if (!Curedge) return;
750 
751  conn_h = conn_t = -1;
752 
753  head = Curedge->head;
754  tail = Curedge->tail;
755 
756  shape_t = ND_shape(tail)->name;
757 
758  /* arrowheads */
759  if (arrow_at_start) {
760  gvputs(job, " <dia:attribute name=\"start_arrow\">\n");
761  gvputs(job, " <dia:enum val=\"3\"/>\n");
762  gvputs(job, " </dia:attribute>\n");
763  gvputs(job, " <dia:attribute name=\"start_arrow_length\">\n");
764  gvputs(job, " <dia:real val=\"0.8\"/>\n");
765  gvputs(job, " </dia:attribute>\n");
766  dia_fputs
767  (" <dia:attribute name=\"start_arrow_width\">\n");
768  gvputs(job, " <dia:real val=\"0.8\"/>\n");
769  gvputs(job, " </dia:attribute>\n");
770  }
771  if (arrow_at_end) {
772  gvputs(job, " <dia:attribute name=\"end_arrow\">\n");
773  gvputs(job, " <dia:enum val=\"3\"/>\n");
774  gvputs(job, " </dia:attribute>\n");
775  gvputs(job, " <dia:attribute name=\"end_arrow_length\">\n");
776  gvputs(job, " <dia:real val=\"0.8\"/>\n");
777  gvputs(job, " </dia:attribute>\n");
778  dia_fputs
779  (" <dia:attribute name=\"end_arrow_width\">\n");
780  gvputs(job, " <dia:real val=\"0.8\"/>\n");
781  gvputs(job, " </dia:attribute>\n");
782  }
783 
784  gvputs(job, " <dia:attribute name=\"conn_endpoints\">\n");
785  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", dia_pt(A[0]).x,
786  dia_pt(A[0]).y);
787  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", dia_pt(A[n - 1]).x,
788  dia_pt(A[n - 1]).y);
789  gvputs(job, " </dia:attribute>\n");
790  gvputs(job, " <dia:connections>\n");
791 
792  if ((strcmp(shape_t, "ellipse") == 0)
793  || (strcmp(shape_t, "circle") == 0)
794  || (strcmp(shape_t, "doublecircle") == 0)) {
795  cp_h = dia_pt(ND_coord_i(head));
796  if (AG_IS_DIRECTED(Rootgraph))
797  conn_h = ellipse_connection(cp_h, dia_pt(A[n - 1]));
798  else
799  conn_h = ellipse_connection(cp_h, dia_pt(A[0]));
800  } else {
801  if (AG_IS_DIRECTED(Rootgraph))
802  conn_h = box_connection(head, dia_pt(A[n - 1]));
803  else
804  conn_h = box_connection(head, dia_pt(A[0]));
805  }
806 
807  if ((strcmp(shape_t, "ellipse") == 0)
808  || (strcmp(shape_t, "circle") == 0)
809  || (strcmp(shape_t, "doublecircle") == 0)) {
810  cp_t = dia_pt(ND_coord_i(tail));
811  if (AG_IS_DIRECTED(Rootgraph))
812  conn_t = ellipse_connection(cp_t, dia_pt(A[0]));
813  else
814  conn_t = ellipse_connection(cp_t, dia_pt(A[n - 1]));
815  } else {
816  if (AG_IS_DIRECTED(Rootgraph))
817  conn_t = box_connection(tail, dia_pt(A[0]));
818  else
819  conn_t = box_connection(tail, dia_pt(A[n - 1]));
820  }
821 
822  if (arrow_at_start) {
823  gvprintf(job,
824  " <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n",
825  head->id, conn_h);
826  gvprintf(job,
827  " <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n",
828  (n - 1), tail->id, conn_t);
829  } else {
830  gvprintf(job,
831  " <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n",
832  tail->id, conn_t);
833  gvprintf(job,
834  " <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n",
835  (n - 1), head->id, conn_h);
836  }
837 
838  gvputs(job, " </dia:connections>\n");
839  gvputs(job, " </dia:object>\n");
840 #endif
841 }
842 
843 
844 
845 static void dia_polygon(GVJ_t * job, pointf * A, int n, int filled)
846 {
847 #if 0
848  int i;
849  pointf p, firstp = { 0, 0 }, llp = {
850  0, 0}, urp = {
851  0, 0};
852 
853  if (cstk[SP].pen == P_NONE) {
854  /* its invisible, don't draw */
855  return;
856  }
857 
858  switch (Obj) {
859  case NODE:
860  gvprintf(job,
861  " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%d\">\n",
862  Curnode->id);
863  break;
864  case EDGE:
865  return;
866  break;
867  case CLST:
868  gvprintf(job,
869  " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n",
870  Curgraph->name);
871  break;
872  default:
873  gvprintf(job,
874  " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n",
875  "polygon");
876  break;
877  }
878  gvputs(job, " <dia:attribute name=\"poly_points\">\n");
879  for (i = 0; i < n; i++) {
880  p = dia_pt(A[i]);
881  if (!i)
882  llp = urp = firstp = p;
883  if (p.x < llp.x || p.y < llp.y)
884  llp = p;
885  if (p.x > urp.x || p.y > urp.y)
886  urp = p;
887  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
888  }
889  gvputs(job, " </dia:attribute>\n");
890  gvputs(job, " <dia:attribute name=\"obj_pos\">\n");
891  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
892  gvputs(job, " </dia:attribute>\n");
893  gvputs(job, " <dia:attribute name=\"obj_bb\">\n");
894  gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
895  llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
896  gvputs(job, " </dia:attribute>\n");
897  dia_style(job, &cstk[SP]);
898  dia_stylefill(job, &cstk[SP], filled);
899  gvputs(job, " </dia:object>\n");
900 #endif
901 }
902 
903 static void dia_polyline(GVJ_t * job, pointf * A, int n)
904 {
905 #if 0
906  int i;
907  pointf p, firstp = { 0, 0 }, llp = {
908  0, 0}, urp = {
909  0, 0};
910 
911  if (cstk[SP].pen == P_NONE) {
912  /* its invisible, don't draw */
913  return;
914  }
915  gvprintf(job,
916  " <dia:object type=\"Standard - PolyLine\" version=\"0\" id=\"%s\">\n",
917  "0");
918  gvputs(job, " <dia:attribute name=\"poly_points\">\n");
919  for (i = 0; i < n; i++) {
920  p = dia_pt(A[i]);
921  if (!i)
922  llp = urp = firstp = p;
923  if (p.x < llp.x || p.y < llp.y)
924  llp = p;
925  if (p.x > urp.x || p.y > urp.y)
926  urp = p;
927  gvprintf(job, "<dia:point val=\"%g,%g\"/>\n", p.x, p.y);
928  }
929  gvputs(job, " </dia:attribute>\n");
930  dia_style(job, &cstk[SP]);
931  gvputs(job, " <dia:attribute name=\"obj_pos\">\n");
932  gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
933  gvputs(job, " </dia:attribute>\n");
934  gvputs(job, " <dia:attribute name=\"obj_bb\">\n");
935  gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
936  llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
937  gvputs(job, " </dia:attribute>\n");
938  gvputs(job, " </dia:object>\n");
939 #endif
940 }
941 
943  dia_begin_job, dia_end_job,
944  dia_begin_graph, dia_end_graph,
945  0, /* dia_begin_layer */ 0, /* dia_end_layer */
946  dia_begin_page, dia_end_page,
947  dia_begin_cluster, dia_end_cluster,
948  0, /* dia_begin_nodes */ 0, /* dia_end_nodes */
949  0, /* dia_begin_edges */ 0, /* dia_end_edges */
950  dia_begin_node, dia_end_node,
951  dia_begin_edge, dia_end_edge,
952  0, /* dia_begin_anchor */ 0, /* dia_end_anchor */
953  0, /* dia_begin_label */ 0, /* dia_end_label */
954  dia_textspan, dia_resolve_color,
955  dia_ellipse, dia_polygon,
956  dia_bezier, dia_polyline,
957  dia_comment,
958  0, /* dia_library_shape */
959 };
960 
961 static gvrender_features_t render_features_dia = {
962  0, /* flags */
963  4., /* default pad - graph units */
964  NULL, /* knowncolors */
965  0, /* sizeof knowncolors */
966  HSVA_DOUBLE, /* color_type */
967 };
968 
969 static gvdevice_features_t device_features_dia = {
971  | GVDEVICE_COMPRESSED_FORMAT, /* flags */
972  {0.,0.}, /* default margin - points */
973  {0.,0.}, /* default page width, height - points */
974  {72.,72.}, /* default dpi */
975 };
976 
978  {FORMAT_DIA, "dia", -1, &dia_engine, &render_features_dia},
979  {0, NULL, 0, NULL, NULL}
980 };
981 
983  {FORMAT_DIA, "dia:dia", -1, NULL, &device_features_dia},
984  {0, NULL, 0, NULL, NULL}
985 };
986 
void s1(graph_t *, node_t *)
Definition: stuff.c:686
#define DEFAULT_FONTNAME
Definition: const.h:70
pointf size
Definition: textspan.h:64
#define WIDTH_NORMAL
union color_s::@10 u
#define NODE
Definition: const.h:128
#define head
Definition: dthdr.h:19
char * fillcolor
Definition: diagen.c:72
#define GVDEVICE_BINARY_FORMAT
Definition: gvcjob.h:93
#define SMALLBUF
Definition: const.h:17
char * weight
Definition: textspan.h:35
#define EDGE
Definition: const.h:129
char fill
Definition: diagen.c:73
char * stretch
Definition: textspan.h:36
#define ROUND(f)
Definition: arith.h:84
#define assert(x)
Definition: cghdr.h:47
Definition: geom.h:28
char * fontfam
Definition: diagen.c:72
#define WIDTH_BOLD
#define P_SOLID
char * svg_font_style
Definition: textspan.h:41
graph_t * g
Definition: gvcint.h:106
Definition: color.h:34
char pen
Definition: diagen.c:73
gvcolor_t pencolor
Definition: gvcjob.h:203
Definition: gvcjob.h:271
#define ND_shape_info(n)
Definition: types.h:535
point UR
Definition: geom.h:33
int x
Definition: geom.h:26
#define POINTS(a_inches)
Definition: geom.h:67
#define CLST
Definition: const.h:130
#define SVG_COLORS_P
#define MAXNEST
#define SCALE
obj_state_t * obj
Definition: gvcjob.h:278
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:270
char * str
Definition: textspan.h:59
color_type_t type
Definition: color.h:44
Definition: types.h:276
struct context_t context_t
double fontsz
Definition: diagen.c:74
int box_connection(node_t *n, pointf p)
Definition: diagen.c:682
#define ND_ht(n)
Definition: types.h:506
gvplugin_installed_t gvrender_dia_types[]
#define ND_shape(n)
Definition: types.h:534
#define DIST2(p, q)
Definition: geom.h:59
double y
Definition: geom.h:28
#define GD_fontnames(g)
Definition: types.h:411
char * xml_string(char *s)
Definition: labels.c:485
#define ND_height(n)
Definition: types.h:504
#define DEFAULT_COLOR
Definition: const.h:51
char * string
Definition: color.h:41
gvplugin_installed_t gvdevice_dia_types[]
#define REGULAR
char style_was_set
Definition: diagen.c:73
#define ND_rw(n)
Definition: types.h:531
double yoffset_centerline
Definition: textspan.h:63
PostscriptAlias * postscript_alias
Definition: textspan.h:51
int sides
Definition: types.h:149
point LL
Definition: geom.h:33
char * svg_font_weight
Definition: textspan.h:40
GVC_t * gvc
Definition: gvcjob.h:272
int ellipse_connection(pointf cp, pointf p)
Definition: diagen.c:652
Definition: grammar.c:79
char fontopt
Definition: diagen.c:72
char font_was_set
Definition: diagen.c:72
COORD dist2(Ppoint_t, Ppoint_t)
Definition: visibility.c:213
if(aagss+aagstacksize-1<=aagssp)
Definition: grammar.c:1332
#define ND_width(n)
Definition: types.h:542
format_type
#define ND_lw(n)
Definition: types.h:513
#define NULL
Definition: logic.h:39
Definition: geom.h:26
double x
Definition: geom.h:28
#define streq(s, t)
Definition: cghdr.h:52
char penwidth
Definition: diagen.c:73
int strcasecmp(const char *s1, const char *s2)
Definition: strcasecmp.c:21
char just
Definition: textspan.h:65
char * style
Definition: textspan.h:37
gvrender_engine_t dia_engine
#define GVDEVICE_COMPRESSED_FORMAT
Definition: gvcjob.h:94
int peripheries
Definition: types.h:148
pointf * vertices
Definition: types.h:154
#define DEFAULT_FONTSIZE
Definition: const.h:64
#define P_DASHED
char * svg_font_family
Definition: textspan.h:39
agxbuf * str
Definition: htmlparse.c:85
struct shape_t shape_t
#define GD_drawing(g)
Definition: types.h:356
int y
Definition: geom.h:26
unsigned char rgba[4]
Definition: color.h:38
char * pencolor
Definition: diagen.c:72
char * family
Definition: textspan.h:34
#define FALSE
Definition: cgraph.h:35
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:389
textfont_t * font
Definition: textspan.h:60
#define P_DOTTED
Definition: geom.h:33
#define P_NONE
#define TRUE
Definition: cgraph.h:38