2
# dotty_draw: drawing functions and data structures
4
dotty.protogt.drawgraph = function (gt, views) {
5
local gid, eid, nid, graph;
8
gt.drawsgraph (gt, views, graph);
9
for (gid in graph.graphs)
10
gt.drawsgraph (gt, views, graph.graphs[gid]);
11
for (eid in graph.edges)
12
gt.drawedge (gt, views, graph.edges[eid]);
13
for (nid in graph.nodes)
14
gt.drawnode (gt, views, graph.nodes[nid]);
16
dotty.protogt.redrawgraph = function (gt, views) {
20
clear (views[vid].canvas);
21
gt.drawgraph (gt, views);
23
dotty.protogt.setviewsize = function (views, r) {
24
local vid, vt, w2v, scale, attr;
29
if (r[1].x == 0 | r[1].y == 0) {
30
attr = getwidgetattr (vt.scroll, [0 = 'size';]);
31
vt.wrect[1] = copy (attr.size);
33
if (vt.type == 'birdseye') {
34
attr = getwidgetattr (vt.scroll, [0 = 'size';]);
35
scale.x = (vt.wrect[1].x - vt.wrect[0].x) / attr.size.x;
36
scale.y = (vt.wrect[1].y - vt.wrect[0].y) / attr.size.y;
37
if (scale.x > 1 & scale.x > scale.y)
46
'x' = (vt.wrect[1].x - vt.wrect[0].x) / w2v;
47
'y' = (vt.wrect[1].y - vt.wrect[0].y) / w2v;
49
setwidgetattr (vt.canvas, [
51
'viewport' = vt.vsize;
55
dotty.protogt.setviewscale = function (views, factor) {
60
if ((w2v = vt.w2v * factor) < 0.01) {
61
dotty.message (0, 'cannot zoom any closer');
66
'x' = (vt.wrect[1].x - vt.wrect[0].x) / w2v;
67
'y' = (vt.wrect[1].y - vt.wrect[0].y) / w2v;
69
setwidgetattr (vt.canvas, ['viewport' = vt.vsize;]);
72
dotty.protogt.setviewcenter = function (views, center) {
78
'x' = center.x * vt.vsize.x / (vt.wrect[1].x - vt.wrect[0].x);
79
'y' = (vt.wrect[1].y - center.y) * vt.vsize.y /
80
(vt.wrect[1].y - vt.wrect[0].y);
82
setwidgetattr (vt.scroll, ['childcenter' = pos;]);
85
dotty.protogt.foldsgraph = function (gt, views, sgraph) {
88
# gt.undrawsgraph(gt, views, sgraph);
89
for (nid in sgraph.nodes)
90
gt.undrawnode (gt, views, graph.nodes[nid]);
93
dotty.protogt.drawsgraph = function (gt, views, sgraph) {
94
local vid, canvas, pos;
97
if (~sgraph.rect[0] | sgraph.graphattr.style == 'invis')
100
canvas = views[vid].canvas;
101
if (~sgraph.type) # 'type' only exists on top level
102
box (canvas, null, sgraph.rect, ['color' = sgraph.color;]);
103
if (sgraph.graphattr.label) {
104
if (sgraph.lp.x >= 0) {
106
text (canvas, null, pos, sgraph.graphattr.label,
107
sgraph.fontname, sgraph.fontsize, 'cc',
108
['color' = sgraph.fontcolor;]);
110
pos = ['x' = sgraph.rect[0].x; 'y' = sgraph.rect[1].y;];
111
text (canvas, null, pos, sgraph.graphattr.label,
112
sgraph.fontname, sgraph.fontsize, 'ld',
113
['color' = sgraph.fontcolor;]);
118
dotty.protogt.undrawsgraph = function (gt, views, sgraph) {
119
local vid, canvas, pos;
124
if (~sgraph.rect[0] | sgraph.graphattr.style == 'invis')
127
canvas = views[vid].canvas;
128
if (~sgraph.type) # 'type' only exists on top level
129
box (canvas, null, sgraph.rect, ['color' = 0;]);
130
if (sgraph.graphattr.label) {
131
if (sgraph.lp.x >= 0) {
133
text (canvas, null, pos, sgraph.graphattr.label,
134
sgraph.fontname, sgraph.fontsize, 'cc',
137
pos = ['x' = sgraph.rect[0].x; 'y' = sgraph.rect[1].y;];
138
text (canvas, null, pos, sgraph.graphattr.label,
139
sgraph.fontname, sgraph.fontsize, 'ld',
143
clearpick (canvas, sgraph);
146
dotty.protogt.drawnode = function (gt, views, node) {
147
local vid, func, pos, size, rect;
152
if (node.attr.style == 'invis') {
155
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
156
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
158
setpick (views[vid].canvas, node, rect);
162
if ( node.attr.folded == '1' )
163
func = gt.shapefunc['Msquare'];
164
else if (~(func = gt.shapefunc[node.attr.shape]))
165
func = gt.shapefunc['box'];
167
func (gt, views[vid].canvas, node);
169
dotty.protogt.undrawnode = function (gt, views, node) {
170
local vid, func, pos, size, rect, color, fontcolor, outlinecolor;
177
if (node.attr.style == 'invis') {
180
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
181
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
183
clearpick (views[vid].canvas, node);
188
fontcolor = node.fontcolor;
190
outlinecolor = dotty.outlinecolor;
191
dotty.outlinecolor = 0;
192
if ( node.attr.folded == '1' )
193
func = gt.shapefunc['Msquare'];
194
else if (~(func = gt.shapefunc[node.attr.shape]))
195
func = gt.shapefunc['box'];
197
func (gt, views[vid].canvas, node);
198
clearpick (views[vid].canvas, node);
201
node.fontcolor = fontcolor;
202
dotty.outlinecolor = outlinecolor;
204
dotty.protogt.shapefunc.record = function (gt, canvas, node) {
205
local rect, pos, size;
209
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
210
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
211
if (node.attr.style == 'filled') {
212
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
213
box (canvas, node, rect, ['color' = dotty.outlinecolor;]);
215
gt.shapefunc.rfields (gt, canvas, node, node.fields);
216
setpick (canvas, node, rect);
218
dotty.protogt.shapefunc.rfields = function (gt, canvas, node, fields) {
219
local fid, field, pos, label;
221
for (fid in fields) {
224
gt.shapefunc.rfields (gt, canvas, node, field.fields);
226
if (node.attr.style == 'filled')
227
box (canvas, null, field.rect, ['color' = dotty.outlinecolor;]);
229
box (canvas, null, field.rect, ['color' = node.color;]);
230
pos.x = (field.rect[1].x + field.rect[0].x) / 2;
231
pos.y = (field.rect[1].y + field.rect[0].y) / 2;
232
if (~(label = field.text) | label == '\N')
234
text (canvas, null, pos, label, node.fontname, node.fontsize,
235
'cc', ['color' = node.fontcolor;]);
239
dotty.protogt.shapefunc.plaintext = function (gt, canvas, node) {
240
local pos, size, label, rect;
244
if (~(label = node.attr.label) | label == '\N')
246
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
247
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
248
setpick (canvas, node, rect);
249
text (canvas, null, pos, label, node.fontname, node.fontsize,
250
'cc', ['color' = node.fontcolor;]);
252
dotty.protogt.shapefunc.box = function (gt, canvas, node) {
253
local pos, size, label, rect;
257
if (~(label = node.attr.label) | label == '\N')
259
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
260
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
261
if (node.attr.style == 'filled') {
262
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
263
box (canvas, node, rect, ['color' = dotty.outlinecolor;]);
265
box (canvas, node, rect, ['color' = node.color;]);
266
text (canvas, null, pos, label, node.fontname, node.fontsize,
267
'cc', ['color' = node.fontcolor;]);
269
dotty.protogt.shapefunc.Msquare = function (gt, canvas, node) {
270
local pos, size, label, rect, color;
274
if (~(label = node.attr.label) | label == '\N')
276
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
277
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
278
if (node.attr.style == 'filled') {
279
box (canvas, node, rect, ['color' = node.color; 'fill' = 'on';]);
280
color = dotty.outlinecolor;
281
box (canvas, node, rect, ['color' = color;]);
282
line (canvas, null, ['x' = rect[0].x; 'y' = rect[0].y + 10;],
283
['x' = rect[0].x + 10; 'y' = rect[0].y;], ['color' = color;]);
284
line (canvas, null, ['x' = rect[0].x; 'y' = rect[1].y - 10;],
285
['x' = rect[0].x + 10; 'y' = rect[1].y;], ['color' = color;]);
286
line (canvas, null, ['x' = rect[1].x; 'y' = rect[0].y + 10;],
287
['x' = rect[1].x - 10; 'y' = rect[0].y;], ['color' = color;]);
288
line (canvas, null, ['x' = rect[1].x; 'y' = rect[1].y - 10;],
289
['x' = rect[1].x - 10; 'y' = rect[1].y;], ['color' = color;]);
292
box (canvas, node, rect, ['color' = color;]);
293
line (canvas, null, ['x' = rect[0].x; 'y' = rect[0].y + 10;],
294
['x' = rect[0].x + 10; 'y' = rect[0].y;], ['color' = color;]);
295
line (canvas, null, ['x' = rect[0].x; 'y' = rect[1].y - 10;],
296
['x' = rect[0].x + 10; 'y' = rect[1].y;], ['color' = color;]);
297
line (canvas, null, ['x' = rect[1].x; 'y' = rect[0].y + 10;],
298
['x' = rect[1].x - 10; 'y' = rect[0].y;], ['color' = color;]);
299
line (canvas, null, ['x' = rect[1].x; 'y' = rect[1].y - 10;],
300
['x' = rect[1].x - 10; 'y' = rect[1].y;], ['color' = color;]);
302
text (canvas, null, pos, label, node.fontname, node.fontsize,
303
'cc', ['color' = node.fontcolor;]);
305
dotty.protogt.shapefunc.ellipse = function (gt, canvas, node) {
306
local pos, size, label;
309
size.x = node.size.x / 2;
310
size.y = node.size.y / 2;
311
if (~(label = node.attr.label) | label == '\N')
313
if (node.attr.style == 'filled') {
314
if (node.attr.shape == 'doublecircle') {
315
arc (canvas, node, pos, size, ['color' = dotty.outlinecolor;]);
319
arc (canvas, node, pos, size, ['color' = node.color; 'fill' = 'on';]);
320
arc (canvas, node, pos, size, ['color' = dotty.outlinecolor;]);
322
if (node.attr.shape == 'doublecircle') {
323
arc (canvas, node, pos, size, ['color' = node.color;]);
327
arc (canvas, node, pos, size, ['color' = node.color;]);
329
text (canvas, null, pos, label, node.fontname, node.fontsize,
330
'cc', ['color' = node.fontcolor;]);
332
dotty.protogt.shapefunc.circle = dotty.protogt.shapefunc.ellipse;
333
dotty.protogt.shapefunc.doublecircle = dotty.protogt.shapefunc.ellipse;
334
dotty.protogt.shapefunc.diamond = function (gt, canvas, node) {
335
local pos, size, label, p, rect;
339
if (~(label = node.attr.label) | label == '\N')
341
p[0] = ['x' = pos.x; 'y' = pos.y + size.y / 2;];
342
p[1] = ['x' = pos.x + size.x / 2; 'y' = pos.y;];
343
p[2] = ['x' = pos.x; 'y' = pos.y - size.y / 2;];
344
p[3] = ['x' = pos.x - size.x / 2; 'y' = pos.y;];
346
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
347
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
348
if (node.attr.style == 'filled') {
349
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
350
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
352
polygon (canvas, node, p, ['color' = node.color;]);
353
setpick (canvas, node, rect);
354
text (canvas, null, pos, label, node.fontname, node.fontsize,
355
'cc', ['color' = node.fontcolor;]);
357
dotty.protogt.shapefunc.parallelogram = function (gt, canvas, node) {
358
local pos, size, label, rect, color, dx, p;
362
if (~(label = node.attr.label) | label == '\N')
364
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
365
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
366
dx = (rect[1].x - rect[0].x) / 5;
367
p[0] = ['x' = rect[0].x; 'y' = rect[0].y;];
368
p[1] = ['x' = rect[1].x - dx; 'y' = rect[0].y;];
369
p[2] = ['x' = rect[1].x; 'y' = rect[1].y;];
370
p[3] = ['x' = rect[0].x + dx; 'y' = rect[1].y;];
371
p[4] = ['x' = rect[0].x; 'y' = rect[0].y;];
372
if (node.attr.style == 'filled') {
373
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
374
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
376
polygon (canvas, node, p, ['color' = node.color;]);
377
setpick (canvas, node, rect);
378
text (canvas, null, pos, label, node.fontname, node.fontsize,
379
'cc', ['color' = node.fontcolor;]);
381
dotty.protogt.shapefunc.trapezium = function (gt, canvas, node) {
382
local pos, size, label, rect, color, dx, p;
386
if (~(label = node.attr.label) | label == '\N')
388
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
389
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
390
dx = (rect[1].x - rect[0].x) / 5;
391
p[0] = ['x' = rect[0].x; 'y' = rect[0].y;];
392
p[1] = ['x' = rect[1].x; 'y' = rect[0].y;];
393
p[2] = ['x' = rect[1].x - dx; 'y' = rect[1].y;];
394
p[3] = ['x' = rect[0].x + dx; 'y' = rect[1].y;];
395
p[4] = ['x' = rect[0].x; 'y' = rect[0].y;];
396
if (node.attr.style == 'filled') {
397
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
398
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
400
polygon (canvas, node, p, ['color' = node.color;]);
401
setpick (canvas, node, rect);
402
text (canvas, null, pos, label, node.fontname, node.fontsize,
403
'cc', ['color' = node.fontcolor;]);
405
dotty.protogt.shapefunc.triangle = function (gt, canvas, node) {
406
local pos, size, label, rect, color, dx, dy, p;
410
if (~(label = node.attr.label) | label == '\N')
412
rect[0] = ['x' = pos.x - size.x / 2; 'y' = pos.y - size.y / 2;];
413
rect[1] = ['x' = rect[0].x + size.x; 'y' = rect[0].y + size.y;];
414
if (node.attr.orientation ~= -90) {
417
p[0] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
418
p[1] = ['x' = pos.x + dx; 'y' = pos.y - dy;];
419
p[2] = ['x' = pos.x; 'y' = rect[1].y;];
420
p[3] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
424
p[0] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
425
p[1] = ['x' = pos.x - dx; 'y' = pos.y + dy;];
426
p[2] = ['x' = pos.x + dx * 2; 'y' = pos.y;];
427
p[3] = ['x' = pos.x - dx; 'y' = pos.y - dy;];
429
if (node.attr.style == 'filled') {
430
polygon (canvas, node, p, ['color' = node.color; 'fill' = 'on';]);
431
polygon (canvas, node, p, ['color' = dotty.outlinecolor;]);
433
polygon (canvas, node, p, ['color' = node.color;]);
434
setpick (canvas, node, rect);
435
text (canvas, null, pos, label, node.fontname, node.fontsize,
436
'cc', ['color' = node.fontcolor;]);
438
dotty.protogt.movenode = function (gt, node, pos) {
439
local ppos, eid, edge, p, fp, lp;
441
ppos = copy (node.pos);
442
gt.undrawnode (gt, gt.views, node);
445
if (node.attr.shape == 'record')
446
gt.moverecordfields (gt, node.fields, pos.x - ppos.x, pos.y - ppos.y);
447
for (eid in node.edges) {
448
edge = node.edges[eid];
449
if (~edge.dir & edge.head ~= edge.tail) {
452
lp = edge.points[tablesize (edge.points) - 1];
453
if (((p.x - fp.x) * (p.x - fp.x) + (p.y - fp.y) * (p.y - fp.y)) <
454
((p.x - lp.x) * (p.x - lp.x) + (p.y - lp.y) * (p.y - lp.y)))
459
gt.moveedge (gt, edge, node, ppos, pos);
461
gt.drawnode (gt, gt.views, node);
463
dotty.protogt.moverecordfields = function (gt, fields, dx, dy) {
466
for (fid in fields) {
469
gt.moverecordfields (gt, field.fields, dx, dy);
471
field.rect[0].x = field.rect[0].x + dx;
472
field.rect[0].y = field.rect[0].y + dy;
473
field.rect[1].x = field.rect[1].x + dx;
474
field.rect[1].y = field.rect[1].y + dy;
478
dotty.protogt.drawedge = function (gt, views, edge) {
484
if (edge.attr.style == 'invis') {
485
if (gt.edgehandles == 0)
488
arc (views[vid].canvas, edge, [
489
'x' = (edge.points[1].x + edge.points[2].x) / 2;
490
'y' = (edge.points[1].y + edge.points[2].y) / 2;
491
], ['x' = 5; 'y' = 5;], ['color' = 1;]);
496
canvas = views[vid].canvas;
497
if (edge.attr.style == 'bold')
498
setgfxattr (canvas, ['width' = 3;]);
499
splinegon (canvas, null, edge.points,
500
['color' = edge.color; 'style' = edge.attr.style;]);
502
arrow (canvas, null, edge.points[0],
503
edge.sp, ['color' = edge.color;]);
505
arrow (canvas, null, edge.points[tablesize (edge.points) - 1],
506
edge.ep, ['color' = edge.color;]);
507
if (edge.attr.style == 'bold')
508
setgfxattr (canvas, ['width' = 0;]);
510
text (canvas, null, edge.lp, edge.attr.label, edge.fontname,
511
edge.fontsize, 'cc', ['color' = edge.fontcolor;]);
512
if (gt.edgehandles == 0)
515
'x' = (edge.points[1].x + edge.points[2].x) / 2;
516
'y' = (edge.points[1].y + edge.points[2].y) / 2;
517
], ['x' = 5; 'y' = 5;], ['color' = 1;]);
520
dotty.protogt.undrawedge = function (gt, views, edge) {
528
if (edge.attr.style == 'invis') {
529
if (gt.edgehandles == 0)
532
arc (views[vid].canvas, edge, [
533
'x' = (edge.points[1].x + edge.points[2].x) / 2;
534
'y' = (edge.points[1].y + edge.points[2].y) / 2;
535
], ['x' = 5; 'y' = 5;], ['color' = 0;]);
536
clearpick (views[vid].canvas, edge);
541
canvas = views[vid].canvas;
542
if (edge.attr.style == 'bold')
543
setgfxattr (canvas, ['width' = 3;]);
544
splinegon (canvas, null, edge.points, ['color' = 0;]);
546
arrow (canvas, null, edge.points[0],
547
edge.sp, ['color' = 0;]);
549
arrow (canvas, null, edge.points[tablesize (edge.points) - 1],
550
edge.ep, ['color' = 0;]);
551
if (edge.attr.style == 'bold')
552
setgfxattr (canvas, ['width' = 0;]);
554
text (canvas, null, edge.lp, edge.attr.label, edge.fontname,
555
edge.fontsize, 'cc', ['color' = 0;]);
556
if (gt.edgehandles == 0)
559
'x' = (edge.points[1].x + edge.points[2].x) / 2;
560
'y' = (edge.points[1].y + edge.points[2].y) / 2;
561
], ['x' = 5; 'y' = 5;], ['color' = 0;]);
562
clearpick (canvas, edge);
565
dotty.protogt.moveedge = function (gt, edge, node, pb, pc) {
566
local dx, dy, tp, hp, pid, p, pa, da, lab, lac, s, ce, se, n, x, y, dir;
568
gt.undrawedge (gt, gt.views, edge);
569
dx = pc.x - pb.x; dy = pc.y - pb.y;
572
if (edge.tail == node) {
573
if (edge.head == node) {
574
for (pid in edge.points) {
575
p = edge.points[pid];
576
p.x = p.x + dx; p.y = p.y + dy;
579
tp.x = tp.x + dx; tp.y = tp.y + dy;
582
hp.x = hp.x + dx; hp.y = hp.y + dy;
585
edge.lp.x = edge.lp.x + dx;
586
edge.lp.y = edge.lp.y + dy;
588
gt.drawedge (gt, gt.views, edge);
597
dir = edge.dir * dir;
598
da = atan (pc.y - pa.y, pc.x - pa.x) - atan (pb.y - pa.y, pb.x - pa.x);
599
lab = sqrt ((pb.y - pa.y) * (pb.y - pa.y) +
600
(pb.x - pa.x) * (pb.x - pa.x));
601
lac = sqrt ((pc.y - pa.y) * (pc.y - pa.y) +
602
(pc.x - pa.x) * (pc.x - pa.x));
606
n = tablesize (edge.points);
607
for (pid = 1; pid < n - 1; pid = pid + 1) {
608
p = edge.points[pid];
611
p.x = pa.x + (ce * x - se * y) * s;
612
p.y = pa.y + (se * x + ce * y) * s;
616
p.x = p.x + dx; p.y = p.y + dy;
618
tp.x = tp.x + dx; tp.y = tp.y + dy;
621
p = edge.points[n - 1];
622
p.x = p.x + dx; p.y = p.y + dy;
624
hp.x = hp.x + dx; hp.y = hp.y + dy;
628
x = edge.lp.x - pa.x;
629
y = edge.lp.y - pa.y;
630
edge.lp.x = pa.x + (ce * x - se * y) * s;
631
edge.lp.y = pa.y + (se * x + ce * y) * s;
633
gt.drawedge (gt, gt.views, edge);
635
dotty.protogt.getcolor = function (views, name) {
636
local vid, vt, color, t;
641
if (~(vt.colors[name] >= 0))
642
color = (vt.colors[name] = vt.colorn);
644
color = vt.colors[name];
647
} else if (~(vt.colors[name] >= 0))
648
vt.colors[name] = color;
649
else if (vt.colors[name] ~= color)
650
dotty.message (0, concat ('inconsistent color ids for ', name));
651
if (setwidgetattr (vt.canvas, ['color' = [color = name;];]) ~= 1) {
652
t = split (name, ' ');
653
if (tablesize (t) ~= 3 |
654
setwidgetattr (vt.canvas, ['color' = [color = [
655
'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
657
dotty.message (0, concat ('unknown color ', name, ' using #1'));
661
vt.colorn = color + 1;
665
dotty.protogt.unpacksgraphattr = function (gt, sgraph) {
668
attr = sgraph.graphattr;
669
if (dotty.fontmap[attr.fontname])
670
sgraph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
672
sgraph[dotty.keys.fname] = attr.fontname;
673
sgraph[dotty.keys.fsize] = ston (attr.fontsize);
674
sgraph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
675
if (attr.style == 'filled' & attr.color == 'black')
676
sgraph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
678
sgraph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
680
dotty.protogt.unpacknodeattr = function (gt, node) {
684
if (dotty.fontmap[attr.fontname])
685
node[dotty.keys.fname] = dotty.fontmap[attr.fontname];
687
node[dotty.keys.fname] = attr.fontname;
688
node[dotty.keys.fsize] = ston (attr.fontsize);
689
node[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
690
if (attr.style == 'filled' & attr.color == 'black')
691
node[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
693
node[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
695
dotty.protogt.unpackedgeattr = function (gt, edge) {
699
if (dotty.fontmap[attr.fontname])
700
edge[dotty.keys.fname] = dotty.fontmap[attr.fontname];
702
edge[dotty.keys.fname] = attr.fontname;
703
edge[dotty.keys.fsize] = ston (attr.fontsize);
704
edge[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
705
if (attr.style == 'filled' & attr.color == 'black')
706
edge[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
708
edge[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
709
if (attr.label & attr.label ~= '' & ~edge.lp & edge.points) {
710
if ((n = tablesize (edge.points)) > 4)
712
'x' = edge.points[toint (n / 2)].x + 5;
713
'y' = edge.points[toint (n / 2)].y + 5;
717
'x' = (edge.points[1].x + edge.points[2].x) / 2 + 5;
718
'y' = (edge.points[1].y + edge.points[2].y) / 2 + 5;
722
dotty.protogt.unpackattr = function (gt) {
723
local gid, sgraph, nid, node, eid, edge, graph, attr;
726
attr = graph.graphattr;
727
if (dotty.fontmap[attr.fontname])
728
graph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
730
graph[dotty.keys.fname] = attr.fontname;
731
graph[dotty.keys.fsize] = ston (attr.fontsize);
732
graph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
733
if (attr.style == 'filled' & attr.color == 'black')
734
graph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
736
graph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
738
# Does this work? Want to save/restore parent filename in graph specification
739
graph[dotty.keys.parent] = attr.parent;
740
for (gid in graph.graphdict) {
741
sgraph = graph.graphs[graph.graphdict[gid]];
742
attr = sgraph.graphattr;
743
if (dotty.fontmap[attr.fontname])
744
sgraph[dotty.keys.fname] = dotty.fontmap[attr.fontname];
746
sgraph[dotty.keys.fname] = attr.fontname;
747
sgraph[dotty.keys.fsize] = ston (attr.fontsize);
748
sgraph[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
749
if (attr.style == 'filled' & attr.color == 'black')
750
sgraph[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
752
sgraph[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
754
for (nid in graph.nodedict) {
755
node = graph.nodes[graph.nodedict[nid]];
757
if (dotty.fontmap[attr.fontname])
758
node[dotty.keys.fname] = dotty.fontmap[attr.fontname];
760
node[dotty.keys.fname] = attr.fontname;
761
node[dotty.keys.fsize] = ston (attr.fontsize);
762
node[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
763
if (attr.style == 'filled' & attr.color == 'black')
764
node[dotty.keys.color] = gt.getcolor (gt.views, 'grey');
766
node[dotty.keys.color] = gt.getcolor (gt.views, attr.color);
768
for (eid in graph.edges) {
769
edge = graph.edges[eid];
771
if (dotty.fontmap[attr.fontname])
772
edge[dotty.keys.fname] = dotty.fontmap[attr.fontname];
774
edge[dotty.keys.fname] = attr.fontname;
775
edge[dotty.keys.fsize] = ston (attr.fontsize);
776
edge[dotty.keys.fcolor] = gt.getcolor (gt.views, attr.fontcolor);
777
edge[dotty.keys.color] = gt.getcolor (gt.views, attr.color);