1
/* $Id: diagen.c,v 1.25 2008/04/23 18:05:06 ellson Exp $ $Revision: 1.25 $ */
2
/* vim:set shiftwidth=4 ts=8: */
4
/**********************************************************
5
* This software is part of the graphviz package *
6
* http://www.graphviz.org/ *
8
* Copyright (c) 1994-2004 AT&T Corp. *
9
* and is licensed under the *
10
* Common Public License, Version 1.0 *
13
* Information and Software Systems Research *
14
* AT&T Research, Florham Park NJ *
15
**********************************************************/
31
/* DIA font modifiers */
39
#define P_DOTTED 4 /* i wasn't sure about this */
40
#define P_DASHED 11 /* or this */
42
/* DIA bold line constant */
43
#define WIDTH_NORMAL 1
46
#define DIA_RESOLUTION 1.0
47
#define SCALE (DIA_RESOLUTION/15.0)
54
/* FIXME - these are not used currently - probably something missing */
57
static char *sdarray = "5,2";
59
static char *sdotarray = "1,5";
60
static int GraphURL, ClusterURL, NodeURL, EdgeURL;
61
static char *op[] = { "graph", "node", "edge", "graph" };
64
/* static int N_pages; */
65
/* static point Pages; */
70
static int onetime = TRUE;
72
static node_t *Curnode;
73
static edge_t *Curedge;
74
static graph_t *Curgraph, *Rootgraph;
76
typedef struct context_t {
77
char *pencolor, *fillcolor, *fontfam, fontopt, font_was_set;
78
char pen, fill, penwidth, style_was_set;
83
static context_t cstk[MAXNEST];
90
static int dia_fputs(char *s)
97
return gzwrite(Zfile, s, (unsigned) len);
105
* Note that this function is unsafe due to the fixed buffer size.
106
* It should only be used when the caller is sure the input will not
107
* overflow the buffer. In particular, it should be avoided for
108
* input coming from users. Also, if vsnprintf is available, the
109
* code should check for return values to use it safely.
111
static int dia_printf(const char *format, ...)
117
va_start(argp, format);
118
#ifdef HAVE_VSNPRINTF
119
(void) vsnprintf(buf, sizeof(buf), format, argp);
121
(void) vsprintf(buf, format, argp);
126
/* some *sprintf (e.g C99 std)
127
don't return the number of
128
bytes actually written */
131
return gzwrite(Zfile, buf, (unsigned) len);
137
#define SVG_COLORS_P 0
139
static int dia_comparestr(const void *s1, const void *s2)
141
return strcmp(*(char **) s1, *(char **) s2);
144
static char *dia_resolve_color(char *name)
146
/* color names from http://www.w3.org/TR/SVG/types.html */
147
/* NB. List must be LANG_C sorted */
148
static char *svg_known_colors[] = {
149
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
150
"beige", "bisque", "black", "blanchedalmond", "blue",
151
"blueviolet", "brown", "burlywood",
152
"cadetblue", "chartreuse", "chocolate", "coral",
153
"cornflowerblue", "cornsilk", "crimson", "cyan",
154
"darkblue", "darkcyan", "darkgoldenrod", "darkgray",
155
"darkgreen", "darkgrey", "darkkhaki", "darkmagenta",
156
"darkolivegreen", "darkorange", "darkorchid", "darkred",
157
"darksalmon", "darkseagreen", "darkslateblue", "darkslategray",
158
"darkslategrey", "darkturquoise", "darkviolet", "deeppink",
159
"deepskyblue", "dimgray", "dimgrey", "dodgerblue",
160
"firebrick", "floralwhite", "forestgreen", "fuchsia",
161
"gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
162
"green", "greenyellow", "grey",
163
"honeydew", "hotpink", "indianred",
164
"indigo", "ivory", "khaki",
165
"lavender", "lavenderblush", "lawngreen", "lemonchiffon",
166
"lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow",
167
"lightgray", "lightgreen", "lightgrey", "lightpink",
168
"lightsalmon", "lightseagreen", "lightskyblue",
169
"lightslategray", "lightslategrey", "lightsteelblue",
170
"lightyellow", "lime", "limegreen", "linen",
171
"magenta", "maroon", "mediumaquamarine", "mediumblue",
172
"mediumorchid", "mediumpurple", "mediumseagreen",
173
"mediumslateblue", "mediumspringgreen", "mediumturquoise",
174
"mediumvioletred", "midnightblue", "mintcream",
175
"mistyrose", "moccasin",
176
"navajowhite", "navy", "oldlace",
177
"olive", "olivedrab", "orange", "orangered", "orchid",
178
"palegoldenrod", "palegreen", "paleturquoise",
179
"palevioletred", "papayawhip", "peachpuff", "peru", "pink",
180
"plum", "powderblue", "purple",
181
"red", "rosybrown", "royalblue",
182
"saddlebrown", "salmon", "sandybrown", "seagreen", "seashell",
183
"sienna", "silver", "skyblue", "slateblue", "slategray",
184
"slategrey", "snow", "springgreen", "steelblue",
185
"tan", "teal", "thistle", "tomato", "turquoise",
187
"wheat", "white", "whitesmoke",
188
"yellow", "yellowgreen",
191
static char buf[SMALLBUF];
195
tok = canontoken(name);
196
if (!SVG_COLORS_P || (bsearch(&tok, svg_known_colors,
197
sizeof(svg_known_colors) / sizeof(char *),
198
sizeof(char *), dia_comparestr) == NULL)) {
199
/* if tok was not found in known_colors */
200
if (streq(tok, "transparent")) {
203
colorxlate(name, &color, RGBA_BYTE);
204
sprintf(buf, "#%02x%02x%02x",
205
color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]);
213
static void dia_reset(void)
219
static void init_dia(void)
222
cstk[0].pencolor = DEFAULT_COLOR; /* DIA pencolor */
223
cstk[0].fillcolor = ""; /* DIA fillcolor */
224
cstk[0].fontfam = DEFAULT_FONTNAME; /* font family name */
225
cstk[0].fontsz = DEFAULT_FONTSIZE; /* font size */
226
cstk[0].fontopt = REGULAR; /* modifier: REGULAR, BOLD or ITALIC */
227
cstk[0].pen = P_SOLID; /* pen pattern style, default is solid */
228
cstk[0].fill = P_NONE;
229
cstk[0].penwidth = WIDTH_NORMAL;
232
static pointf diapt(point p)
237
rv.x = PB.LL.x + p.x * Scale + Offset.x;
238
rv.y = PB.UR.y - 1 - p.y * Scale - Offset.y;
240
rv.x = PB.UR.x - 1 - p.y * Scale - Offset.x;
241
rv.y = PB.UR.y - 1 - p.x * Scale - Offset.y;
246
static void dia_grstyle(context_t * cp)
248
if (strcmp(cp->pencolor, DEFAULT_COLOR)) {
249
dia_fputs(" <dia:attribute name=\"border_color\">\n");
250
dia_printf(" <dia:color val=\"%s\"/>\n",
251
dia_resolve_color(cp->pencolor));
252
dia_fputs(" </dia:attribute>\n");
254
if (cp->penwidth != WIDTH_NORMAL) {
255
dia_fputs(" <dia:attribute name=\"line_width\">\n");
256
dia_printf(" <dia:real val=\"%g\"/>\n",
257
Scale * (cp->penwidth));
258
dia_fputs(" </dia:attribute>\n");
260
if (cp->pen == P_DASHED) {
261
dia_fputs(" <dia:attribute name=\"line_style\">\n");
262
dia_printf(" <dia:real val=\"%d\"/>\n", 1);
263
dia_fputs(" </dia:attribute>\n");
265
} else if (cp->pen == P_DOTTED) {
266
dia_printf("stroke-dasharray:%s;", sdotarray);
271
static void dia_grstylefill(context_t * cp, int filled)
274
dia_fputs(" <dia:attribute name=\"inner_color\">\n");
275
dia_printf(" <dia:color val=\"%s\"/>\n",
276
dia_resolve_color(cp->fillcolor));
277
dia_fputs(" </dia:attribute>\n");
279
dia_fputs(" <dia:attribute name=\"show_background\">\n");
280
dia_printf(" <dia:boolean val=\"%s\"/>\n", "true");
281
dia_fputs(" </dia:attribute>\n");
285
static void dia_comment(char *str)
288
dia_fputs(xml_string(str));
293
dia_begin_job(FILE * ofp, graph_t * g, char **lib, char *user,
294
char *info[], point pages)
299
fd = dup(fileno(Output_file)); /* open dup so can gzclose
300
independent of FILE close */
301
Zfile = gzdopen(fd, "wb");
303
agerr(AGERR, "Error opening compressed output file\n");
308
"No support for compressed output. Not compiled with zlib.\n");
313
/* N_pages = pages.x * pages.y; */
314
dia_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
318
static void dia_end_job(void)
322
static void dia_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
325
PB.LL.x = PB.LL.y = 0;
326
PB.UR.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * SCALE;
327
PB.UR.y = (bb.UR.y - bb.LL.y + 2 * GD_drawing(g)->margin.y) * SCALE;
328
Offset.x = GD_drawing(g)->margin.x * SCALE;
329
Offset.y = GD_drawing(g)->margin.y * SCALE;
335
("<dia:diagram xmlns:dia=\"http://www.lysator.liu.se/~alla/dia/\">\n");
336
dia_fputs(" <dia:diagramdata>\n");
337
dia_fputs(" <dia:attribute name=\"background\">\n");
338
dia_fputs(" <dia:color val=\"#ffffff\"/>\n");
339
dia_fputs(" </dia:attribute>\n");
340
dia_fputs(" <dia:attribute name=\"paper\">\n");
341
dia_fputs(" <dia:composite type=\"paper\">\n");
342
dia_fputs(" <dia:attribute name=\"name\">\n");
343
dia_fputs(" <dia:string>#A4#</dia:string>\n");
344
dia_fputs(" </dia:attribute>\n");
345
dia_fputs(" <dia:attribute name=\"tmargin\">\n");
346
dia_fputs(" <dia:real val=\"2.8222\"/>\n");
347
dia_fputs(" </dia:attribute>\n");
348
dia_fputs(" <dia:attribute name=\"bmargin\">\n");
349
dia_fputs(" <dia:real val=\"2.8222\"/>\n");
350
dia_fputs(" </dia:attribute>\n");
351
dia_fputs(" <dia:attribute name=\"lmargin\">\n");
352
dia_fputs(" <dia:real val=\"2.8222\"/>\n");
353
dia_fputs(" </dia:attribute>\n");
354
dia_fputs(" <dia:attribute name=\"rmargin\">\n");
355
dia_fputs(" <dia:real val=\"2.8222\"/>\n");
356
dia_fputs(" </dia:attribute>\n");
357
dia_fputs(" <dia:attribute name=\"is_portrait\">\n");
358
dia_fputs(" <dia:boolean val=\"true\"/>\n");
359
dia_fputs(" </dia:attribute>\n");
360
dia_fputs(" <dia:attribute name=\"scaling\">\n");
361
dia_fputs(" <dia:real val=\"1\"/>\n");
362
dia_fputs(" </dia:attribute>\n");
363
dia_fputs(" <dia:attribute name=\"fitto\">\n");
364
dia_fputs(" <dia:boolean val=\"false\"/>\n");
365
dia_fputs(" </dia:attribute>\n");
366
dia_fputs(" </dia:composite>\n");
367
dia_fputs(" </dia:attribute>\n");
368
dia_fputs(" <dia:attribute name=\"grid\">\n");
369
dia_fputs(" <dia:composite type=\"grid\">\n");
370
dia_fputs(" <dia:attribute name=\"width_x\">\n");
371
dia_fputs(" <dia:real val=\"1\"/>\n");
372
dia_fputs(" </dia:attribute>\n");
373
dia_fputs(" <dia:attribute name=\"width_y\">\n");
374
dia_fputs(" <dia:real val=\"1\"/>\n");
375
dia_fputs(" </dia:attribute>\n");
376
dia_fputs(" <dia:attribute name=\"visible_x\">\n");
377
dia_fputs(" <dia:int val=\"1\"/>\n");
378
dia_fputs(" </dia:attribute>\n");
379
dia_fputs(" <dia:attribute name=\"visible_y\">\n");
380
dia_fputs(" <dia:int val=\"1\"/>\n");
381
dia_fputs(" </dia:attribute>\n");
382
dia_fputs(" </dia:composite>\n");
383
dia_fputs(" </dia:attribute>\n");
384
dia_fputs(" <dia:attribute name=\"guides\">\n");
385
dia_fputs(" <dia:composite type=\"guides\">\n");
386
dia_fputs(" <dia:attribute name=\"hguides\"/>\n");
387
dia_fputs(" <dia:attribute name=\"vguides\"/>\n");
388
dia_fputs(" </dia:composite>\n");
389
dia_fputs(" </dia:attribute>\n");
390
dia_fputs(" </dia:diagramdata>\n");
393
static void dia_end_graph(void)
395
dia_printf("</dia:diagram>\n");
402
dia_begin_page(graph_t * g, point page, double scale, int rot,
405
/* int page_number; */
408
Scale = scale * SCALE;
410
/* page_number = page.x + page.y * Pages.x + 1; */
411
/* sz = sub_points(PB.UR,PB.LL); */
413
dia_printf(" <dia:layer name=\"Background\" visible=\"true\">\n");
416
static void dia_end_page(void)
418
dia_fputs(" </dia:layer>\n");
421
static void dia_begin_cluster(graph_t * g)
423
dia_printf("<dia:group>\n");
427
static void dia_end_cluster(void)
429
dia_printf("</dia:group>\n");
432
static void dia_begin_node(node_t * n)
434
dia_printf("<dia:group>\n");
438
static void dia_end_node(void)
440
dia_printf("</dia:group>\n");
443
static void dia_begin_edge(edge_t * e)
448
static void dia_end_edge(void)
453
static void dia_begin_context(void)
455
assert(SP + 1 < MAXNEST);
456
cstk[SP + 1] = cstk[SP];
460
static void dia_end_context(void)
464
/*free(cstk[psp].fontfam); */
468
static void dia_set_font(char *name, double size)
474
cp->font_was_set = TRUE;
480
static void dia_set_pencolor(char *name)
482
cstk[SP].pencolor = name;
485
static void dia_set_fillcolor(char *name)
487
cstk[SP].fillcolor = name;
490
static void dia_set_style(char **s)
496
while ((p = line = *s++)) {
497
if (streq(line, "solid"))
499
else if (streq(line, "dashed"))
501
else if (streq(line, "dotted"))
503
else if (streq(line, "invis"))
505
else if (streq(line, "bold"))
506
cp->penwidth = WIDTH_BOLD;
507
else if (streq(line, "setlinewidth")) {
511
cp->penwidth = atol(p);
512
} else if (streq(line, "filled"))
514
else if (streq(line, "unfilled"))
518
"dia_set_style: unsupported style %s - ignoring\n",
521
cp->style_was_set = TRUE;
523
/* if (cp->style_was_set) dia_style(cp); */
526
static void dia_textpara(point p, textpara_t * para)
533
switch (para->just) {
548
(" <dia:object type=\"Standard - Text\" version=\"0\" id=\"%s\">\n",
550
dia_fputs(" <dia:attribute name=\"text\">\n");
551
dia_fputs(" <dia:composite type=\"text\">\n");
552
dia_fputs(" <dia:attribute name=\"string\">\n");
553
dia_fputs(" <dia:string>#");
554
dia_fputs(xml_string(para->str));
555
dia_fputs("#</dia:string>\n");
556
dia_fputs(" </dia:attribute>\n");
557
dia_fputs(" <dia:attribute name=\"font\">\n");
558
dia_printf(" <dia:font name=\"%s\"/>\n", cp->fontfam);
559
dia_fputs(" </dia:attribute>\n");
560
dia_fputs(" <dia:attribute name=\"height\">\n");
561
dia_printf(" <dia:real val=\"%g\"/>\n",
562
Scale * (cp->fontsz));
563
dia_fputs(" </dia:attribute>\n");
564
dia_fputs(" <dia:attribute name=\"pos\">\n");
565
dia_printf(" <dia:point val=\"%g,%g\"/>\n", mp.x, mp.y);
566
dia_fputs(" </dia:attribute>\n");
567
dia_fputs(" <dia:attribute name=\"color\">\n");
568
dia_printf(" <dia:color val=\"%s\"/>\n",
569
dia_resolve_color(cp->pencolor));
570
dia_fputs(" </dia:attribute>\n");
571
dia_fputs(" <dia:attribute name=\"alignment\">\n");
572
dia_printf(" <dia:enum val=\"%d\"/>\n", anchor);
573
dia_fputs(" </dia:attribute>\n");
574
dia_fputs(" </dia:composite>\n");
575
dia_fputs(" </dia:attribute>\n");
576
dia_fputs(" <dia:attribute name=\"obj_pos\">\n");
577
dia_printf(" <dia:point val=\"%g,%g\"/>\n", mp.x, mp.y);
578
dia_fputs(" </dia:attribute>\n");
579
dia_fputs(" <dia:attribute name=\"obj_bb\">\n");
580
dia_printf(" <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
581
mp.x - (Scale * (para->width) / 2.), mp.y - 0.4,
582
mp.x + (Scale * (para->width) / 2.), mp.y + 0.4);
583
dia_fputs(" </dia:attribute>\n");
584
dia_fputs(" </dia:object>\n");
587
static void dia_ellipse(point p, int rx, int ry, int filled)
594
nodeId = Curnode->id;
601
if (cstk[SP].pen == P_NONE) {
602
/* its invisible, don't draw */
617
(" <dia:object type=\"Standard - Ellipse\" version=\"0\" id=\"%d\">\n",
619
dia_fputs(" <dia:attribute name=\"elem_corner\">\n");
620
dia_printf(" <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x,
622
dia_fputs(" </dia:attribute>\n");
623
dia_fputs(" <dia:attribute name=\"elem_width\">\n");
624
dia_printf(" <dia:real val=\"%g\"/>\n", rp.x + rp.x);
625
dia_fputs(" </dia:attribute>\n");
626
dia_fputs(" <dia:attribute name=\"elem_height\">\n");
627
dia_printf(" <dia:real val=\"%g\"/>\n", rp.y + rp.y);
628
dia_fputs(" </dia:attribute>\n");
629
dia_fputs(" <dia:attribute name=\"obj_pos\">\n");
630
dia_printf(" <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x,
632
dia_fputs(" </dia:attribute>\n");
633
dia_fputs(" <dia:attribute name=\"obj_bb\">\n");
634
dia_printf(" <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
635
cp.x - rp.x - .11, cp.y - rp.y - .11, cp.x + rp.x + .11,
637
dia_fputs(" </dia:attribute>\n");
638
dia_grstyle(&cstk[SP]);
639
dia_grstylefill(&cstk[SP], filled);
640
dia_fputs(" </dia:object>\n");
644
int ellipse_connection(pointf cp, pointf p)
653
} else if (cp.y == p.y) {
658
} else if (cp.x < p.x) {
663
} else if (cp.x > p.x) {
674
int box_connection(node_t * n, pointf p)
676
int i = 0, j, sides, conn = 0, peripheries, z;
677
double xsize, ysize, mindist2 = 0.0, dist2;
683
poly = (polygon_t *) ND_shape_info(n);
684
vertices = poly->vertices;
686
peripheries = poly->peripheries;
688
if (A_size < sides) {
690
A = ALLOC(A_size, A, point);
693
xsize = ((ND_lw_i(n) + ND_rw_i(n)) / POINTS(ND_width(n))) * 16.0;
694
ysize = ((ND_ht_i(n)) / POINTS(ND_height(n))) * 16.0;
696
for (j = 0; j < peripheries; j++) {
697
for (i = 0; i < sides; i++) {
698
P = vertices[i + j * sides];
699
/* simple rounding produces random results around .5
700
* this trick should clip off the random part.
701
* (note xsize/ysize prescaled by 16.0 above) */
702
A[i].x = ROUND(P.x * xsize) / 16;
703
A[i].y = ROUND(P.y * ysize) / 16;
705
A[i].x += ND_coord_i(n).x;
706
A[i].y += ND_coord_i(n).y;
713
dist2 = DIST2(p, diapt(A[z]));
718
if (dist2 < mindist2) {
727
P.x = (diapt(A[z]).x + diapt(A[z + 1]).x) / 2;
728
P.y = (diapt(A[z]).y + diapt(A[z + 1]).y) / 2;
730
if (dist2 < mindist2) {
742
dia_bezier(point * A, int n, int arrow_at_start, int arrow_at_end, int filled)
744
int i, conn_h, conn_t;
745
pointf p, firstp = { 0, 0 }, llp = {
752
if (cstk[SP].pen == P_NONE) {
753
/* its invisible, don't draw */
758
(" <dia:object type=\"Standard - BezierLine\" version=\"0\" id=\"%s\">\n",
760
dia_fputs(" <dia:attribute name=\"bez_points\">\n");
761
for (i = 0; i < n; i++) {
764
llp = urp = firstp = p;
765
if (p.x < llp.x || p.y < llp.y)
767
if (p.x > urp.x || p.y > urp.y)
769
dia_printf(" <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
771
dia_fputs(" </dia:attribute>\n");
772
dia_grstyle(&cstk[SP]);
773
dia_fputs(" <dia:attribute name=\"obj_pos\">\n");
774
dia_printf(" <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
775
dia_fputs(" </dia:attribute>\n");
776
dia_fputs(" <dia:attribute name=\"obj_bb\">\n");
777
dia_printf(" <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
778
llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
779
dia_fputs(" </dia:attribute>\n");
782
conn_h = conn_t = -1;
784
head = Curedge->head;
785
tail = Curedge->tail;
787
shape_t = ND_shape(tail)->name;
790
if (arrow_at_start) {
791
dia_fputs(" <dia:attribute name=\"start_arrow\">\n");
792
dia_fputs(" <dia:enum val=\"3\"/>\n");
793
dia_fputs(" </dia:attribute>\n");
794
dia_fputs(" <dia:attribute name=\"start_arrow_length\">\n");
795
dia_fputs(" <dia:real val=\"0.8\"/>\n");
796
dia_fputs(" </dia:attribute>\n");
798
(" <dia:attribute name=\"start_arrow_width\">\n");
799
dia_fputs(" <dia:real val=\"0.8\"/>\n");
800
dia_fputs(" </dia:attribute>\n");
803
dia_fputs(" <dia:attribute name=\"end_arrow\">\n");
804
dia_fputs(" <dia:enum val=\"3\"/>\n");
805
dia_fputs(" </dia:attribute>\n");
806
dia_fputs(" <dia:attribute name=\"end_arrow_length\">\n");
807
dia_fputs(" <dia:real val=\"0.8\"/>\n");
808
dia_fputs(" </dia:attribute>\n");
810
(" <dia:attribute name=\"end_arrow_width\">\n");
811
dia_fputs(" <dia:real val=\"0.8\"/>\n");
812
dia_fputs(" </dia:attribute>\n");
815
dia_fputs(" <dia:attribute name=\"conn_endpoints\">\n");
816
dia_printf(" <dia:point val=\"%g,%g\"/>\n", diapt(A[0]).x,
818
dia_printf(" <dia:point val=\"%g,%g\"/>\n", diapt(A[n - 1]).x,
820
dia_fputs(" </dia:attribute>\n");
821
dia_fputs(" <dia:connections>\n");
823
if ((strcmp(shape_t, "ellipse") == 0)
824
|| (strcmp(shape_t, "circle") == 0)
825
|| (strcmp(shape_t, "doublecircle") == 0)) {
826
cp_h = diapt(ND_coord_i(head));
827
if (AG_IS_DIRECTED(Rootgraph))
828
conn_h = ellipse_connection(cp_h, diapt(A[n - 1]));
830
conn_h = ellipse_connection(cp_h, diapt(A[0]));
832
if (AG_IS_DIRECTED(Rootgraph))
833
conn_h = box_connection(head, diapt(A[n - 1]));
835
conn_h = box_connection(head, diapt(A[0]));
838
if ((strcmp(shape_t, "ellipse") == 0)
839
|| (strcmp(shape_t, "circle") == 0)
840
|| (strcmp(shape_t, "doublecircle") == 0)) {
841
cp_t = diapt(ND_coord_i(tail));
842
if (AG_IS_DIRECTED(Rootgraph))
843
conn_t = ellipse_connection(cp_t, diapt(A[0]));
845
conn_t = ellipse_connection(cp_t, diapt(A[n - 1]));
847
if (AG_IS_DIRECTED(Rootgraph))
848
conn_t = box_connection(tail, diapt(A[0]));
850
conn_t = box_connection(tail, diapt(A[n - 1]));
853
if (arrow_at_start) {
855
(" <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n",
858
(" <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n",
859
(n - 1), tail->id, conn_t);
862
(" <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n",
865
(" <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n",
866
(n - 1), head->id, conn_h);
869
dia_fputs(" </dia:connections>\n");
871
dia_fputs(" </dia:object>\n");
876
static void dia_polygon(point * A, int n, int filled)
879
pointf p, firstp = { 0, 0 }, llp = {
883
if (cstk[SP].pen == P_NONE) {
884
/* its invisible, don't draw */
891
(" <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%d\">\n",
899
(" <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n",
904
(" <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n",
908
dia_fputs(" <dia:attribute name=\"poly_points\">\n");
909
for (i = 0; i < n; i++) {
912
llp = urp = firstp = p;
913
if (p.x < llp.x || p.y < llp.y)
915
if (p.x > urp.x || p.y > urp.y)
917
dia_printf(" <dia:point val=\"%g,%g\"/>\n", p.x, p.y);
919
dia_fputs(" </dia:attribute>\n");
920
dia_fputs(" <dia:attribute name=\"obj_pos\">\n");
921
dia_printf(" <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
922
dia_fputs(" </dia:attribute>\n");
923
dia_fputs(" <dia:attribute name=\"obj_bb\">\n");
924
dia_printf(" <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
925
llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
926
dia_fputs(" </dia:attribute>\n");
927
dia_grstyle(&cstk[SP]);
928
dia_grstylefill(&cstk[SP], filled);
929
dia_fputs(" </dia:object>\n");
932
static void dia_polyline(point * A, int n)
935
pointf p, firstp = { 0, 0 }, llp = {
939
if (cstk[SP].pen == P_NONE) {
940
/* its invisible, don't draw */
944
(" <dia:object type=\"Standard - PolyLine\" version=\"0\" id=\"%s\">\n",
946
dia_fputs(" <dia:attribute name=\"poly_points\">\n");
947
for (i = 0; i < n; i++) {
950
llp = urp = firstp = p;
951
if (p.x < llp.x || p.y < llp.y)
953
if (p.x > urp.x || p.y > urp.y)
955
dia_printf("<dia:point val=\"%g,%g\"/>\n", p.x, p.y);
957
dia_fputs(" </dia:attribute>\n");
958
dia_grstyle(&cstk[SP]);
959
dia_fputs(" <dia:attribute name=\"obj_pos\">\n");
960
dia_printf(" <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y);
961
dia_fputs(" </dia:attribute>\n");
962
dia_fputs(" <dia:attribute name=\"obj_bb\">\n");
963
dia_printf(" <dia:rectangle val=\"%g,%g;%g,%g\"/>\n",
964
llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11);
965
dia_fputs(" </dia:attribute>\n");
966
dia_fputs(" </dia:object>\n");
969
static void dia_usershape(usershape_t *us, boxf b, point *A, int n, boolean filled)
973
if (cstk[SP].pen == P_NONE) {
974
/* its invisible, don't draw */
980
imagefile = agget(Curnode, "shapefile");
986
dia_polygon(A, n, filled);
991
codegen_t DIA_CodeGen = {
993
dia_begin_job, dia_end_job,
994
dia_begin_graph, dia_end_graph,
995
dia_begin_page, dia_end_page,
996
0, /* dia_begin_layer */ 0, /* dia_end_layer */
997
dia_begin_cluster, dia_end_cluster,
998
0, /* dia_begin_nodes */ 0, /* dia_end_nodes */
999
0, /* dia_begin_edges */ 0, /* dia_end_edges */
1000
dia_begin_node, dia_end_node,
1001
dia_begin_edge, dia_end_edge,
1002
dia_begin_context, dia_end_context,
1003
0, /* dia_begin_anchor */ 0, /* dia_end_anchor */
1004
dia_set_font, dia_textpara,
1005
dia_set_pencolor, dia_set_fillcolor, dia_set_style,
1006
dia_ellipse, dia_polygon,
1007
dia_bezier, dia_polyline,
1008
1, /* bezier_has_arrows */