1 /*
2 Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 - Neither the name of The Numerical ALgorithms Group Ltd. nor the
18 names of its contributors may be used to endorse or promote products
19 derived from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35 #define _GFUN_C
36
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "Gdraws0.h"
43 #include "G.h"
44 #include "hash.h"
45
46 #include "hash.H1"
47 #include "Gfun.H1"
48 #include "strutil.h"
49
50 /*
51 * Given 2 file pointers, this function copies file ifp to file ofp
52 */
53
54 static void
filecopy(FILE * ifp,FILE * ofp)55 filecopy(FILE * ifp, FILE * ofp)
56 {
57
58 int c;
59
60 while ((c = getc(ifp)) != EOF)
61 putc(c, ofp);
62 }
63
64
65 /*
66 * PSCreateFile generates the output file by using the order of defined
67 * variables; they are used to create the OUTPUT file. Essentially,
68 * PSCreateFile() loop through the index of 0 to psDrawNo and checks if the
69 * file/procedure is used. If so, the file is included into the output
70 * file.
71 */
72
73 int
PSCreateFile(int bWidth,Window vw,Window tw,char * title)74 PSCreateFile(
75 int bWidth, /* border width of picture frame */
76 Window vw, Window tw, /* viewWindow, and titleWindow */
77 char *title) /* title of picture to be drawn in title bar */
78 {
79 FILE *ifp, *ofp, *fp; /* input, output and temp file pointer */
80 int i; /* index */
81
82 /* last things to add to the script file */
83
84 fp = fopen(psData[scriptps].filename, "a");
85 fprintf(fp, "\n grestore\t%% restore graphics state\n\n");
86 fclose(fp);
87
88 #if 0
89 /* Make frame drawing optional. */
90
91 Gdraws_drawFrame(bWidth, vw, tw, title);
92 #endif
93
94 /* put procedures and script together into OUTPUT.ps */
95
96 if ((ofp = fopen(psData[output].filename, "w")) == NULL) {
97 fprintf(stderr, "Cannot open %s to write.\n", psData[output].filename);
98 return (psError);
99 }
100 else {
101 i = 1;
102 while (i < psDrawNo) { /* loops through each file/procedure */
103 if (psData[i].flag) { /* if set, procedure/file is used */
104 if ((ifp = fopen(psData[i].filename, "r")) == NULL) {
105 if (i == GCdictps) { /* GC dictionaries */
106 fprintf(stderr, "Warning: missing GCdictionary.\n");
107 }
108 else {
109 fprintf(stderr, "Cannot open %s to read.\n",
110 psData[i].filename);
111 fclose(ofp);
112 return (psError);
113 }
114 }
115 else {
116 filecopy(ifp, ofp);
117 fclose(ifp);
118 }
119 }
120 i++;
121 }
122 }
123
124 /* remove script file in tmp */
125
126 unlink(psData[scriptps].filename);
127
128 #if 0
129 /* remove GCdict file in tmp */
130 unlink(psData[GCdictps].filename);
131 #endif
132
133 return (fclose(ofp));
134 }
135
136
137
138 /*
139 * This function draws the frame of the picture, which corresponds to the
140 * picture frame on the X display. In addition, it draws the title window as
141 * well as the title of the picture.
142 */
143
144 int
Gdraws_drawFrame(int borderW,Window viewWindow,Window titleWindow,char * title)145 Gdraws_drawFrame(
146 int borderW, /* border width */
147 Window viewWindow, Window titleWindow,
148 char *title) /* title of picture */
149 {
150 FILE *fp;
151 XWindowAttributes vwInfo, twInfo;
152
153 /* choose 2 and "frameDict" for frame dictionary: can be anything else */
154
155 PSCreateContext((GC)2, "frameDict", borderW, psButtCap, psMiterJoin,
156 psWhite, psBlack);
157
158 fp = fopen(psData[scriptps].filename, "a");
159
160 XGetWindowAttributes(dsply, viewWindow, &vwInfo);
161
162 /* draw title window */
163
164 XGetWindowAttributes(dsply, titleWindow, &twInfo);
165 fprintf(fp, "\t%s\t%d\t%d\t%d\t%d\ttitle\n", "frameDict",
166 twInfo.height - vwInfo.height, twInfo.width, 0, vwInfo.height);
167
168 /* draw viewport window */
169
170 fprintf(fp, "\t%s\tdrawFrame\n", "frameDict"); /* using Gdraws_setDimension() */
171
172 /* draw title text */
173
174 psData[drawIstrps].flag = yes;
175 fprintf(fp, "\t%s\tloadFont\n\t%d\t(%s) stringwidth pop sub 2 div\n",
176 "frameDict", twInfo.width, title);
177 fprintf(fp, "\t%d\t(%s)\t(%s)\tpsDrawIStr\n", 15, title, "title");
178
179 return (fclose(fp));
180 }
181
182
183 /* setDimension sets the dimension of the picture */
184
185 int
Gdraws_setDimension(Window viewWindow,Window titleWindow)186 Gdraws_setDimension(
187 Window viewWindow,
188 Window titleWindow)
189 {
190 FILE *fp;
191 XWindowAttributes vwInfo, twInfo;
192 float pageWidth, pageHeight, width;
193
194 fp = fopen(psData[scriptps].filename, "w");
195
196 XGetWindowAttributes(dsply, titleWindow, &twInfo);
197 XGetWindowAttributes(dsply, viewWindow, &vwInfo);
198 pageWidth = 575.0;
199 pageHeight = 750.0;
200
201 #if 0
202 pageWidth = (float) (DisplayWidth(dsply, scrn) / DisplayWidthMM(dsply, scrn));
203 pageWidth *= 160.0;
204 pageHeight = (float) (DisplayHeight(dsply, scrn) / DisplayHeightMM(dsply, scrn));
205 pageHeight *= 210.0;
206 fprintf(stderr, "%f, %f\n", pageWidth, pageHeight);
207 #endif
208
209 fprintf(fp, "\n gsave\t%% save graphics state for clipping path\n\n");
210 if ((vwInfo.height > pageWidth) || (vwInfo.height > pageHeight)) {
211 width = (float) vwInfo.width;
212 if (vwInfo.height > pageWidth) {
213 width = pageWidth / width;
214 fprintf(fp, "\t%f\t%f", width, width);
215 }
216 else {
217 if (vwInfo.height > pageHeight)
218 fprintf(fp, "\t%f\t%f", width, pageHeight / width);
219 }
220 }
221 else {
222 fprintf(fp, "\t%f\t%f", 1.0, 1.0);
223 }
224 fprintf(fp, "\tscale\n\n");
225
226 fprintf(fp, "\t%d\t%d\t%d\tsetDim\n", twInfo.height - vwInfo.height,
227 vwInfo.height, vwInfo.width);
228
229 /* Write a Bounding Box for psfig etc. */
230
231 fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n", vwInfo.height, vwInfo.width);
232
233 fprintf(fp, "\tmaxX maxY\t0 0\trectangle\tclip\t%% set clip path\n\n");
234 return (fclose(fp));
235 }
236 /*
237 * GDrawImageString draws an image text string
238 */
239
240 int
GDrawImageString(GC gc,Window wid,int x,int y,char * string,int length,int dFlag)241 GDrawImageString(
242 GC gc, /* graphics context */
243 Window wid, /* window id */
244 int x, int y,
245 char *string,
246 int length, int dFlag)
247 {
248 int s;
249
250 switch (dFlag) {
251 case Xoption:
252 s = XDrawImageString(dsply, wid, gc, x, y, string, length);
253 break;
254 case PSoption:
255 {
256 FILE *fp;
257
258 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
259 fprintf(stderr, "GDrawImageString cannot open %s\n",
260 psData[scriptps].filename);
261 return (psError);
262 }
263
264 psData[drawIstrps].flag = yes; /* set procedure flag */
265 fprintf(fp, "\t%s\t%d\t%d\t(%s)\t(%s)\tpsDrawIStr\n",
266 PSfindGC(gc), x, y, string, "window");
267 s = fclose(fp);
268 }
269 break;
270 default:
271 fprintf(stderr, "GdrawImagestring request (%d) not implemented yet.\n", dFlag);
272 return (psError);
273 }
274 return (s);
275 }
276
277 /* Draws an arc; see XDrawArc */
278
279 int
GDrawArc(GC gc,Window wid,int x,int y,unsigned int wdth,unsigned int hght,int ang1,int ang2,int dFlag)280 GDrawArc(
281 GC gc, /* graphics context */
282 Window wid, /* window id */
283 int x, int y,
284 unsigned int wdth, unsigned int hght,
285 int ang1, int ang2, int dFlag)
286 {
287 int s = 0;
288
289 switch (dFlag) {
290 case Xoption:
291 XDrawArc(dsply, wid, gc, x, y, wdth, hght, ang1, ang2);
292 break;
293 case PSoption:
294 {
295 FILE *fp;
296
297 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
298 fprintf(stderr, "GDrawArc cannot open %s\n",
299 psData[scriptps].filename);
300 return (psError);
301 }
302
303 psData[drawarcps].flag = yes;
304 fprintf(fp, "\t%s\t%d\t%d\t%d\t%d\t%d\t%d\tpsDrawArc\n",
305 PSfindGC(gc), x, y, hght, wdth, ang1 / 64, ang2 / 64);
306 s = fclose(fp);
307 }
308 break;
309 default:
310 fprintf(stderr, "Gdrawarc request (%d) not implemented yet.\n",
311 dFlag);
312 return (psError);
313 }
314 return (s);
315 }
316 /*
317 * GDrawLine draws a line, see XDrawLine
318 */
319
320 int
GDrawLine(GC gc,Window wid,int x0,int y0,int x1,int y1,int dFlag)321 GDrawLine(
322 GC gc, /* graphics context */
323 Window wid, /* window id */
324 int x0, int y0, int x1, int y1, int dFlag)
325 {
326 int s = 0;
327
328 switch (dFlag) {
329 case Xoption:
330 XDrawLine(dsply, wid, gc, x0, y0, x1, y1);
331 break;
332 case PSoption:
333 {
334 FILE *fp;
335
336 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
337 fprintf(stderr, "GDrawLine cannot open %s\n",
338 psData[scriptps].filename);
339 return (psError);
340 }
341
342 psData[drawlineps].flag = yes; /* sets procedure flag */
343 fprintf(fp, "\t%s\t%d\t%d\t%d\t%d\tpsDrawLine\n",
344 PSfindGC(gc), x1, y1, x0, y0);
345 s = fclose(fp);
346 }
347 break;
348 default:
349 fprintf(stderr, "Gdrawline request (%d) not implemented yet.\n",
350 dFlag);
351 return (psError);
352 }
353 return (s);
354 }
355
356
357
358
359
360 /*
361 * GDrawLines draws lines; see XDrawLines
362 */
363
364 int
GDrawLines(GC gc,Window wid,XPoint * points,int numberOfPoints,int mode,int dFlag)365 GDrawLines(
366 GC gc, /* graphics context */
367 Window wid, /* window id */
368 XPoint * points, /* points */
369 int numberOfPoints, int mode, int dFlag)
370 /* number of points, mode and display flag */
371 {
372 int s = 0;
373
374 switch (dFlag) {
375 case Xoption:
376 XDrawLines(dsply, wid, gc, points, numberOfPoints, mode);
377 break;
378 case PSoption:
379 {
380 FILE *fp; /* not dealing with modes yet */
381 int i = 0;
382
383 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
384 fprintf(stderr, "GDrawLines cannot open %s\n",
385 psData[scriptps].filename);
386 return (psError);
387 }
388
389 psData[drawlinesps].flag = yes; /* set procedure flag */
390 fprintf(fp, "\t%s\n", PSfindGC(gc));
391 i = numberOfPoints - 1;
392 while (i > 0)
393 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
394 i = i-1;
395 }
396
397 fprintf(fp, "\t%d\t%d\t%d\tpsDrawLines\n",
398 numberOfPoints, points[i].x, points[i].y);
399 s = fclose(fp);
400 }
401 break;
402 default:
403 fprintf(stderr, "Gdrawlines request (%d) not implemented yet\n",
404 dFlag);
405 return (psError);
406 }
407 return (s);
408 }
409
410 /*
411 * GDrawPoint draws a point, see XDrawPoint
412 */
413
414 int
GDrawPoint(Window wid,GC gc,int x0,int y0,int dFlag)415 GDrawPoint(
416 Window wid, /* window id */
417 GC gc, /* graphics context */
418 int x0, int y0, int dFlag)
419 {
420 int s = 0;
421
422 switch (dFlag) {
423 case Xoption:
424 XDrawPoint(dsply, wid, gc, x0, y0);
425 break;
426 case PSoption:
427 {
428 FILE *fp;
429
430 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
431 fprintf(stderr, "GDrawPoint cannot open %s\n",
432 psData[scriptps].filename);
433 return (psError);
434 }
435
436 psData[drawpointps].flag = yes; /* sets procedure flag */
437 fprintf(fp, "\t%s\t%d\t%d\t%d\t%d\tpsDrawPoint\n",
438 PSfindGC(gc), x0, y0, x0 + 1, y0 + 1);
439 s = fclose(fp);
440 }
441 break;
442 default:
443 fprintf(stderr, "Gdrawpoint request (%d) not implemented yet\n",
444 dFlag);
445 return (psError);
446 }
447 return (s);
448 }
449
450 /*
451 * GDrawRectangle draws a rectangle; see XDrawRectangle
452 */
453
454 int
GDrawRectangle(GC gc,Window windowId,short int x,short int y,short int width,short int height,int dFlag)455 GDrawRectangle(
456 GC gc,
457 Window windowId,
458 short int x,short int y,short int width,short int height,
459 int dFlag)
460 {
461 int s = 0;
462
463 switch (dFlag) {
464 case Xoption:
465 XDrawRectangle(dsply, windowId, gc, x, y, width, height);
466 break;
467 case PSoption:
468 {
469 FILE *fp;
470
471 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
472 fprintf(stderr, "GDrawRect cannot open %s\n",
473 psData[scriptps].filename);
474 return (psError);
475 }
476
477 psData[drawrectps].flag = yes;
478 fprintf(fp, "\t%s\t%d\t%d\t%d\t%d\tpsDrawRect\n",
479 PSfindGC(gc), width, height, x, y);
480 s = fclose(fp);
481 }
482 break;
483 default:
484 fprintf(stderr, "Gdrawrect request (%d) not implemented yet\n",
485 dFlag);
486 return (psError);
487 }
488 return (s);
489 }
490
491 /*
492 * GDraw3DButtonOut draws a rectangle with 3D shading on rhs and bottom
493 */
494
495 int
GDraw3DButtonOut(GC gc,Window windowId,short int x,short int y,short int width,short int height,int dFlag)496 GDraw3DButtonOut(
497 GC gc,
498 Window windowId,
499 short int x,short int y,short int width,short int height,
500 int dFlag)
501 {
502 /* draw regular rectangle */
503
504 int s = GDrawRectangle(gc, windowId, x, y, width - 1, height - 1, dFlag);
505
506 /* add extra line down rhs */
507
508 GDrawLine(gc, windowId,
509 x + width, y + 1, x + width, y + height,
510 dFlag);
511
512 /* add extra line across bottom */
513
514 GDrawLine(gc, windowId,
515 x + 1, y + height, x + width, y + height,
516 dFlag);
517
518 return (s);
519 }
520
521 /*
522 * GDraw3DButtonIn draws a rectangle with 3D shading on lhs and top
523 */
524
525 int
GDraw3DButtonIn(GC gc,Window windowId,short int x,short int y,short int width,short int height,int dFlag)526 GDraw3DButtonIn(
527 GC gc,
528 Window windowId,
529 short int x,short int y,short int width,short int height,
530 int dFlag)
531 {
532 /* draw regular rectangle */
533
534 int s = GDrawRectangle(gc, windowId, x + 1, y + 1, width - 1, height - 1, dFlag);
535
536 /* add extra line down lhs */
537
538 GDrawLine(gc, windowId,
539 x, y, x, y + height - 1,
540 dFlag);
541
542 /* add extra line across top */
543
544 GDrawLine(gc, windowId,
545 x, y, x + width - 1, y,
546 dFlag);
547
548 return (s);
549 }
550
551 /*
552 * GDrawPushButton draws a push button whose appearance depends on "isOn."
553 */
554
555 int
GDrawPushButton(Display * display,GC gc1,GC gc2,GC gc3,Window windowId,short int x,short int y,short int width,short int height,int isOn,char * text,unsigned long buttonColor,unsigned long color,int dFlag)556 GDrawPushButton(
557 Display * display,
558 GC gc1, GC gc2, GC gc3,
559 Window windowId,
560 short int x,short int y,short int width,short int height,
561 int isOn, char *text,
562 unsigned long buttonColor, unsigned long color,
563 int dFlag)
564 {
565 int len = strlen(text);
566
567 if (dFlag == Xoption)
568 XClearArea(display, windowId, x, y, width + 1, height + 1, False);
569
570 GSetForeground(gc1, (float) buttonColor, dFlag);
571
572 if (isOn)
573 GDraw3DButtonIn(gc1, windowId, x, y, width, height, dFlag);
574 else
575 GDraw3DButtonOut(gc1, windowId, x, y, width, height, dFlag);
576
577 GSetForeground(gc2, (float) color, dFlag);
578
579 return GDrawString(gc2, windowId,
580 x + (isOn ? 2 : 0) + centerX(gc3, text, len, width),
581 y + (isOn ? 2 : 0) + centerY(gc3, height),
582 text, len, dFlag);
583 }
584
585
586
587 /*
588 * Draws a string; see XDrawString
589 */
590
591 int
GDrawString(GC gc,Window wid,int x,int y,char * string,int length,int dFlag)592 GDrawString(
593 GC gc, /* graphics context */
594 Window wid, /* window id */
595 int x, int y,
596 char *string, /* string to be drawn */
597 int length, int dFlag)
598 {
599 int s;
600
601 switch (dFlag) {
602 case Xoption:
603 s = XDrawString(dsply, wid, gc, x, y, string, length);
604 break;
605 case PSoption:
606 {
607 FILE *fp;
608
609 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
610 fprintf(stderr, "GDrawString cannot open %s\n",
611 psData[scriptps].filename);
612 return (psError);
613 }
614
615 psData[drawstrps].flag = yes; /* sets procedure flag */
616 fprintf(fp, "\t%s\t(%s)\t%d\t%d\tpsDrawStr\n",
617 PSfindGC(gc), string, x, y);
618
619 s = fclose(fp);
620 }
621 break;
622 default:
623 fprintf(stderr, "Gdrawstring request (%d) not implemented yet\n",
624 dFlag);
625 return (psError);
626 }
627 return (s);
628 }
629
630 /*
631 * Draws and fills an arc with foreground color; see XFillArc
632 */
633
634 int
GFillArc(GC gc,Window wid,int x,int y,unsigned int wdth,unsigned int hght,int ang1,int ang2,int dFlag)635 GFillArc(
636 GC gc, /* graphics context */
637 Window wid, /* window id */
638 int x, int y,
639 unsigned int wdth, unsigned int hght,
640 int ang1, int ang2, int dFlag)
641 {
642 int s = 0;
643
644 switch (dFlag) {
645 case Xoption: /* angle: times 64 already */
646 XFillArc(dsply, wid, gc, x, y, wdth, hght, ang1, ang2);
647 break;
648 case PSoption:
649 {
650 FILE *fp;
651
652 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
653 fprintf(stderr, "GFillArc cannot open %s\n",
654 psData[scriptps].filename);
655 return (psError);
656 }
657
658 psData[fillarcps].flag = yes; /* sets procedure flag */
659 fprintf(fp, "\t%s\t%d %d\t%d %d\t%d %d\t%d %d\tpsFillArc\n",
660 PSfindGC(gc), x, y, hght, wdth, ang1 / 64, ang2 / 64,
661 x + wdth / 2, y + hght / 2);
662 s = fclose(fp);
663 }
664 break;
665 default:
666 fprintf(stderr, "GFillArc request (%d) not implemented yet\n",
667 dFlag);
668 return (psError);
669 }
670 return (s);
671 }
672
673 /*
674 * Initializes the path and files to be used.
675 */
676
677 int
PSGlobalInit(void)678 PSGlobalInit(void)
679 { /* This needs to be called only once each
680 * session. */
681 char *tmp;
682
683 /* path-independent global file name */
684 psData[GCdictps].flag = yes;
685 tmp = tempnam(NULL, "axPS");
686 fricas_sprintf_to_buf1(psData[GCdictps].filename, "%s", tmp);
687 free(tmp);
688 psData[setupps].flag = yes;
689 psData[scriptps].flag = yes;/* new script file name */
690 psData[endps].flag = yes;
691
692 /* path specific file names */
693
694 if ((env_fricas = getenv("DEVE")) != NULL) { /* get env var FRICAS */
695
696 psData[headerps].flag = yes;
697 fricas_sprintf_to_buf2(psData[headerps].filename, "%s%s", env_fricas, "/Gdraws/PS/header.ps");
698 fricas_sprintf_to_buf2(psData[drawps].filename, "%s%s", env_fricas, "/Gdraws/PS/draw.ps");
699 fricas_sprintf_to_buf2(psData[drawarcps].filename, "%s%s", env_fricas,
700 "/Gdraws/PS/drawarc.ps");
701 fricas_sprintf_to_buf2(psData[drawfilledps].filename, "%s%s", env_fricas,
702 "/Gdraws/PS/drwfilled.ps");
703 fricas_sprintf_to_buf2(psData[drawcolorps].filename, "%s%s", env_fricas,
704 "/Gdraws/PS/drawcolor.ps");
705 fricas_sprintf_to_buf2(psData[fillpolyps].filename, "%s%s", env_fricas,
706 "/Gdraws/PS/fillpoly.ps");
707 fricas_sprintf_to_buf2(psData[colorpolyps].filename, "%s%s", env_fricas,
708 "/Gdraws/PS/colorpoly.ps");
709 fricas_sprintf_to_buf2(psData[fillwolps].filename, "%s%s", env_fricas,
710 "/Gdraws/PS/fillwol.ps");
711 fricas_sprintf_to_buf2(psData[colorwolps].filename, "%s%s", env_fricas,
712 "/Gdraws/PS/colorwol.ps");
713 fricas_sprintf_to_buf2(psData[drawpointps].filename, "%s%s", env_fricas,
714 "/Gdraws/PS/drawpoint.ps");
715 fricas_sprintf_to_buf2(psData[drawlineps].filename, "%s%s", env_fricas,
716 "/Gdraws/PS/drawline.ps");
717 fricas_sprintf_to_buf2(psData[drawlinesps].filename, "%s%s", env_fricas,
718 "/Gdraws/PS/drawlines.ps");
719 fricas_sprintf_to_buf2(psData[drawrectps].filename, "%s%s", env_fricas,
720 "/Gdraws/PS/drawrect.ps");
721 fricas_sprintf_to_buf2(psData[drawstrps].filename, "%s%s", env_fricas,
722 "/Gdraws/PS/drawstr.ps");
723 fricas_sprintf_to_buf2(psData[drawIstrps].filename, "%s%s", env_fricas,
724 "/Gdraws/PS/drawIstr.ps");
725 fricas_sprintf_to_buf2(psData[fillarcps].filename, "%s%s", env_fricas,
726 "/Gdraws/PS/fillarc.ps");
727 fricas_sprintf_to_buf2(psData[setupps].filename, "%s%s", env_fricas, "/Gdraws/PS/setup.ps");
728 fricas_sprintf_to_buf2(psData[endps].filename, "%s%s", env_fricas, "/Gdraws/PS/end.ps");
729 }
730 else if ((env_fricas = getenv("FRICAS")) != NULL) {
731 psData[headerps].flag = yes;
732 fricas_sprintf_to_buf2(psData[headerps].filename, "%s%s", env_fricas,
733 "/lib/graph/header.ps");
734 fricas_sprintf_to_buf2(psData[drawps].filename, "%s%s", env_fricas,
735 "/lib/graph/draw.ps");
736 fricas_sprintf_to_buf2(psData[drawarcps].filename, "%s%s", env_fricas,
737 "/lib/graph/drawarc.ps");
738 fricas_sprintf_to_buf2(psData[drawfilledps].filename, "%s%s", env_fricas,
739 "/lib/graph/drwfilled.ps");
740 fricas_sprintf_to_buf2(psData[drawcolorps].filename, "%s%s", env_fricas,
741 "/lib/graph/drawcolor.ps");
742 fricas_sprintf_to_buf2(psData[fillpolyps].filename, "%s%s", env_fricas,
743 "/lib/graph/fillpoly.ps");
744 fricas_sprintf_to_buf2(psData[colorpolyps].filename, "%s%s", env_fricas,
745 "/lib/graph/colorpoly.ps");
746 fricas_sprintf_to_buf2(psData[fillwolps].filename, "%s%s", env_fricas,
747 "/lib/graph/fillwol.ps");
748 fricas_sprintf_to_buf2(psData[colorwolps].filename, "%s%s", env_fricas,
749 "/lib/graph/colorwol.ps");
750 fricas_sprintf_to_buf2(psData[drawpointps].filename, "%s%s", env_fricas,
751 "/lib/graph/drawpoint.ps");
752 fricas_sprintf_to_buf2(psData[drawlineps].filename, "%s%s", env_fricas,
753 "/lib/graph/drawline.ps");
754 fricas_sprintf_to_buf2(psData[drawlinesps].filename, "%s%s", env_fricas,
755 "/lib/graph/drawlines.ps");
756 fricas_sprintf_to_buf2(psData[drawrectps].filename, "%s%s", env_fricas,
757 "/lib/graph/drawrect.ps");
758 fricas_sprintf_to_buf2(psData[drawstrps].filename, "%s%s", env_fricas,
759 "/lib/graph/drawstr.ps");
760 fricas_sprintf_to_buf2(psData[drawIstrps].filename, "%s%s", env_fricas,
761 "/lib/graph/drawIstr.ps");
762 fricas_sprintf_to_buf2(psData[fillarcps].filename, "%s%s", env_fricas,
763 "/lib/graph/fillarc.ps");
764 fricas_sprintf_to_buf2(psData[setupps].filename, "%s%s", env_fricas,
765 "/lib/graph/setup.ps");
766 fricas_sprintf_to_buf2(psData[endps].filename, "%s%s", env_fricas,
767 "/lib/graph/end.ps");
768 }
769 else {
770 fprintf(stderr, " need environment variable FRICAS or DEVE; process aborted\n");
771 return (psError);
772 }
773
774 return (psInit = yes);
775 }
776
777
778 /*
779 * This needs to be called for every postscript file generated. It
780 * initializes the procedure flags.
781 */
782
783 int
PSInit(Window vw,Window tw)784 PSInit(Window vw, Window tw)
785 {
786 if (!psInit) {
787 /* must have PSGlobalInit() called before this */
788 fprintf(stderr, "Error: need initialization for ps data files: call PSGlobalInit().\n");
789 return (psError);
790 }
791
792 fricas_sprintf_to_buf1(psData[output].filename, "%s", PSfilename); /* output file name */
793
794 psData[drawps].flag = no; /* ps procedures flags */
795 psData[drawarcps].flag = no;
796 psData[drawfilledps].flag = no;
797 psData[drawcolorps].flag = no;
798 psData[fillpolyps].flag = no;
799 psData[fillwolps].flag = no;
800 psData[colorpolyps].flag = no;
801 psData[colorwolps].flag = no;
802 psData[drawpointps].flag = no;
803 psData[drawlineps].flag = no;
804 psData[drawlinesps].flag = no;
805 psData[drawrectps].flag = no;
806 psData[drawstrps].flag = no;
807 psData[drawIstrps].flag = no;
808 psData[fillarcps].flag = no;
809
810 fricas_sprintf_to_buf1(psData[scriptps].filename, "%s", tmpnam(NULL)); /* script file */
811 return (Gdraws_setDimension(vw, tw));
812 }
813
814 /*
815 * This procedure sets the line attributes; notice that lineWidth is not set
816 * for PS, this is because lineWidth of 0, the thinest line on the ps device,
817 * is device-dependent, thus, we'll leave it and use default. Also lineStyle
818 * is solid in ps by default, thus we don't need to set it. We'll leave out
819 * line style here since we really never used anything other than line solid
820 * which is the default line style in postscript.
821 */
822
823 int
PSCreateContext(GC gc,char * C_gc,int lineWidth,int capStyle,int joinStyle,float bg,float fg)824 PSCreateContext(
825 GC gc, /* graphics context */
826 char *C_gc, /* GC name to be used as postscript variable */
827 int lineWidth, int capStyle, int joinStyle,
828 float bg, float fg)
829 {
830 FILE *fp;
831 GCptr newGC, curGC;
832
833 /* get memory for new GC cell */
834
835 if (!(newGC = (GCptr) malloc(sizeof(GCstruct)))) {
836 fprintf(stderr, "Ran out of memory(malloc) trying to create a ps GC.\n");
837 exit(-1);
838 }
839
840 /* attach newGC to chain */
841
842 if (GChead == NULL)
843 GChead = newGC;
844 else { /* attach newGC to end of linked list */
845 curGC = GChead;
846 while (curGC->next != NULL)
847 curGC = curGC->next;
848 curGC->next = newGC;
849 }
850
851 /* fill newGC with information */
852
853 newGC->GCint = gc;
854 fricas_sprintf_to_buf1(newGC->GCchar, "%s", C_gc);
855 newGC->next = NULL;
856
857 if ((fp = fopen(psData[GCdictps].filename, "a")) == NULL) {
858 fprintf(stderr, "PSCreateContext cannot open %s\n",
859 psData[GCdictps].filename);
860 return (psError);
861 }
862
863 fprintf(fp, "\t%d\t%d\t%d\n\t%f\t%f\t/%s\tmakeDict\n", joinStyle,
864 capStyle, lineWidth, bg, fg, C_gc);
865
866 return (fclose(fp));
867 }
868
869 /*
870 * Looks into GC linked list with gc (unsigned long) as index to find the
871 * character name.
872 */
873
874 char *
PSfindGC(GC gc)875 PSfindGC(GC gc)
876 {
877 GCptr curGC;
878
879 curGC = GChead;
880 while ((curGC != NULL) && (curGC->GCint != gc))
881 curGC = curGC->next;
882
883 if (curGC == NULL) {
884 fprintf(stderr, "PSfindGC cannot find gc: %p.\n",gc);
885 return (NULL);
886 }
887 else
888 return (curGC->GCchar);
889 }
890
891 /*
892 * Sets foreground color; see XSetForeground
893 */
894
895 int
GSetForeground(GC gc,float color,int dFlag)896 GSetForeground(
897 GC gc, /* graphics context */
898 float color, /* foreground color to be set */
899 int dFlag) /* display flag: PS, X,... */
900 {
901 int s = 0;
902
903 switch (dFlag) {
904 case Xoption:
905 XSetForeground(dsply, gc, (unsigned long) color);
906 break;
907 case PSoption:
908 {
909 FILE *fp;
910
911 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
912 fprintf(stderr, "GSetForeground cannot open %s\n",
913 psData[scriptps].filename);
914 return (0);
915 }
916 fprintf(fp, "\t%s\t%f\tsetForeground\n", PSfindGC(gc), color);
917 s = fclose(fp);
918 break;
919 }
920 default:
921 fprintf(stderr, "GSetForeground request (%d) not implemented yet\n", dFlag);
922 return (0);
923 }
924 return (s);
925 }
926
927 /*
928 * Sets background color; see XSetBackground
929 */
930
931 int
GSetBackground(GC gc,float color,int dFlag)932 GSetBackground(
933 GC gc, /* graphics context */
934 float color, /* background color to be set */
935 int dFlag) /* display flag: PS, X,... */
936 {
937 int s = 0;
938
939 switch (dFlag) {
940 case Xoption:
941 XSetBackground(dsply, gc, (unsigned long) color);
942 break;
943 case PSoption:
944 {
945 FILE *fp;
946
947 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
948 fprintf(stderr, "GSetBackground cannot open %s\n",
949 psData[scriptps].filename);
950 return (0);
951 }
952 fprintf(fp, "\t%s\t%f\tsetBackground\n", PSfindGC(gc), color);
953 s = fclose(fp);
954 break;
955 }
956 default:
957 fprintf(stderr, "GSetBackground request (%d) not implemented yet\n", dFlag);
958 return (0);
959 }
960 return (s);
961 }
962
963 /*
964 * See XSetLineAttributes. Notice that we'll not setting line style for
965 * postscript. This is because solid is the ls in ps and in view3D and 2D,
966 * we really don't use anything else than solid.
967 */
968
969 int
GSetLineAttributes(GC gc,int lineWidth,int lineStyle,int capStyle,int joinStyle,int dFlag)970 GSetLineAttributes(
971 GC gc,
972 int lineWidth, int lineStyle, int capStyle, int joinStyle,
973 int dFlag)
974 {
975 int s = 0;
976
977 switch (dFlag) {
978 case Xoption:
979 XSetLineAttributes(dsply, gc, lineWidth, lineStyle,
980 capStyle, joinStyle);
981 break;
982 case PSoption:
983 {
984 FILE *fp;
985 int psCap, psJoin;
986
987 switch (capStyle) {
988 case 0: /* CapNotLast is not implemented in ps */
989 case 1:
990 psCap = psButtCap;
991 break;
992 case 2:
993 psCap = psRoundCap;
994 break;
995 case 3:
996 psCap = psPSqCap;
997 break;
998 default:
999 fprintf(stderr, "cap style: %d unknown, using default.\n", capStyle);
1000 psCap = psButtCap;
1001 }
1002
1003 switch (joinStyle) {
1004 case 0:
1005 psJoin = psMiterJoin;
1006 break;
1007 case 1:
1008 psJoin = psRoundJoin;
1009 break;
1010 case 2:
1011 psJoin = psBevelJoin;
1012 break;
1013 default:
1014 fprintf(stderr, "join style: %d unknown, using default.\n", joinStyle);
1015 psJoin = psMiterJoin;
1016 }
1017
1018 /*
1019 * width of zero is machine-dependent and is not recom- mended,
1020 * we'll use 1 as the thinest line available if (lineWidth < 1)
1021 * lineWidth = 1;
1022 */
1023
1024 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1025 fprintf(stderr, "GSetLineAttributes cannot open %s\n",
1026 psData[scriptps].filename);
1027 return (0);
1028 }
1029
1030 fprintf(fp, "\t%d\t%d\t%d\t%s\tsetLineAttributes\n",
1031 lineWidth, psCap, psJoin, PSfindGC(gc));
1032 s = fclose(fp);
1033 }
1034 break;
1035 default:
1036 fprintf(stderr, "GSetLineAttributes request (%d) not implemented yet\n", dFlag);
1037 return (0);
1038 }
1039 return (s);
1040 }
1041
1042 /*
1043 * This procedure frees the data structure used for GC information, and also
1044 * unlinks the GC dictionary file.
1045 */
1046
1047 int
PSClose(void)1048 PSClose(void)
1049 {
1050 if (GChead != NULL) {
1051
1052 /* free memory used by GC struct */
1053
1054 GCptr curGC = GChead;
1055
1056 while (curGC != NULL) {
1057 GCptr freeGC = curGC;
1058
1059 curGC = curGC->next;
1060 free(freeGC);
1061 }
1062 }
1063
1064 /* remove GC dictionary file */
1065
1066 return (unlink(psData[GCdictps].filename));
1067 }
1068
1069
1070
1071
1072 int
centerX(GC viewGCx,char * theString,int strlength,int windowWidth)1073 centerX (GC viewGCx,char * theString,int strlength,int windowWidth)
1074 {
1075 XFontStruct *fontStruct;
1076 GContext con;
1077 int result;
1078
1079
1080 con=XGContextFromGC(viewGCx);
1081 fontStruct = XQueryFont(dsply,con);
1082 if(fontStruct == NULL) return(0);
1083 result = (windowWidth - XTextWidth(fontStruct,theString,strlength))/2 -
1084 fontStruct->min_bounds.lbearing;
1085 XFreeFontInfo(NULL,fontStruct,1);
1086 return(result);
1087 }
1088
1089
1090 int
centerY(GC viewGCy,int windowHeight)1091 centerY (GC viewGCy,int windowHeight)
1092 {
1093
1094 XFontStruct *fontStruct;
1095 GContext con;
1096 int result;
1097
1098 con=XGContextFromGC(viewGCy);
1099 fontStruct = XQueryFont(dsply,con);
1100 if (fontStruct == NULL) return(0);
1101 result = (windowHeight -
1102 (fontStruct->max_bounds.ascent + fontStruct->max_bounds.descent))/2 +
1103 fontStruct->max_bounds.ascent;
1104 XFreeFontInfo(NULL,fontStruct,1);
1105 return(result);
1106
1107 }
1108
1109
1110 /*
1111 * PSColorPolygon draws and fills a polygon given data in XPoint; see
1112 * XFillPolygon
1113 */
1114
1115 int
PSColorPolygon(float r,float g,float b,XPoint * points,int numberOfPoints)1116 PSColorPolygon(
1117 float r, float g, float b, /* red, green and blue color
1118 * components */
1119 XPoint * points, /* vertices of polygon */
1120 int numberOfPoints) /* number of points */
1121 {
1122 int i = 0;
1123 FILE *fp;
1124
1125 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1126 fprintf(stderr, "PSColorPolygon cannot open %s\n",
1127 psData[scriptps].filename);
1128 return (psError);
1129 }
1130
1131 psData[colorpolyps].flag = yes; /* sets procedure flag */
1132
1133 fprintf(fp, "\t%f\t%f\t%f\tsetrgbcolor\n", r, g, b);
1134
1135 i = numberOfPoints - 1;
1136 while (i > 0)
1137 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
1138 i = i-1;
1139 }
1140
1141 fprintf(fp, "\t%d\t%d\t%d\tpsColorPoly\n", numberOfPoints, points[i].x, points[i].y);
1142
1143 return (fclose(fp));
1144 }
1145
1146
1147 /*
1148 * PSColorwOutline draws and also outlines the colored polygon.
1149 */
1150
1151 int
PSColorwOutline(float r,float g,float b,XPoint * points,int numberOfPoints)1152 PSColorwOutline(
1153 float r, float g, float b, /* red, green and blue color
1154 * components */
1155 XPoint * points, /* vertices of polygon */
1156 int numberOfPoints) /* number of points */
1157 {
1158 int i = 0;
1159 FILE *fp;
1160
1161 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1162 fprintf(stderr, "PSDrawFOL cannot open %s\n", psData[scriptps].filename);
1163 return (psError);
1164 }
1165
1166 psData[colorwolps].flag = yes; /* sets procedure flag */
1167
1168 fprintf(fp, "\t%f\t%f\t%f\tsetrgbcolor\n", r, g, b);
1169
1170 i = numberOfPoints - 1;
1171 while (i > 0)
1172 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
1173 i = i-1;
1174 }
1175
1176 fprintf(fp, "\t%d\t%d\t%d\tpsFillwOutline\n",
1177 numberOfPoints, points[i].x, points[i].y);
1178
1179 return (fclose(fp));
1180 }
1181 /*
1182 * This function does what XDraw would do, notice that only a subset of
1183 * attributes in GC is implemented -- adequate for our purpose now
1184 */
1185
1186 int
PSDrawColor(float r,float g,float b,XPoint * points,int numberOfPoints)1187 PSDrawColor(
1188 float r, float g, float b, /* red, green and blue color
1189 * components */
1190 XPoint *points, /* point list */
1191 int numberOfPoints) /* vertex count and display flag (X, PS,...) */
1192 {
1193 int i = 0;
1194 FILE *fp;
1195
1196 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1197 fprintf(stderr, "GDraw cannot open %s\n",
1198 psData[scriptps].filename);
1199 return (psError);
1200 }
1201
1202 psData[drawcolorps].flag = yes; /* set procedure flag */
1203
1204 fprintf(fp, "\t%f\t%f\t%f\tsetrgbcolor\n", r, g, b);
1205
1206 i = numberOfPoints - 1;
1207 while (i > 0)
1208 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
1209 i=i-1;
1210 }
1211
1212 fprintf(fp, "\t%d\t%d\t%d\tpsDrawColor\n", numberOfPoints, points[i].x, points[i].y);
1213
1214 return (fclose(fp));
1215 }
1216 /*
1217 * PSFillPolygon draws and fills a polygon given data in XPoint; see
1218 * XFillPolygon.
1219 */
1220
1221 int
PSFillPolygon(GC gc,XPoint * points,int numberOfPoints)1222 PSFillPolygon(
1223 GC gc, /* graphics context */
1224 XPoint * points, /* vertices of polygon */
1225 int numberOfPoints) /* number of points */
1226 {
1227 int i = 0;
1228 FILE *fp;
1229
1230 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1231 fprintf(stderr, "PSFillPolygon cannot open %s\n",
1232 psData[scriptps].filename);
1233 return (psError);
1234 }
1235
1236 psData[fillpolyps].flag = yes; /* sets procedure flag */
1237 fprintf(fp, "\t%s\n", PSfindGC(gc));
1238
1239 i = numberOfPoints - 1;
1240 while (i > 0)
1241 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
1242 i = i-1;
1243 }
1244
1245 fprintf(fp, "\t%d\t%d\t%d\tpsFillPoly\n", numberOfPoints, points[i].x, points[i].y);
1246
1247 return (fclose(fp));
1248 }
1249
1250 /*
1251 * PSFillwOutline draws and also outlines the filled polygon.
1252 */
1253
1254 int
PSFillwOutline(GC gc,XPoint * points,int numberOfPoints)1255 PSFillwOutline(
1256 GC gc, /* graphics context */
1257 XPoint * points, /* vertices of polygon */
1258 int numberOfPoints)
1259 /* number of points */
1260 {
1261 int i = 0;
1262 FILE *fp;
1263
1264 if ((fp = fopen(psData[scriptps].filename, "a")) == NULL) {
1265 fprintf(stderr, "PSDrawFOL cannot open %s\n", psData[scriptps].filename);
1266 return (psError);
1267 }
1268
1269 psData[fillwolps].flag = yes; /* sets procedure flag */
1270 fprintf(fp, "\t%s\n", PSfindGC(gc));
1271
1272 i = numberOfPoints - 1;
1273 while (i > 0)
1274 { fprintf(fp, "\t%d\t%d\n", points[i].x, points[i].y);
1275 i = i-1;
1276 }
1277
1278 fprintf(fp, "\t%d\t%d\t%d\tpsFillwOutline\n",
1279 numberOfPoints, points[i].x, points[i].y);
1280
1281 return (fclose(fp));
1282 }
1283
1284 static int
TrivEqual(Window s1,Window s2)1285 TrivEqual(Window s1,Window s2)
1286 {
1287 return ( s1 == s2);
1288 }
1289
1290 static int
TrivHash_code(Window s,int size)1291 TrivHash_code(Window s,int size)
1292 {
1293 return (s % size);
1294 }
1295
1296
1297 HashTable *
XCreateAssocTable(int size)1298 XCreateAssocTable(int size)
1299 {
1300 HashTable * table;
1301 table = (HashTable *) malloc(sizeof(HashTable));
1302 hash_init(table,size,(EqualFunction)TrivEqual,(HashcodeFunction)TrivHash_code);
1303 return table;
1304 }
1305
1306 void
XMakeAssoc(Display * dsp,HashTable * table,Window w,int * p)1307 XMakeAssoc(Display * dsp, HashTable *table, Window w, int * p)
1308 {
1309 hash_insert(table,(char *) p, (char *) w);
1310 }
1311
1312 int *
XLookUpAssoc(Display * dsp,HashTable * table,Window w)1313 XLookUpAssoc(Display * dsp, HashTable *table,Window w)
1314 {
1315 return (int *) hash_find(table,(char *)w);
1316 }
1317
1318 void
XDeleteAssoc(Display * dsp,HashTable * table,Window w)1319 XDeleteAssoc(Display * dsp,HashTable * table, Window w)
1320 {
1321 hash_delete(table,(char *) w);
1322 }
1323