source: trunk/Jgraph/draw.c@ 660

Last change on this file since 660 was 420, checked in by Nicholas Riley, 17 years ago

Jgraph: my changes - ANSIfication, few minor bug fixes; works on OS X 10.5 now

File size: 24.5 KB
Line 
1/*
2 * $Source: /tmp_mnt/n/fs/grad1/jsp/src/jgraph/RCS/draw.c,v $
3 * $Revision: 8.3 $
4 * $Date: 92/11/30 11:42:10 $
5 * $Author: jsp $
6 */
7
8#include "jgraph.h"
9#include <stdio.h>
10#include <math.h>
11#include <stdlib.h> //by pzn@debian.org
12#include <string.h> //by pzn@debian.org
13
14static char real_eof = EOF;
15
16float ctop(val, axis)
17float val;
18Axis axis;
19{
20 if (axis->is_lg) {
21 if (val <= 0.0) {
22 error_header();
23 fprintf(stderr,
24 "Value of %f is at negative infinity with logarithmic %c axis\n",
25 val, (axis->is_x) ? 'x' : 'y');
26 exit(1);
27 }
28 return (log(val) / axis->logfactor - axis->logmin) * axis->factor;
29 } else {
30 return (val - axis->min) * axis->factor;
31 }
32}
33
34float disttop(val, axis)
35float val;
36Axis axis;
37{
38 if (axis->is_lg) {
39 return FCPI * val;
40 } else {
41 return (val) * axis->factor;
42 }
43}
44
45float intop(val)
46float val;
47{
48 return FCPI * val;
49}
50
51#define MAXIMUM(a,b) ((a > b) ? a : b)
52
53void draw_label(Label l)
54{
55 if (l->label == CNULL) return;
56 comment(l->label);
57 print_label(l);
58}
59
60void draw_axis(Axis a, Axis other)
61{
62 char orientation;
63 Hash h;
64 String s;
65
66 orientation = (a->is_x) ? 'x' : 'y';
67 setlinewidth(1.0);
68 comment("Drawing Axis");
69 if (a->grid_lines) {
70 comment("Drawing Grid lines");
71 gsave();
72 setgray(a->gr_graytype, a->gr_gray);
73 for (h = first(a->hash_lines); h != nil(a->hash_lines); h = next(h)) {
74 if (h->major) {
75 printline(h->loc, 0.0, h->loc, other->psize, orientation);
76 }
77 }
78 grestore();
79 }
80 if (a->mgrid_lines) {
81 comment("Drawing Minor Grid lines");
82 gsave();
83 setgray(a->mgr_graytype, a->mgr_gray);
84 for (h = first(a->hash_lines); h != nil(a->hash_lines); h = next(h)) {
85 if (!h->major) {
86 printline(h->loc, 0.0, h->loc, other->psize, orientation);
87 }
88 }
89 grestore();
90 }
91 gsave();
92 setgray(a->graytype, a->gray);
93 if (a->draw_axis_line) {
94 printline(0.0, a->draw_at, a->psize, a->draw_at, orientation);
95 }
96 if (a->draw_hash_marks) {
97 comment("Drawing Hash Marks");
98 for (h = first(a->hash_lines); h != nil(a->hash_lines); h = next(h)) {
99 printline(h->loc, a->draw_hash_marks_at, h->loc,
100 a->draw_hash_marks_at + (h->size * a->hash_scale),
101 orientation);
102 }
103 }
104 if (a->draw_hash_labels) {
105 comment("Drawing Hash Labels");
106 for (s = first(a->hash_labels); s != nil(a->hash_labels); s = next(s)) {
107 a->hl->label = s->s->label;
108 if (a->is_x) {
109 a->hl->x = s->s->x;
110 } else {
111 a->hl->y = s->s->y;
112 }
113 draw_label(a->hl);
114 }
115 }
116 if (a->draw_axis_label) {
117 comment("Drawing Axis Label");
118 draw_label(a->label);
119 }
120 grestore();
121 printf("\n");
122}
123
124
125void set_clip(Graph g)
126{
127 comment("Setting Clip");
128 printf("newpath\n");
129 printf(" 0 0 moveto 0 %f lineto %f %f lineto %f 0 lineto\n",
130 g->y_axis->psize, g->x_axis->psize,
131 g->y_axis->psize, g->x_axis->psize);
132 printf(" closepath clip newpath\n");
133}
134
135void draw_curve(Curve c, Graph g);
136
137void draw_curves(Graph g)
138{
139 Curve c;
140
141 gsave();
142 printf("\n");
143 if (g->clip) set_clip(g);
144 for(c = first(g->curves); c != nil(g->curves); c = next(c)) {
145 draw_curve(c, g);
146 }
147 grestore();
148 printf("\n");
149}
150
151void draw_mark(float x, float y, Curve c, Graph g);
152void draw_arrow(float x1, float y1, float x2, float y2, Curve c);
153
154void draw_curve(Curve c, Graph g)
155{
156 Point p, px, py;
157 int i, j;
158 float this_x, this_y, last_x, last_y, x, y;
159
160 gsave();
161 setgray(c->graytype, c->gray);
162 if (c->clip) set_clip(g);
163 if (first(c->xepts) != nil(c->xepts) ||
164 first(c->yepts) != nil(c->yepts)) {
165 comment("Drawing Epts");
166 px = first(c->xepts);
167 py = first(c->yepts);
168 setlinewidth(c->linethick);
169 setlinestyle('s', (Flist)0);
170 for (p = first(c->pts); p != nil(c->pts); p = next(p)) {
171 if (p->e == 'x') {
172 x = ctop(p->x, g->x_axis);
173 y = ctop(p->y, g->y_axis);
174 print_ebar(x, y, ctop(px->x, g->x_axis), c->marksize[1]/2.0, 'x');
175 px = next(px);
176 print_ebar(x, y, ctop(px->x, g->x_axis), c->marksize[1]/2.0, 'x');
177 px = next(px);
178 } else if (p->e == 'y') {
179 x = ctop(p->x, g->x_axis);
180 y = ctop(p->y, g->y_axis);
181 print_ebar(y, x, ctop(py->y, g->y_axis), c->marksize[0]/2.0, 'y');
182 py = next(py);
183 print_ebar(y, x, ctop(py->y, g->y_axis), c->marksize[0]/2.0, 'y');
184 py = next(py);
185 }
186 }
187 }
188
189 comment("Drawing Curve");
190 if (c->linetype != '0' || c->poly) {
191 if (c->bezier) {
192 i = 0;
193 j = 0;
194 if (c->poly) printf("newpath ");
195 for (p = first(c->pts); p != nil(c->pts); p = next(p)) {
196 if (j == 0 && i == 0) {
197 start_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis), c);
198 j++;
199 } else if (i != 0) {
200 bezier_control(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
201 } else {
202 bezier_end(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
203 j++;
204 }
205 if (!c->poly && j == 30 && i == 0) {
206 end_line();
207 p = prev(p);
208 j = 0;
209 i = 0;
210 } else i = (i + 1) % 3;
211 }
212 if (j != 0) {
213 if (c->poly) {
214 printf("closepath ");
215 setfill(0.0, 0.0, c->pfilltype, c->pfill, c->ppattern, c->pparg);
216 }
217 end_line();
218 }
219 } else {
220 i = 0;
221 if (c->poly) printf("newpath ");
222 for (p = first(c->pts);
223 p != nil(c->pts);
224 p = next(p)) {
225 if (i == 0) {
226 start_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis), c);
227 } else {
228 cont_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
229 }
230 if (!c->poly && i == 100 && next(p)) {
231 end_line();
232 p = prev(p);
233 i = 0;
234 } else i++;
235 }
236 if (i != 0) {
237 if (c->poly) {
238 printf("closepath ");
239 setfill(0.0, 0.0, c->pfilltype, c->pfill, c->ppattern, c->pparg);
240 }
241 end_line();
242 }
243 }
244 }
245 comment("Drawing Curve points");
246 i = 0;
247 for (p = first(c->pts);
248 p != nil(c->pts);
249 p = next(p)) {
250 this_x = ctop(p->x, g->x_axis);
251 this_y = ctop(p->y, g->y_axis);
252 if (!c->bezier || i == 0) draw_mark(this_x, this_y, c, g);
253 if (p != first(c->pts)) {
254 if (c->rarrows || (c->rarrow && p == last(c->pts))) {
255 if (!c->bezier || i == 0)
256 draw_arrow(this_x, this_y, last_x, last_y, c);
257 }
258 if (c->larrows || (c->larrow && prev(p) == first(c->pts))) {
259 if (!c->bezier || i == 1)
260 draw_arrow(last_x, last_y, this_x, this_y, c);
261 }
262 }
263 last_x = this_x;
264 last_y = this_y;
265 i = (i + 1) % 3;
266 }
267 grestore();
268 printf("\n");
269}
270
271void draw_mark(float x, float y, Curve c, Graph g)
272{
273 Point p;
274 float ms0, ms1, scx, scy, trx, try;
275 int i, j;
276 FILE *f;
277 char ch;
278 int done, newline;
279 char inp[100];
280 int bb[4];
281
282 if (c->marktype == 'n') return;
283 ms0 = c->marksize[0] / 2.0;
284 ms1 = c->marksize[1] / 2.0;
285
286 gsave();
287 printf(" %f %f translate %f rotate\n", x, y, c->mrotate);
288
289 switch (c->marktype) {
290 case 'n': break;
291 case 'E': if (c->eps == CNULL) break;
292 f = fopen(c->eps, "r");
293 if (f == NULL) {
294 fprintf(stderr, "Error: eps file %s couldn't be opened\n",
295 c->eps);
296 exit(1);
297 }
298 /* Get bbox */
299 newline = 1;
300 done = 0;
301 while(!done) {
302 while(!newline) {
303 ch = getc(f);
304 if (ch == real_eof) {
305 fprintf(stderr, "Error: Eps file '%s' has %s\n",
306 c->eps, "no bounding box");
307 exit(1);
308 }
309 newline = (ch == '\n');
310 }
311 fscanf(f, "%s", inp);
312 if (strcmp(inp, "%%BoundingBox:") == 0) done = 1;
313 }
314 for (i = 0; i < 4; i++) {
315 if (fscanf(f, "%d", &(bb[i])) == 0) {
316 fprintf(stderr, "Error: Eps file '%s': eof in %s\n",
317 c->eps, "bounding box");
318 exit(1);
319 }
320 }
321 if (bb[2] - bb[0] == 0) {
322 scx = ms0;
323 trx = 0.0;
324 } else {
325 scx = ms0 * 2.0/(float)(bb[2] - bb[0]);
326 trx = -(float)(bb[2] - bb[0])/2.0 - bb[0];
327 }
328 if (bb[3] - bb[1] == 0) {
329 scy = ms1;
330 try = 0.0;
331 } else {
332 scy = ms1 * 2.0/(float)(bb[3] - bb[1]);
333 try = -(float)(bb[3] - bb[1])/2.0 - bb[1];
334 }
335 /* Don't scale if ms == 0 0 */
336 if (ms0 == 0.0 && ms1 == 0.0) {
337 scx = 1.0;
338 scy = 1.0;
339 }
340
341 sprintf(inp, "Including eps file %s", c->eps);
342 comment(inp);
343 /* Use bbox to scale and translate */
344
345 printf("%f %f scale %f %f translate\n", scx, scy, trx, try);
346 /* Include the rest of the file */
347 for (ch = getc(f); ch != real_eof; ch = getc(f)) putchar(ch);
348 putchar('\n');
349 fclose(f);
350 break;
351 case 'p': if (c->postscript == CNULL) break;
352 if (ms0 != 0.0 || ms1 != 0.0) {
353 printf("%f %f scale\n", ms0, ms1);
354 }
355 if (!c->postfile) {
356 printf("%s\n", c->postscript);
357 } else {
358 f = fopen(c->postscript, "r");
359 if (f == NULL) {
360 fprintf(stderr,
361 "Error: postscript file %s couldn't be opened\n",
362 c->postscript);
363 exit(1);
364 }
365 for (ch = getc(f); ch != real_eof; ch = getc(f)) putchar(ch);
366 putchar('\n');
367 fclose(f);
368 }
369 break;
370 case 'c': printline(-ms0, 0.0, ms0, 0.0, 'x');
371 printline(-ms1, 0.0, ms1, 0.0, 'y');
372 break;
373 case 'b': start_poly(-ms0, -ms1);
374 cont_poly(ms0, -ms1);
375 cont_poly(ms0, ms1);
376 cont_poly(-ms0, ms1);
377 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
378 break;
379 case 'd': start_poly(-ms0, 0.0);
380 cont_poly(0.0, -ms1);
381 cont_poly(ms0, 0.0);
382 cont_poly(0.0, ms1);
383 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
384 break;
385 case 'g': p = first(c->general_marks);
386 if (p == nil(c->general_marks)) break;
387 if (next(p) == nil(c->general_marks)) break;
388 start_poly(p->x*ms0, p->y*ms1);
389 for(p = next(p); p != nil(c->general_marks); p = next(p))
390 cont_poly(p->x*ms0, p->y*ms1);
391 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
392 break;
393 case 'G': i = 0;
394 for (p = first(c->general_marks);
395 p != nil(c->general_marks);
396 p = next(p)) {
397 if (i == 0) {
398 printf("%f %f moveto ", p->x*ms0, p->y*ms1);
399 } else {
400 printf("%f %f lineto\n", p->x*ms0, p->y*ms1);
401 }
402 if (i == 100) {
403 printf("stroke\n");
404 p = prev(p);
405 i = 0;
406 } else i++;
407 }
408 if (i != 0) printf("stroke\n");
409 break;
410 case 'B': i = 0;
411 j = 0;
412 for (p = first(c->general_marks);
413 p != nil(c->general_marks);
414 p = next(p)) {
415 if (j == 0 && i == 0) {
416 printf("%f %f moveto ", p->x*ms0, p->y*ms1);
417 j++;
418 } else if (i != 0) {
419 printf("%f %f ", p->x*ms0, p->y*ms1);
420 } else {
421 printf("%f %f curveto\n", p->x*ms0, p->y*ms1);
422 j++;
423 }
424 if (j == 30 && i == 0) {
425 printf(" stroke\n");
426 p = prev(p);
427 j = 0;
428 i = 0;
429 } else i = (i + 1) % 3;
430 }
431 if (j != 0) printf(" stroke\n");
432 if (! ((i == 1) || (i == 0 && j == 0))) {
433 fprintf(stderr, "Error: curve %d, %s\n", c->num,
434 "wrong number of points for bezier marktype\n");
435 exit(1);
436 }
437 break;
438
439 case 'Z': i = 0;
440 j = 0;
441 for (p = first(c->general_marks);
442 p != nil(c->general_marks);
443 p = next(p)) {
444 if (i == 0 && j == 0) {
445 printf("newpath %f %f moveto ", p->x*ms0, p->y*ms1);
446 j++;
447 } else if (i != 0) {
448 printf("%f %f ", p->x*ms0, p->y*ms1);
449 } else {
450 printf("%f %f curveto\n", p->x*ms0, p->y*ms1);
451 }
452 i = (i + 1) % 3;
453 }
454 printf("closepath ");
455 setfill(x, y, c->filltype, c->fill, c->pattern, c->parg);
456 printf("stroke\n");
457
458 if (i != 1) {
459 fprintf(stderr, "Error: curve %d, %s\n", c->num,
460 "wrong number of points for bezier marktype\n");
461 exit(1);
462 }
463 break;
464
465 case 'x': printline(-ms0, -ms1, ms0, ms1, 'x');
466 printline(-ms0, ms1, ms0, -ms1, 'x');
467 break;
468 case 'o': printellipse(x, y, ms0, ms0,
469 c->filltype, c->fill, c->pattern, c->parg);
470 break;
471 case 'e': printellipse(x, y, ms0, ms1,
472 c->filltype, c->fill, c->pattern, c->parg);
473 break;
474 case 't': start_poly(ms0, -ms1);
475 cont_poly(0.0, ms1);
476 cont_poly(-ms0, -ms1);
477 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
478 break;
479 case 'X': start_poly(ms0, 0.0);
480 cont_poly(-ms0, 0.0);
481 cont_poly(-ms0, g->x_axis->draw_at - y);
482 cont_poly(ms0, g->x_axis->draw_at - y);
483 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
484 break;
485 case 'Y': start_poly(0.0, ms1);
486 cont_poly(0.0, -ms1);
487 cont_poly(g->y_axis->draw_at - x, -ms1);
488 cont_poly(g->y_axis->draw_at - x, ms1);
489 end_poly(x, y, c->filltype, c->fill, c->pattern, c->parg);
490 break;
491 case 'l': draw_label(c->lmark);
492 break;
493 default: error_header();
494 fprintf(stderr, "Unknown mark: %c\n", c->marktype);
495 break;
496 }
497 grestore();
498}
499
500void draw_arrow(float x1, float y1, float x2, float y2, Curve c)
501{
502 float dx, dy;
503 float ms0;
504 float theta, ct, st;
505
506
507 if (c->marktype == 'o') {
508 dx = x1 - x2;
509 dy = y1 - y2;
510 if (dx == 0.0 && dy == 0.0) return;
511
512 ms0 = c->marksize[0] / 2.0;
513 if (dx == 0.0) theta = asin(1.0); else theta = atan(dy/dx);
514 if (theta < 0.0) theta = -theta;
515 ct = cos(theta)*ms0;
516 st = sin(theta)*ms0;
517 x1 = x1 + ct*(dx > 0.0 ? -1.0 : 1.0);
518 y1 = y1 + st*(dy > 0.0 ? -1.0 : 1.0);
519
520 if ( ((x1 - x2 > 0) != (dx > 0)) ||
521 ((y1 - y2 > 0) != (dy > 0)) ) return;
522 }
523
524 dx = x1 - x2;
525 dy = y1 - y2;
526 if (dx == 0.0 && dy == 0.0) return;
527
528 gsave();
529 printf("%f %f translate %f %f atan rotate\n", x1, y1, dy, dx);
530 start_poly(0.0, 0.0);
531 cont_poly(-(c->asize[0]), (c->asize[1]));
532 cont_poly(-(c->asize[0]), -(c->asize[1]));
533 end_poly(0.0, 0.0, c->afilltype, c->afill, c->apattern, c->aparg);
534 grestore();
535 printf("\n");
536}
537
538void draw_legend(Graph g)
539{
540 Curve c;
541 Legend l;
542 float x, y;
543 char tmpmktype;
544
545 l = g->legend;
546 comment("Drawing legend");
547 if (l->type == 'n' || l->anylines < 0) return;
548 gsave();
549 if (l->type == 'u') {
550 printf("%f %f translate %f rotate\n", l->l->x, l->l->y, l->l->rotate);
551 }
552 for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
553 if (c->l->label != CNULL) {
554 gsave();
555 setgray(c->graytype, c->gray);
556 y = (c->l->ymax + c->l->ymin) / 2.0;
557 if (l->anylines) {
558 if (c->linetype != '0' && l->linelength != 0) {
559 if (l->type == 'c' && c->l->hj == 'r') {
560 x = c->l->x + l->midspace;
561 } else {
562 x = c->l->x - l->midspace - l->linelength;
563 }
564 start_line(x, y, c);
565 cont_line(x+l->linelength, y);
566 end_line();
567 }
568 tmpmktype = c->marktype;
569 c->marktype = 'n';
570 if (c->larrows || c->larrow) draw_arrow(x, y, x+l->linelength, y, c);
571 if (c->rarrows || c->rarrow) draw_arrow(x+l->linelength, y, x, y, c);
572 c->marktype = tmpmktype;
573 if (l->type == 'c' && c->l->hj == 'r') {
574 x = c->l->x + l->midspace + l->linelength / 2.0;
575 } else {
576 x = c->l->x - l->midspace - l->linelength / 2.0;
577 }
578 } else if (l->type == 'c' && c->l->hj == 'r') {
579 x = c->l->x + l->midspace;
580 } else {
581 x = c->l->x - l->midspace;
582 }
583 if (c->marktype == 'X' || c->marktype == 'Y') {
584 char old;
585 old = c->marktype;
586 c->marktype = 'b';
587 draw_mark(x, y, c, g);
588 c->marktype = old;
589 } else {
590 draw_mark(x, y, c, g);
591 }
592 grestore();
593 printf("\n");
594 draw_label(c->l);
595 }
596 }
597 grestore();
598 printf("\n");
599}
600
601void draw_strings(Graph g)
602{
603 String s;
604
605 comment("Drawing strings");
606 for (s = first(g->strings); s != nil(g->strings); s = next(s))
607 draw_label(s->s);
608}
609
610void draw_graph(Graph g)
611{
612 comment("Drawing New Graph");
613 printf("%f %f translate\n", g->x_translate, g->y_translate);
614 if (g->border) {
615 printline(0.0, 0.0, 0.0, g->y_axis->psize, 'x');
616 printline(0.0, 0.0, 0.0, g->x_axis->psize, 'y');
617 printline(g->x_axis->psize, 0.0, g->x_axis->psize, g->y_axis->psize, 'x');
618 printline(g->y_axis->psize, 0.0, g->y_axis->psize, g->x_axis->psize, 'y');
619 }
620 draw_axis(g->x_axis, g->y_axis);
621 draw_axis(g->y_axis, g->x_axis);
622 draw_label(g->title);
623 draw_curves(g);
624 draw_legend(g);
625 draw_strings(g);
626 printf("%f %f translate\n", - g->x_translate, - g->y_translate);
627
628}
629
630void draw_header(Graphs gs, int pp, int landscape);
631void draw_footer(Graphs gs, int pp);
632
633void draw_graphs(Graphs gs, int pp, int landscape)
634{
635 Graphs gs_p;
636 Graph g;
637 int page_counter=0;
638
639 for (gs_p = first(gs); gs_p != nil(gs); gs_p = next(gs_p)) {
640 page_counter++;
641 draw_header(gs_p, pp, landscape);
642 for (g = first(gs_p->g); g != nil(gs_p->g); g = next(g)) {
643 draw_graph(g);
644 }
645 draw_footer(gs_p, pp);
646 }
647 if (pp) {
648 printf("\n%%%%Trailer\n");
649 printf("%%%%Pages: %i\n",page_counter);
650 printf("%%%%EOF\n");
651 }
652}
653
654void draw_header(Graphs gs, int pp, int landscape)
655{
656 FILE *f;
657 char c;
658
659 if (gs->page == 1) {
660 if (pp) {
661 printf("%%!PS-Adobe-3.0\n");
662 printf("%%%%Pages: (atend)\n");
663 printf("%%%%Creator: jgraph\n");
664 printf("%%%%EndComments\n\n");
665 printf("%%%%BeginProlog\n");
666 printf("%%%%EndProlog\n");
667 printf("%%%%BeginSetup\n");
668 printf("%%%%EndSetup\n");
669 } else {
670 printf("%%!PS-Adobe-2.0 EPSF-1.2\n");
671 printf("%%%%Creator: jgraph\n");
672 }
673 }
674
675 if (pp) {
676 printf("\n%%%%Page: %d %d\n", gs->page, gs->page);
677 printf("%%%%BeginPageSetup\n");
678 printf("%%%%EndPageSetup\n\n");
679 }
680
681 if ( (gs->page>1) && !pp ) {
682 /* tring EPS with more than one page */
683 fprintf(stderr, "Error: 'newpage' token is not allowed"
684 " without '-P' command line option.\n");
685 exit(1);
686 }
687
688 /* if (landscape) {
689 printf("%%%%BoundingBox: %d %d %d %d\n", gs->bb[1], gs->bb[0],
690 gs->bb[3], gs->bb[2]);
691 } else {
692 printf("%%%%BoundingBox: %d %d %d %d\n", gs->bb[0], gs->bb[1],
693 gs->bb[2], gs->bb[3]);
694 }
695 printf("%%%%EndComments\n"); */
696
697 //BEGIN added by pzn@debian.org
698 { // expands the bounding box to fit characters with tilde, acute,...
699 // if user has set JGRAPH_BORDER enviroment variable
700 int expandborder=0;
701 char *s; \
702 s=(char *)getenv("JGRAPH_BORDER");
703 if (s!=NULL) {
704 expandborder=atoi(s);
705 }
706 if (!pp) {
707 if (landscape) {
708 printf("%%%%BoundingBox: %d %d %d %d\n", gs->bb[1]-expandborder,
709 gs->bb[0]-expandborder, gs->bb[3]+expandborder,
710 gs->bb[2]+expandborder);
711 } else {
712 printf("%%%%BoundingBox: %d %d %d %d\n", gs->bb[0]-expandborder,
713 gs->bb[1]-expandborder, gs->bb[2]+expandborder,
714 gs->bb[3]+expandborder);
715 }
716 printf("%%%%EndComments\n\n");
717 }
718 }
719
720 if (gs->page==1)
721 //reencode fonts to ISOLatin1 or other
722 { //NOTE: this is a preliminary version. It will only work with
723 // the default fonts, that are Times-Roman and Times-Bold
724 // "export JGRAPH_ENCODING=ISOLatin1Encoding" will work in sh
725 char *s; \
726 s=(char *)getenv("JGRAPH_ENCODING");
727 if ((s!=NULL) && (strlen(s)>0)) {
728 comment("Setting font encoding by pzn@debian.org");
729 printf("/Times-Bold findfont\n");
730 printf("dup length dict begin\n");
731 printf(" {1 index /FID ne {def} {pop pop} ifelse} forall\n");
732 printf(" /Encoding %s def\n",s);
733 printf(" currentdict\n");
734 printf("end\n");
735 printf("/Times-Bold exch definefont pop\n");
736 printf("/Times-Roman findfont\n");
737 printf("dup length dict begin\n");
738 printf(" {1 index /FID ne {def} {pop pop} ifelse} forall\n");
739 printf(" /Encoding %s def\n",s);
740 printf(" currentdict\n");
741 printf("end\n");
742 printf("/Times-Roman exch definefont pop\n");
743 comment("End of font encoding");
744 printf("\n");
745 }
746 }
747 //END added by pzn
748
749 if (landscape) {
750 printf("-90 rotate\n");
751 }
752 if (pp) {
753 if (landscape) {
754 printf("%f 0 translate\n", -(11.0 * FCPI));
755 printf("%f %f translate\n",
756 (((11.0 * FCPI) - (gs->bb[2] - gs->bb[0])) / 2.0) - gs->bb[0],
757 (((8.5 * FCPI) - (gs->bb[3] - gs->bb[1])) / 2.0) - gs->bb[1]);
758 } else {
759 printf("%f %f translate\n",
760 (((8.5 * FCPI) - (gs->bb[2] - gs->bb[0])) / 2.0) - gs->bb[0],
761 (((11.0 * FCPI) - (gs->bb[3] - gs->bb[1])) / 2.0) - gs->bb[1]);
762 }
763 } else if (landscape) {
764 printf("%d 0 translate\n", -gs->bb[2] - gs->bb[0]);
765 }
766 printf("1 setlinecap 1 setlinejoin\n");
767 printf("0.700 setlinewidth\n");
768 printf("0.00 setgray\n");
769
770 printf("\n");
771 printf("/Jrnd { exch cvi exch cvi dup 3 1 roll idiv mul } def\n");
772
773 printf("/JDEdict 8 dict def\n");
774 printf("JDEdict /mtrx matrix put\n");
775 printf("/JDE {\n");
776 printf(" JDEdict begin\n");
777 printf(" /yrad exch def\n");
778 printf(" /xrad exch def\n");
779 printf(" /savematrix mtrx currentmatrix def\n");
780 printf(" xrad yrad scale\n");
781 printf(" 0 0 1 0 360 arc\n");
782 printf(" savematrix setmatrix\n");
783 printf(" end\n");
784 printf("} def\n");
785
786 printf("/JSTR {\n");
787 printf(" gsave 1 eq { gsave 1 setgray fill grestore } if\n");
788 printf(" exch neg exch neg translate \n");
789 printf(" clip \n");
790 printf(" rotate \n");
791 printf(" 4 dict begin\n");
792 printf(" pathbbox /&top exch def\n");
793 printf(" /&right exch def\n");
794 printf(" /&bottom exch def\n");
795 printf(" &right sub /&width exch def\n");
796 printf(" newpath\n");
797 printf(" currentlinewidth mul round dup \n");
798 printf(" &bottom exch Jrnd exch &top \n");
799 printf(" 4 -1 roll currentlinewidth mul setlinewidth \n");
800 printf(" { &right exch moveto &width 0 rlineto stroke } for \n");
801 printf(" end\n");
802 printf(" grestore\n");
803 printf(" newpath\n");
804 printf("} bind def\n");
805
806 gsave();
807 setfont("Times-Roman", 9.00);
808 if (gs->preamble != CNULL) {
809 if (gs->prefile) {
810 f = fopen(gs->preamble, "r");
811 if (f == NULL) {
812 fprintf(stderr, "Error: preamble file %s couldn't be opened\n",
813 gs->preamble);
814 exit(1);
815 }
816 for (c = getc(f); c != real_eof; c = getc(f)) putchar(c);
817 putchar('\n');
818 fclose(f);
819 } else {
820 printf("%s\n", gs->preamble);
821 }
822 }
823}
824
825void draw_footer(Graphs gs, int pp)
826{
827 FILE *f;
828 char c;
829
830 if (gs->epilogue != CNULL) {
831 if (gs->epifile) {
832 f = fopen(gs->epilogue, "r");
833 if (f == NULL) {
834 fprintf(stderr, "Error: epilogue file %s couldn't be opened\n",
835 gs->epilogue);
836 exit(1);
837 }
838 for (c = getc(f); c != real_eof; c = getc(f)) putchar(c);
839 putchar('\n');
840 fclose(f);
841 } else {
842 printf("%s\n", gs->epilogue);
843 }
844 }
845 grestore();
846 if (pp) printf("showpage\n"); else printf("\n");
847
848 if (pp) {
849 printf("%%%%PageTrailer\n");
850 }
851
852}
853
Note: See TracBrowser for help on using the repository browser.