comparison toolboxes/graph_visualisation/share/graphviz/lefty/dotty.lefty @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 #
2 # DOTTY
3 #
4 dotty = [
5 'keys' = [
6 'nid' = 'nid';
7 'eid' = 'eid';
8 'gid' = 'gid';
9 'name' = 'name';
10 'attr' = 'attr';
11 'gattr' = 'graphattr';
12 'eattr' = 'edgeattr';
13 'nattr' = 'nodeattr';
14 'edges' = 'edges';
15 'tail' = 'tail';
16 'tport' = 'tport';
17 'head' = 'head';
18 'hport' = 'hport';
19 'pos' = 'pos';
20 'size' = 'size';
21 'rect' = 'rect';
22 'fname' = 'fontname';
23 'fsize' = 'fontsize';
24 'fcolor' = 'fontcolor';
25 'dcolor' = 'drawcolor';
26 'bcolor' = 'fillcolor';
27 ];
28 'maps' = [
29 'X11' = [
30 'fontmap' = [
31 'Times-Roman' = '-*-times-medium-r-*--%d-*-*-*-*-*-*-1';
32 'Times-Italic' = '-*-times-medium-i-*--%d-*-*-*-*-*-*-1';
33 'Times-Bold' = '-*-times-bold-r-*--%d-*-*-*-*-*-*-1';
34 'Courier' = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
35 'Courier-Bold' = '-*-courier-bold-r-*--%d-*-*-*-*-*-*-1';
36 'Helvetica' = (
37 '-*-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1'
38 );
39 'Helvetica-Bold' = (
40 '-*-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1'
41 );
42 ];
43 'psfontmap' = [
44 'Times-Roman' = 'Times-Roman';
45 'Times-Italic' = 'Times-Italic';
46 'Times-Bold' = 'Times-Bold';
47 'Courier' = 'Courier';
48 'Courier-Bold' = 'Courier-Bold';
49 'Helvetica' = 'Helvetica';
50 'Helvetica-Bold' = 'Helvetica-Bold';
51 ];
52 ];
53 'mswin' = [
54 'fontmap' = [
55 'Times-Roman' = 'Times New Roman';
56 'Times-Italic' = 'Times New Roman Italic';
57 'Times-Bold' = 'Times New Roman Bold';
58 'Courier' = 'Courier New';
59 'Courier-Bold' = 'Courier New Bold';
60 'Helvetica' = 'Arial';
61 'Helvetica-Bold' = 'Arial Bold';
62 ];
63 'psfontmap' = [
64 'Times-Roman' = 'Times New Roman';
65 'Times-Italic' = 'Times New Roman Italic';
66 'Times-Bold' = 'Times New Roman Bold';
67 'Courier' = 'Courier New';
68 'Courier-Bold' = 'Courier New Bold';
69 'Helvetica' = 'Arial';
70 'Helvetica-Bold' = 'Arial Bold';
71 ];
72 ];
73 ];
74 'protogt' = [
75 'graph' = [
76 'graphattr' = [
77 'fontsize' = '14';
78 'fontname' = 'Times-Roman';
79 'fontcolor' = 'black';
80 ];
81 'nodeattr' = [
82 'shape' = 'ellipse';
83 'fontsize' = '14';
84 'fontname' = 'Times-Roman';
85 'fontcolor' = 'black';
86 'style' = 'solid';
87 ];
88 'edgeattr' = [
89 'fontsize' = '14';
90 'fontname' = 'Times-Roman';
91 'fontcolor' = 'black';
92 'style' = 'solid';
93 ];
94 'graphdict' = [];
95 'nodedict' = [];
96 'graphs' = [];
97 'nodes' = [];
98 'edges' = [];
99 'maxgid' = 0;
100 'maxnid' = 0;
101 'maxeid' = 0;
102 'type' = 'digraph';
103 ];
104 'layoutmode' = 'sync';
105 'lserver' = 'dot';
106 'edgehandles' = 1;
107 'noundo' = 0;
108 ];
109 'lservers' = [];
110 'mlevel' = 0;
111 'graphs' = [];
112 'views' = [];
113 'protovt' = [
114 'normal' = [
115 'name' = 'DOTTY';
116 'orig' = ['x' = 1; 'y' = 1;];
117 'size' = ['x' = 420; 'y' = 520;];
118 'wrect' = [
119 0 = ['x' = 0; 'y' = 0;];
120 1 = ['x' = 400; 'y' = 500;];
121 ];
122 'vsize' = ['x' = 400; 'y' = 500;];
123 'w2v' = 1;
124 ];
125 'birdseye' = [
126 'type' = 'birdseye';
127 'name' = 'DOTTY birdseye view';
128 'orig' = ['x' = 1; 'y' = 1;];
129 'size' = ['x' = 220; 'y' = 260;];
130 'wrect' = [
131 0 = ['x' = 0; 'y' = 0;];
132 1 = ['x' = 200; 'y' = 250;];
133 ];
134 'vsize' = ['x' = 200; 'y' = 250;];
135 'w2v' = 1;
136 ];
137 ];
138 'pagesizes' = [
139 '8.5x11' = ['x' = 8; 'y' = 10.5;];
140 '11x17' = ['x' = 10.5; 'y' = 16.5;];
141 '36x50' = ['x' = 35.5; 'y' = 49.5;];
142 ];
143 ];
144 load ('dotty_draw.lefty');
145 load ('dotty_edit.lefty');
146 load ('dotty_layout.lefty');
147 load ('dotty_ui.lefty');
148 #
149 # initialization functions
150 #
151 dotty.init = function () {
152 dotty.fontmap = dotty.maps[getenv ('LEFTYWINSYS')].fontmap;
153 dotty.clipgt = dotty.protogt.creategraph (['noundo' = 1;]);
154 dotty.inited = 1;
155 };
156 dotty.simple = function (file) {
157 if (dotty.inited ~= 1)
158 dotty.init ();
159 dotty.createviewandgraph (file, 'file', null, null);
160 txtview ('off');
161 };
162 #
163 # main operations
164 #
165 dotty.protogt.creategraph = function (protogt) {
166 local gt, id, gtid;
167
168 if (~protogt)
169 protogt = dotty.protogt;
170 for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
171 ;
172 gt = (dotty.graphs[gtid] = []);
173 if (protogt.mode ~= 'replace') {
174 for (id in dotty.protogt)
175 gt[id] = copy (dotty.protogt[id]);
176 }
177 for (id in protogt)
178 gt[id] = copy (protogt[id]);
179 gt.gtid = gtid;
180 gt.views = [];
181 gt.undoarray = ['level' = 0; 'entries' = [];];
182 gt.busy = 0;
183 return gt;
184 };
185 dotty.protogt.copygraph = function (ogt) {
186 local gt, gtid, id;
187
188 for (gtid = 0; dotty.graphs[gtid]; gtid = gtid + 1)
189 ;
190 gt = (dotty.graphs[gtid] = []);
191 for (id in ogt)
192 gt[id] = copy (ogt[id]);
193 gt.gtid = gtid;
194 gt.views = [];
195 gt.undoarray = ['level' = 0; 'entries' = [];];
196 gt.busy = 0;
197 return gt;
198 };
199 dotty.protogt.destroygraph = function (gt) {
200 local vid, vlist;
201
202 if (gt.layoutpending > 0)
203 gt.cancellayout (gt);
204 for (vid in gt.views)
205 vlist[vid] = gt.views[vid];
206 for (vid in gt.views)
207 gt.destroyview (gt, vlist[vid]);
208 remove (gt.gtid, dotty.graphs);
209 };
210 dotty.protogt.loadgraph = function (gt, name, type, protograph, layoutflag) {
211 local fd, vid, vt, graph, nid, eid, gid;
212
213 if (gt.layoutpending > 0)
214 gt.cancellayout (gt);
215 if (~name)
216 if (~(name = ask ('file name:', 'file', '')))
217 return;
218 dotty.pushbusy (gt, gt.views);
219 dotty.message (1, 'loading');
220 if (~protograph)
221 protograph = dotty.protogt.graph;
222 if (
223 ~((fd = dotty.openio (name, type, 'r')) >= 0) |
224 ~(graph = readgraph (fd, protograph))
225 ) {
226 dotty.message (0, 'cannot load graph');
227 dotty.popbusy (gt, gt.views);
228 return;
229 }
230 for (vid in gt.views) {
231 vt = gt.views[vid];
232 vt.colors = [];
233 vt.colorn = 2;
234 }
235 gt.graph = graph;
236 gt.name = name;
237 gt.type = type;
238 gt.undoarray = ['level' = 0; 'entries' = [];];
239 if (~(type == 'file' & name == '-'))
240 closeio (fd);
241 graph.maxgid = tablesize (graph.graphs);
242 graph.maxnid = tablesize (graph.nodes);
243 graph.maxeid = tablesize (graph.edges);
244 for (nid in graph.nodes)
245 graph.nodes[nid][dotty.keys.nid] = nid;
246 for (eid in graph.edges)
247 graph.edges[eid][dotty.keys.eid] = eid;
248 for (gid in graph.graphs)
249 graph.graphs[gid][dotty.keys.gid] = gid;
250 gt.unpackattr (gt);
251 if (layoutflag) {
252 dotty.message (1, 'generating layout');
253 gt.layoutgraph (gt);
254 }
255 dotty.popbusy (gt, gt.views);
256 return gt.graph;
257 };
258 dotty.protogt.savegraph = function (gt, name, type) {
259 local fd;
260
261 if (~name)
262 if (~(name = ask ('file name:', 'file', '')))
263 return;
264 if (
265 ~((fd = dotty.openio (name, type, 'w')) >= 0) |
266 ~writegraph (fd, gt.graph, 0)
267 ) {
268 dotty.message (0, 'cannot save graph');
269 return;
270 }
271 if (~(type == 'file' & name == '-'))
272 closeio (fd);
273 };
274 dotty.protogt.setgraph = function (gt, graph) {
275 local vid, vt, nid, eid, gid;
276
277 if (gt.layoutpending > 0)
278 gt.cancellayout (gt);
279 for (vid in gt.views) {
280 vt = gt.views[vid];
281 vt.colors = [];
282 vt.colorn = 2;
283 }
284 gt.graph = copy (graph);
285 gt.undoarray = ['level' = 0; 'entries' = [];];
286 gt.unpackattr (gt);
287 gt.graph.maxgid = tablesize (graph.graphs);
288 gt.graph.maxnid = tablesize (graph.nodes);
289 gt.graph.maxeid = tablesize (graph.edges);
290 for (nid in gt.graph.nodes)
291 gt.graph.nodes[nid][dotty.keys.nid] = nid;
292 for (eid in gt.graph.edges)
293 gt.graph.edges[eid][dotty.keys.eid] = eid;
294 for (gid in gt.graph.graphs)
295 gt.graph.graphs[gid][dotty.keys.gid] = gid;
296 gt.unpackattr (gt);
297 dotty.message (1, 'generating layout');
298 gt.layoutgraph (gt);
299 return gt.graph;
300 };
301 dotty.protogt.erasegraph = function (gt, protogt, protovt) {
302 local vid, vt;
303
304 if (gt.layoutpending > 0)
305 gt.cancellayout (gt);
306 for (vid in gt.views) {
307 vt = gt.views[vid];
308 vt.colors = [];
309 vt.colorn = 2;
310 clear (vt.canvas);
311 }
312 if (~protogt)
313 protogt = dotty.protogt;
314 gt.graph = copy (protogt.graph);
315 gt.undoarray = ['level' = 0; 'entries' = [];];
316 };
317 dotty.protogt.layoutgraph = function (gt) {
318 if (gt.graph.graphattr.xdotversion) {
319 gt.unpacklayout (gt, gt.graph);
320 gt.setviewsize (gt.views, gt.graph.rect);
321 gt.redrawgraph (gt, gt.views);
322 return;
323 }
324 if (gt.layoutmode == 'async') {
325 if (~gt.haveinput) {
326 gt.startlayout (gt);
327 return;
328 }
329 if (~gt.finishlayout (gt))
330 return;
331 gt.setviewsize (gt.views, gt.graph.rect);
332 gt.redrawgraph (gt, gt.views);
333 } else {
334 if (~gt.startlayout (gt))
335 return;
336 else
337 while (~gt.finishlayout (gt))
338 ;
339 gt.setviewsize (gt.views, gt.graph.rect);
340 gt.redrawgraph (gt, gt.views);
341 }
342 };
343 dotty.protogt.createview = function (gt, protovt) {
344 local vt, ovt, id, t;
345
346 vt = [];
347 vt.colors = [];
348 vt.colorn = 2;
349 if (~protovt)
350 protovt = dotty.protovt.normal;
351 if (protovt.mode ~= 'replace') {
352 for (id in dotty.protovt[protovt.type])
353 vt[id] = copy (dotty.protovt[protovt.type][id]);
354 }
355 for (id in protovt)
356 vt[id] = copy (protovt[id]);
357 if (~(vt.parent >= 0)) {
358 vt.view = createwidget (-1, [
359 'type' = 'view';
360 'name' = vt.name;
361 'origin' = vt.orig;
362 'size' = vt.size;
363 ]);
364 vt.scroll = createwidget (vt.view, ['type' = 'scroll';]);
365 } else {
366 vt.view = -1;
367 vt.scroll = createwidget (vt.parent, [
368 'type' = 'scroll';
369 'size' = vt.size;
370 ]);
371 }
372 vt.canvas = createwidget (vt.scroll, [
373 'type' = 'canvas';
374 'color' = [0 = protovt.bgcolor; 1 = protovt.fgcolor;];
375 ]);
376 setwidgetattr (vt.canvas, [
377 'window' = vt.wrect;
378 'viewport' = vt.vsize;
379 ]);
380 clear (vt.canvas);
381 dotty.views[vt.canvas] = vt;
382 vt.vtid = vt.canvas;
383 vt.gtid = gt.gtid;
384 gt.views[vt.vtid] = vt;
385 dotty.views[vt.scroll] = vt;
386 if (vt.view ~= -1)
387 dotty.views[vt.view] = vt;
388 if (protovt.colors & tablesize (protovt.colors) > 0) {
389 for (id in protovt.colors)
390 if (id == '_bgcolor_')
391 setwidgetattr (vt.canvas, [
392 'color' = [0 = protovt.colors[id];];
393 ]);
394 else if (setwidgetattr (vt.canvas, ['color' = [
395 protovt.colors[id] = id;
396 ];]) ~= 1) {
397 t = split (id, ' ');
398 if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
399 'color' = [protovt.colors[id] = [
400 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
401 ];];
402 ]) ~= 1) {
403 dotty.message (
404 0, concat ('unknown color ', id, ' using #1')
405 );
406 }
407 }
408 vt.colors = copy (protovt.colors);
409 vt.colorn = protovt.colorn;
410 } else if (tablesize (gt.views) > 1) {
411 for (id in gt.views)
412 if (gt.views[id] ~= vt)
413 break;
414 ovt = gt.views[id];
415 for (id in ovt.colors)
416 if (id == '_bgcolor_')
417 setwidgetattr (vt.canvas, ['color' = [0 = ovt.colors[id];];]);
418 else if (setwidgetattr (vt.canvas, ['color' = [
419 ovt.colors[id] = id;
420 ];]) ~= 1) {
421 t = split (id, ' ');
422 if (tablesize (t) ~= 3 | setwidgetattr (vt.canvas, [
423 'color' = [ovt.colors[id] = [
424 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
425 ];];
426 ]) ~= 1) {
427 dotty.message (
428 0, concat ('unknown color ', id, ' using #1')
429 );
430 }
431 }
432 vt.colors = copy (ovt.colors);
433 vt.colorn = ovt.colorn;
434 }
435 if (gt.graph.rect)
436 gt.setviewsize ([vt.vtid = vt;], gt.graph.rect);
437 gt.drawgraph (gt, [vt.vtid = vt;]);
438 for (id in vt.uifuncs)
439 if (id == 'closeview')
440 widgets[vt.view][id] = vt.uifuncs[id];
441 else
442 widgets[vt.canvas][id] = vt.uifuncs[id];
443 return vt;
444 };
445 dotty.protogt.destroyview = function (gt, vt) {
446 destroywidget (vt.canvas);
447 destroywidget (vt.scroll);
448 if (vt.view ~= -1) {
449 destroywidget (vt.view);
450 remove (vt.view, dotty.views);
451 }
452 remove (vt.scroll, dotty.views);
453 remove (vt.canvas, dotty.views);
454 if (vt.gtid >= 0)
455 remove (vt.vtid, gt.views);
456 if (tablesize (dotty.views) == 0)
457 exit ();
458 };
459 dotty.protogt.zoom = function (gt, vt, factor, pos) {
460 gt.setviewscale ([vt.vtid = vt;], factor);
461 if (pos)
462 gt.setviewcenter ([vt.vtid = vt;], pos);
463 gt.redrawgraph (gt, [vt.vtid = vt;]);
464 };
465 dotty.protogt.findnode = function (gt, vt) {
466 local key, node, node1, nid;
467
468 if (~(key = ask ('give node name or label')))
469 return;
470 if (gt.graph.nodedict[key] >= 0)
471 node = gt.graph.nodes[gt.graph.nodedict[key]];
472 else if (gt.graph.nodedict[ston (key)] >= 0)
473 node = gt.graph.nodes[gt.graph.nodedict[ston (key)]];
474 else {
475 for (nid in gt.graph.nodes) {
476 node1 = gt.graph.nodes[nid];
477 if (node1.attr.label == key | node1.attr.label == ston (key)) {
478 node = node1;
479 break;
480 }
481 }
482 }
483 if (~node) {
484 dotty.message (0, concat ('cannot find node: ', key));
485 return;
486 }
487 gt.setviewcenter ([vt.vtid = vt;], node.pos);
488 };
489 dotty.protogt.setattr = function (gt, obj) {
490 local kv, t, attr, value, n, i, s;
491
492 if (~(kv = ask ('give attr/value, eg. color=blue')))
493 return;
494 t = split (kv, '=');
495 attr = t[0];
496 value = t[1];
497 if ((n = tablesize (t)) > 2)
498 for (i = 2; i < n; i = i + 1)
499 value = concat (value, '=', t[i]);
500 # Check for HTML string and convert using lefty convention
501 s = split (value, '');
502 n = tablesize (s);
503 if ((s[0] == '<') & (s[n-1] == '>')) {
504 s[0] = '>';
505 s[n-1] = '<';
506 value = s[0];
507 for (i = 1; i < n; i = i + 1)
508 value = concat (value, s[i]);
509 }
510 if (
511 obj.attr == gt.graph.graphattr |
512 obj.attr == gt.graph.edgeattr |
513 obj.attr == gt.graph.nodeattr
514 ) {
515 obj.attr[attr] = value;
516 return;
517 }
518 if (obj.nid >= 0) {
519 gt.undrawnode (gt, gt.views, obj);
520 obj.attr[attr] = value;
521 gt.unpacknodeattr (gt, obj);
522 gt.drawnode (gt, gt.views, obj);
523 } else if (obj.eid >= 0) {
524 gt.undrawedge (gt, gt.views, obj);
525 obj.attr[attr] = value;
526 gt.unpackedgeattr (gt, obj);
527 gt.drawedge (gt, gt.views, obj);
528 }
529 };
530 dotty.protogt.getattr = function (gt, node) {
531 local kv;
532
533 if (~(kv.key = ask ('give attr name')))
534 return null;
535 if ((kv.val = node.attr[kv.key]))
536 return kv;
537 return null;
538 };
539 #
540 # utilities
541 #
542 dotty.createviewandgraph = function (name, type, protogt, protovt) {
543 local vt, gt;
544
545 if (~protogt)
546 protogt = dotty.protogt;
547 if (protogt.creategraph)
548 gt = protogt.creategraph (protogt);
549 else
550 gt = dotty.protogt.creategraph (protogt);
551 vt = gt.createview (gt, protovt);
552 if (~protogt.graph)
553 protogt.graph = copy (dotty.protogt.graph);
554 if (name)
555 gt.loadgraph (gt, name, type, protogt.graph, 1);
556 return ['gt' = gt; 'vt' = vt;];
557 };
558 dotty.openio = function (name, type, mode) {
559 local fd;
560
561 if (~name)
562 return null;
563 if (type == 'file') {
564 if (name == '-') {
565 if (mode == 'r' | mode == 'r+')
566 fd = 0;
567 else
568 fd = 1;
569 } else if (~((fd = openio ('file', name, mode)) >= 0)) {
570 dotty.message (0, concat ('cannot open file: ', name));
571 return null;
572 }
573 } else if (type == 'pipe') {
574 if (~((fd = openio (
575 'pipe', 'ksh', mode, concat ("%e ", name)
576 )) >= 0)) {
577 dotty.message (0, concat ('cannot run command: ', name));
578 return null;
579 }
580 } else
581 return null;
582 return fd;
583 };
584 dotty.pushbusy = function (gt, views) {
585 local vid;
586
587 if (gt.busy == 0)
588 for (vid in gt.views)
589 setwidgetattr (vid, ['cursor' = 'watch';]);
590 gt.busy = gt.busy + 1;
591 };
592 dotty.popbusy = function (gt, views) {
593 local vid;
594
595 gt.busy = gt.busy - 1;
596 if (gt.busy == 0)
597 for (vid in gt.views)
598 setwidgetattr (vid, ['cursor' = 'default';]);
599 };
600 dotty.message = function (level, text) {
601 if (level <= dotty.mlevel)
602 echo ('dotty.lefty: ', text);
603 };
604 #
605 # printing or saving to file
606 #
607 dotty.protogt.printorsave = function (gt, vt, otype, name, mode, ptype) {
608 local pr, wrect, vsize, xy, psize, canvas, pscanvas, cid, cname, t;
609 local graph, edgehandles, fontmap, eid, edge, nid, node, gid, sgraph;
610 local did, draw, i;
611
612 if (~otype)
613 if (~(otype = ask ('print to', 'choice', 'file|printer')))
614 return;
615 if (otype == 'printer') {
616 if (~getenv ('TMPDIR'))
617 name = concat (getenv ('HOME'), '/.dottyout.ps');
618 else
619 name = concat (getenv ('TMPDIR'), '/.dottyout.ps', random (10000));
620 if (getenv ('LEFTYWINSYS') ~= 'mswin' & ~pr)
621 if (~(pr = ask ('printer command', 'string', 'lpr')))
622 return;
623 }
624 if (~name)
625 if (~(name = ask ('postscript file', 'file', 'out.ps')))
626 return;
627 if (~ptype)
628 if (~(ptype = ask ('page size', 'choice', '8.5x11|11x17|36x50')))
629 return;
630 if (~mode)
631 if (~(mode = ask ('mode', 'choice', 'portrait|landscape|best fit')))
632 return;
633 wrect = copy (vt.wrect);
634 wrect[0].x = wrect[0].x - 1;
635 wrect[1].x = wrect[1].x + 1;
636 wrect[0].y = wrect[0].y - 1;
637 wrect[1].y = wrect[1].y + 1;
638 vsize = copy (vt.vsize);
639 if (vsize.x == 0)
640 vsize.x = 1;
641 if (vsize.y == 0)
642 vsize.y = 1;
643 xy = vsize.x / vsize.y;
644 if (mode == 'best fit') {
645 if (xy < 1)
646 mode = 'portrait';
647 else
648 mode = 'landscape';
649 }
650 psize = dotty.pagesizes[ptype];
651 if (mode == 'portrait') {
652 if (xy < psize.x / psize.y) {
653 vsize.y = psize.y * 300;
654 vsize.x = vsize.y * xy;
655 } else {
656 vsize.x = psize.x * 300;
657 vsize.y = vsize.x / xy;
658 }
659 } else {
660 if (xy < psize.y / psize.x) {
661 vsize.y = psize.x * 300;
662 vsize.x = vsize.y * xy;
663 } else {
664 vsize.x = psize.y * 300;
665 vsize.y = vsize.x / xy;
666 }
667 }
668 if (~((pscanvas = createwidget (-1, [
669 'type' = 'ps';
670 'origin' = ['x' = 0; 'y' = 0;];
671 'size' = vsize;
672 'mode' = mode;
673 'name' = name;
674 ])) >= 0)) {
675 dotty.message (0, 'cannot open printer device');
676 return;
677 }
678 for (cname in vt.colors) {
679 cid = vt.colors[cname];
680 if (cname == '_bgcolor_')
681 setwidgetattr (pscanvas, ['color' = [0 = cid;];]);
682 else if (setwidgetattr (pscanvas, ['color' = [cid = cname;];]) ~= 1) {
683 t = split (cname, ' ');
684 if (tablesize (t) ~= 3 | setwidgetattr (pscanvas, [
685 'color' = [cid = [
686 'h' = ston (t[0]); 's' = ston (t[1]); 'v' = ston (t[2]);
687 ];];
688 ]) ~= 1) {
689 dotty.message (
690 0, concat ('unknown color ', cname, ' using #1')
691 );
692 }
693 }
694 }
695 setwidgetattr (pscanvas, ['window' = wrect;]);
696 graph = copy (gt.graph);
697 canvas = vt.canvas;
698 vt.canvas = pscanvas;
699 edgehandles = gt.edgehandles;
700 gt.edgehandles = 0;
701 fontmap = dotty.maps[getenv ('LEFTYWINSYS')].psfontmap;
702 for (eid in graph.edges) {
703 edge = graph.edges[eid];
704 edge.fontname = fontmap[edge.attr.fontname];
705 for (did in edge.draws) {
706 if (did == 'ep')
707 continue;
708 draw = edge.draws[did];
709 for (i = 0; draw[i]; i = i + 1)
710 if (draw[i].type == 'F')
711 draw[i].fn = fontmap[draw[i].ofn];
712 }
713 gt.drawedge (gt, [0 = vt;], edge);
714 }
715 for (nid in graph.nodes) {
716 node = graph.nodes[nid];
717 node.fontname = fontmap[node.attr.fontname];
718 for (did in node.draws) {
719 if (did == 'ep')
720 continue;
721 draw = node.draws[did];
722 for (i = 0; draw[i]; i = i + 1)
723 if (draw[i].type == 'F')
724 draw[i].fn = fontmap[draw[i].ofn];
725 }
726 gt.drawnode (gt, [0 = vt;], node);
727 }
728 for (gid in graph.graphs) {
729 sgraph = graph.graphs[gid];
730 sgraph.fontname = fontmap[sgraph.graphattr.fontname];
731 for (did in sgraph.draws) {
732 if (did == 'ep')
733 continue;
734 draw = sgraph.draws[did];
735 for (i = 0; draw[i]; i = i + 1)
736 if (draw[i].type == 'F')
737 draw[i].fn = fontmap[draw[i].ofn];
738 }
739 gt.drawsgraph (gt, [0 = vt;], sgraph);
740 }
741 graph.fontname = fontmap[graph.graphattr.fontname];
742 gt.drawsgraph (gt, [0 = vt;], graph);
743 gt.edgehandles = edgehandles;
744 vt.canvas = canvas;
745 destroywidget (pscanvas);
746 if (otype == 'printer' & getenv ('LEFTYWINSYS') ~= 'mswin')
747 system (concat (pr, ' ', name, '; rm ',name));
748 };