Annotation of OpenXM_contrib/gnuplot/term/next.trm, Revision 1.1.1.1
1.1 maekawa 1: /*
2: * $Id: next.trm,v 1.22 1998/06/18 14:59:21 ddenholm Exp $
3: *
4: */
5:
6: /* GNUPLOT - next.trm */
7:
8: /*[
9: * Copyright 1991 - 1993, 1998
10: *
11: * Permission to use, copy, and distribute this software and its
12: * documentation for any purpose with or without fee is hereby granted,
13: * provided that the above copyright notice appear in all copies and
14: * that both that copyright notice and this permission notice appear
15: * in supporting documentation.
16: *
17: * Permission to modify the software is granted, but not the right to
18: * distribute the complete modified source code. Modifications are to
19: * be distributed as patches to the released version. Permission to
20: * distribute binaries produced by compiling modified sources is granted,
21: * provided you
22: * 1. distribute the corresponding source modifications from the
23: * released version in the form of a patch file along with the binaries,
24: * 2. add special version identification to distinguish your version
25: * in addition to the base release version number,
26: * 3. provide your name and address as the primary contact for the
27: * support of your modified version, and
28: * 4. retain our contact information in regard to use of the base
29: * software.
30: * Permission to distribute the released version of the source code along
31: * with corresponding source modifications in the form of a patch file is
32: * granted with same provisions 2 through 4 for binary distributions.
33: *
34: * This software is provided "as is" without express or implied warranty
35: * to the extent permitted by applicable law.
36: ]*/
37:
38: /*
39: * This file is included by ../term.c via ../term.h.
40: *
41: * This terminal driver supports:
42: * next
43: *
44: * AUTHORS
45: * Robert Lutwak from Russell Lang's post.trm
46: * 'old' option invokes Nick Strobel's original, single viewport terminal
47: *
48: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
49: *
50: * This terminal attempts to connect, via the NeXTstep Distributed
51: * Objects system, to the "gnuplotServer." If there is no such
52: * service registered with the OS, the terminal attempts to fire
53: * up GnuTerm.app. If the user has not set the environment variable
54: * GNUTERMPATH, the terminal uses the users ApplicationPaths Workspace
55: * dwrite to search for GnuTerm.app (Note: this is usually something
56: * like ~/Apps, ~/LocalApps, ~/NextApps, etc.).
57: * In order to use this filter, you MUST have GnuTerm.app installed
58: * on your system.
59: *
60: * Once connected to the server, this filter is basically Russell Lang's
61: * Postscript filter, except that the resultant postscript code
62: * is sent, via the D.O. system, to GnuTerm.app, which manages
63: * the windows which produce the postscript output on the screen.
64: *
65: *
66: * Defaults are
67: * 'set term next new dashed auto "Helvetica" 14'
68: *
69: * To change font to Times-Roman and font size to 20pts use
70: * 'set term next "Times-Roman" 20'.
71: *
72: * to choose window by title
73: * 'set term next title "Window title"
74: *
75: * Monitor Options:
76: * monochrome, color
77: *
78: * To invoke Nick Strobel's old terminal
79: * 'set term next old'
80: */
81:
82: #include "driver.h"
83:
84: #ifdef TERM_REGISTER
85: register_term(next)
86: #endif
87:
88: #ifdef TERM_PROTO
89:
90: /* whether or not to compile support for the old (self-contained)
91: NeXT terminal */
92: /* #define NEXT_OLDTERMINAL 1 */
93:
94: #import <appkit/appkit.h>
95: #import <remote/NXProxy.h> /* setProtocolForProxy */
96: #import <remote/NXConnection.h> /* setProtocolForProxy */
97: #import <machkit/NXNetNameServer.h>
98: #import <machkit/senderIsInvalid.h>
99: #import <stdarg.h>
100:
101:
102: #ifdef NEXT_OLDTERMINAL
103: static void window_create __PROTO((void));
104: @interface EpsViewer:Application
105: {
106: id theNewWin;
107: }
108:
109: -windowCreate:(NXCoord)
110: width Height:(NXCoord) height;
111: -(NXRect *) nextRectForWidth:(NXCoord)
112: width Height:(NXCoord) height;
113: @end
114: #endif /* NEXT_OLDTERMINAL */
115:
116:
117: TERM_PUBLIC void NEXT_options __PROTO((void));
118: TERM_PUBLIC void NEXT_common_init __PROTO((int uses_fonts, unsigned int xoff, unsigned int yoff, unsigned int xsize, unsigned int ysize, char **dict));
119: TERM_PUBLIC void NEXT_init __PROTO((void));
120: TERM_PUBLIC void NEXT_graphics __PROTO((void));
121: TERM_PUBLIC void NEXT_text __PROTO((void));
122: TERM_PUBLIC void NEXT_reset __PROTO((void));
123: TERM_PUBLIC void NEXT_linetype __PROTO((int linetype));
124: TERM_PUBLIC void NEXT_move __PROTO((unsigned int x, unsigned int y));
125: TERM_PUBLIC void NEXT_vector __PROTO((unsigned int x, unsigned int y));
126: TERM_PUBLIC void NEXT_put_text __PROTO((unsigned int x, unsigned int y, char *str));
127: TERM_PUBLIC int NEXT_text_angle __PROTO((int ang));
128: TERM_PUBLIC int NEXT_justify_text __PROTO((enum JUSTIFY mode));
129: TERM_PUBLIC void NEXT_point __PROTO((unsigned int x, unsigned int y, int number));
130: TERM_PUBLIC int NEXT_set_font __PROTO((char *font));
131: TERM_PUBLIC char *NEXT_RememberFont __PROTO((char *fname));
132: TERM_PUBLIC void NEXT_set_pointsize __PROTO((double size));
133:
134:
135: #define NEXT_POINT_TYPES 8 /* div */
136: #define NEXT_XOFF 1 /* page offset in pts */
137: #define NEXT_YOFF 1
138: #define NEXT_XMAX 6400
139: #define NEXT_YMAX 4800
140: #define NEXT_XLAST (NEXT_XMAX - 1)
141: #define NEXT_YLAST (NEXT_YMAX - 1)
142: #define NEXT_VTIC (NEXT_YMAX/80)
143: #define NEXT_HTIC (NEXT_YMAX/80)
144: #define NEXT_SC (10) /* scale is 1pt = 10 units */
145: #define NEXT_LW (0.5*NEXT_SC) /* linewidth = 0.5 pts */
146: #define NEXT_VCHAR (14*NEXT_SC) /* default is 14 point characters */
147: #define NEXT_HCHAR (14*NEXT_SC*6/10)
148:
149: #define GOT_NEXT_PROTO
150: #endif
151:
152:
153: #ifndef TERM_PROTO_ONLY
154:
155: #ifdef TERM_BODY
156:
157: @interface GnuTermDriver:Object < NXSenderIsInvalid >
158: {
159: id server;
160: }
161:
162: -senderIsInvalid:(id) sender;
163: -plot:(char *) PSstr;
164: -init;
165: @end
166:
167:
168: #define DEFAULTNEXTSIZE 10000
169:
170: static id gnuTermAccess; /* local object manages the D.O. connection */
171:
172: static char *NEXTBuffer, *NEXTBufAt, *NEXTBufEnd;
173: static int NEXTsize;
174: static char NEXTTmpBuf[1000];
175: static void NEXTPrintf(char *,...);
176: static TBOOLEAN NEXT_oldterminal = FALSE;
177: /*static TBOOLEAN NEXT_colordetect();*/
178:
179: static char NEXT_title[MAX_LINE_LEN + 1]; /* name of font */
180:
181: static char NEXT_font[MAX_LINE_LEN + 1] = "Helvetica"; /* name of font */
182: static int NEXT_fontsize = 14; /* size of font in pts */
183: static TBOOLEAN NEXT_color = FALSE;
184: static TBOOLEAN NEXT_solid = FALSE; /* use dashed lines */
185: static int NEXT_path_count = 0; /* count of lines in path */
186: static int NEXT_ang = 0; /* text angle */
187: static enum JUSTIFY NEXT_justify = LEFT; /* text is flush left */
188:
189: static TBOOLEAN NEXT_duplex_state = FALSE;
190: static TBOOLEAN NEXT_duplex_option = FALSE;
191:
192: static char GPFAR *GPFAR NEXT_header[] =
193: {
194: "/M {moveto} bind def\n",
195: "/L {lineto} bind def\n",
196: "/R {rmoveto} bind def\n",
197: "/V {rlineto} bind def\n",
198: "/vpt2 vpt 2 mul def\n",
199: "/hpt2 hpt 2 mul def\n",
200: /* flush left show */
201: "/Lshow { currentpoint stroke M\n",
202: " 0 vshift R show } def\n",
203: /* flush right show */
204: "/Rshow { currentpoint stroke M\n",
205: " dup stringwidth pop neg vshift R show } def\n",
206: /* centred show */
207: "/Cshow { currentpoint stroke M\n",
208: " dup stringwidth pop -2 div vshift R show } def\n",
209: /* Dash or Color Line */
210: "/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }\n",
211: " {pop pop pop Solid {pop []} if 0 setdash} ifelse } def\n",
212: /* Border Lines */
213: "/BL { stroke gnulinewidth 2 mul setlinewidth } def\n",
214: /* Axes Lines */
215: "/AL { stroke gnulinewidth 2 div setlinewidth } def\n",
216: /* Plot Lines */
217: "/PL { stroke gnulinewidth setlinewidth } def\n",
218: /* Line Types */
219: "/LTb { BL [] 0 0 0 DL } def\n", /* border */
220: "/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def\n", /* axes */
221: "/LT0 { PL [] 0 1 0 DL } def\n",
222: "/LT1 { PL [4 dl 2 dl] 0 0 1 DL } def\n",
223: "/LT2 { PL [2 dl 3 dl] 1 0 0 DL } def\n",
224: "/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def\n",
225: "/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def\n",
226: "/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def\n",
227: "/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def\n",
228: "/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def\n",
229: "/LT8 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 0.5 0.5 0.5 DL } def\n",
230: /* Point (Round) *//* Matt Heffron make it round */
231: "/Pnt { stroke [] 0 setdash\n",
232: " gsave 1 setlinecap M 0 0 V stroke grestore } def\n",
233:
234: /* Diamond */
235: "/Dia { stroke [] 0 setdash 2 copy vpt add M\n",
236: " hpt neg vpt neg V hpt vpt neg V\n",
237: " hpt vpt V hpt neg vpt V closepath stroke\n",
238: " Pnt } def\n",
239:
240: /* Plus */
241: "/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V\n",
242: " currentpoint stroke M\n",
243: " hpt neg vpt neg R hpt2 0 V stroke\n",
244: " } def\n",
245:
246: /* Box */
247: "/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M\n",
248: " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
249: " hpt2 neg 0 V closepath stroke\n",
250: " Pnt } def\n",
251:
252: /* Cross (X) */
253: "/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
254: " hpt2 vpt2 neg V currentpoint stroke M\n",
255: " hpt2 neg 0 R hpt2 vpt2 V stroke } def\n",
256:
257: /* Triangle Up*/
258: "/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M\n",
259: " hpt neg vpt -1.62 mul V\n",
260: " hpt 2 mul 0 V\n",
261: " hpt neg vpt 1.62 mul V closepath stroke\n",
262: " Pnt } def\n",
263:
264: /* Star */
265: "/Star { 2 copy Pls Crs } def\n",
266:
267: /* div added filed box */
268: /* Filled Box */
269: "/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
270: " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
271: " hpt2 neg 0 V closepath fill } def\n",
272:
273: /* div added filled triangle */
274: /* Triangle Up, Filled */
275: "/TriUF { stroke [] 0 setdash vpt 1.12 mul add M\n",
276: " hpt neg vpt -1.62 mul V\n",
277: " hpt 2 mul 0 V\n",
278: " hpt neg vpt 1.62 mul V closepath fill } def\n",
279:
280: /* Matt Heffron: added a few more types */
281: /* Triangle Down */
282: "/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M\n",
283: " hpt neg vpt 1.62 mul V\n",
284: " hpt 2 mul 0 V\n",
285: " hpt neg vpt -1.62 mul V closepath stroke\n",
286: " Pnt } def\n",
287:
288: /* Triangle Down, Filled*/
289: "/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M\n",
290: " hpt neg vpt 1.62 mul V\n",
291: " hpt 2 mul 0 V\n",
292: " hpt neg vpt -1.62 mul V closepath fill} def\n",
293:
294: /* Diamond, Filled */
295: "/DiaF { stroke [] 0 setdash vpt add M\n",
296: " hpt neg vpt neg V hpt vpt neg V\n",
297: " hpt vpt V hpt neg vpt V closepath fill } def\n",
298:
299: /* Pentagon */
300: "/Pent { stroke [] 0 setdash 2 copy gsave\n",
301: " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
302: " closepath stroke grestore Pnt } def\n",
303:
304: /* Pentagon, Filled */
305: "/PentF { stroke [] 0 setdash gsave\n",
306: " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
307: " closepath fill grestore } def\n",
308:
309: /* Circle */
310: "/Circle { stroke [] 0 setdash 2 copy\n",
311: " hpt 0 360 arc stroke Pnt } def\n",
312:
313: /* Circle,Filled */
314: "/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def\n",
315: /* 16 differently filled circles */
316: "/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def\n",
317: "/C1 { BL [] 0 setdash 2 copy moveto\n",
318: " 2 copy vpt 0 90 arc closepath fill\n",
319: " vpt 0 360 arc closepath } bind def\n",
320: "/C2 { BL [] 0 setdash 2 copy moveto\n",
321: " 2 copy vpt 90 180 arc closepath fill\n",
322: " vpt 0 360 arc closepath } bind def\n",
323: "/C3 { BL [] 0 setdash 2 copy moveto\n",
324: " 2 copy vpt 0 180 arc closepath fill\n",
325: " vpt 0 360 arc closepath } bind def\n",
326: "/C4 { BL [] 0 setdash 2 copy moveto\n",
327: " 2 copy vpt 180 270 arc closepath fill\n",
328: " vpt 0 360 arc closepath } bind def\n",
329: "/C5 { BL [] 0 setdash 2 copy moveto\n",
330: " 2 copy vpt 0 90 arc\n",
331: " 2 copy moveto\n",
332: " 2 copy vpt 180 270 arc closepath fill\n",
333: " vpt 0 360 arc } bind def\n",
334: "/C6 { BL [] 0 setdash 2 copy moveto\n",
335: " 2 copy vpt 90 270 arc closepath fill\n",
336: " vpt 0 360 arc closepath } bind def\n",
337: "/C7 { BL [] 0 setdash 2 copy moveto\n",
338: " 2 copy vpt 0 270 arc closepath fill\n",
339: " vpt 0 360 arc closepath } bind def\n",
340: "/C8 { BL [] 0 setdash 2 copy moveto\n",
341: " 2 copy vpt 270 360 arc closepath fill\n",
342: " vpt 0 360 arc closepath } bind def\n",
343: "/C9 { BL [] 0 setdash 2 copy moveto\n",
344: " 2 copy vpt 270 450 arc closepath fill\n",
345: " vpt 0 360 arc closepath } bind def\n",
346: "/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill\n",
347: " 2 copy moveto\n",
348: " 2 copy vpt 90 180 arc closepath fill\n",
349: " vpt 0 360 arc closepath } bind def\n",
350: "/C11 { BL [] 0 setdash 2 copy moveto\n",
351: " 2 copy vpt 0 90 arc closepath fill\n",
352: " 2 copy moveto\n",
353: " 2 copy vpt 180 360 arc closepath fill\n",
354: " vpt 0 360 arc closepath } bind def\n",
355: "/C12 { BL [] 0 setdash 2 copy moveto\n",
356: " 2 copy vpt 180 360 arc closepath fill\n",
357: " vpt 0 360 arc closepath } bind def\n",
358: "/C13 { BL [] 0 setdash 2 copy moveto\n",
359: " 2 copy vpt 0 90 arc closepath fill\n",
360: " 2 copy moveto\n",
361: " 2 copy vpt 180 360 arc closepath fill\n",
362: " vpt 0 360 arc closepath } bind def\n",
363: "/C14 { BL [] 0 setdash 2 copy moveto\n",
364: " 2 copy vpt 90 360 arc closepath fill\n",
365: " vpt 0 360 arc } bind def\n",
366: "/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill\n",
367: " vpt 0 360 arc closepath } bind def\n",
368:
369: /* Auxiliary definitions for rectangles */
370:
371: "/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n",
372: " neg 0 rlineto closepath } bind def\n",
373: "/Square { dup Rec } bind def\n",
374: "/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def\n",
375:
376: /* 16 differently filled squares */
377:
378: "/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def\n",
379: "/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def\n",
380: "/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
381: "/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def\n",
382: "/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
383: "/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill\n",
384: " exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
385: "/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
386: "/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill\n",
387: " 2 copy vpt Square fill\n",
388: " Bsquare } bind def\n",
389: "/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def\n",
390: "/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
391: "/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill\n",
392: " Bsquare } bind def\n",
393: "/S11 { 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill\n",
394: " Bsquare } bind def\n",
395: "/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def\n",
396: "/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
397: " 2 copy vpt Square fill Bsquare } bind def\n",
398: "/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
399: " 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
400: "/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def\n",
401:
402: /* 16 different diamonds (actually just rotated squares) */
403:
404: "/D0 { gsave translate 45 rotate 0 0 Box stroke grestore } bind def\n",
405: "/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def\n",
406: "/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def\n",
407: "/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def\n",
408: "/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def\n",
409: "/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def\n",
410: "/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def\n",
411: "/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def\n",
412: "/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def\n",
413: "/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def\n",
414: "/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def\n",
415: "/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def\n",
416: "/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def\n",
417: "/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def\n",
418: "/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def\n",
419: "/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def\n",
420:
421: NULL
422: };
423:
424: static char GPFAR *GPFAR ENHNEXT_header[] =
425: {
426: /* For MFshow and MFwidth the tos is an array with the string and font info: */
427: /* [<fontname (a string)> <fontsize> <vertical offset> <width significant?> <text string>] */
428:
429: "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n",
430: " [ currentpoint ] exch dup 2 get 0 exch rmoveto dup 4 get show dup\n",
431: " 3 get {2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n",
432: "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n",
433: " 4 get stringwidth pop add}\n",
434: " {pop} ifelse} forall} bind def\n",
435:
436: /* flush left show */
437: "/MLshow { currentpoint stroke M\n",
438: " 0 exch R MFshow } bind def\n",
439:
440: /* flush right show */
441: "/MRshow { currentpoint stroke M\n",
442: " exch dup MFwidth neg 3 -1 roll R MFshow } def\n",
443:
444: /* centred show */
445: "/MCshow { currentpoint stroke M\n",
446: " exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n",
447: NULL
448: };
449:
450: /* added to post by Matt Heffron <heffron@falstaff.css.beckman.com> */
451: /* moved to post.trm by drd */
452:
453: struct NEXT_FontName {
454: char *name;
455: struct NEXT_FontName *next;
456: } *NEXT_DocFonts = NULL;
457:
458: TERM_PUBLIC char *NEXT_RememberFont(fname)
459: char *fname;
460: {
461: struct NEXT_FontName *fnp;
462:
463: for (fnp = NEXT_DocFonts; fnp && strcmp(fnp->name, fname); fnp = fnp->next);
464: if (fnp)
465: return fnp->name; /* we must have found it in the list */
466:
467: if (encoding == ENCODING_ISO_8859_1) {
468: NEXTPrintf("/%s reencodeISO def\n", fname);
469: }
470: fnp = (struct NEXT_FontName *) gp_alloc(sizeof(struct NEXT_FontName), "PostScript Font record");
471: fnp->name = gp_alloc(1 + strlen(fname), "PostScript Font name");
472: strcpy(fnp->name, fname);
473: fnp->next = NEXT_DocFonts;
474: NEXT_DocFonts = fnp;
475: return fnp->name;
476: }
477:
478: int NEXT_pen_x, NEXT_pen_y;
479: int NEXT_taken;
480: int NEXT_linetype_last;
481: TBOOLEAN NEXT_relative_ok;
482:
483: TERM_PUBLIC void NEXT_options()
484: {
485: char buf[40];
486: for (; !END_OF_COMMAND; ++c_token) {
487: if (almost_equals(c_token, "d$efault")) {
488: NEXT_oldterminal = FALSE;
489: /*NEXT_color=NEXT_colordetect(); */
490: NEXT_color = FALSE;
491: NEXT_solid = FALSE;
492: NEXT_duplex_option = FALSE;
493: strcpy(NEXT_font, "Helvetica");
494: NEXT_fontsize = 14;
495: term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
496: term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
497: term->put_text = NEXT_put_text;
498: } else if (almost_equals(c_token, "mono$chrome")) {
499: NEXT_color = FALSE;
500: } else if (almost_equals(c_token, "col$or")
501: || almost_equals(c_token, "col$our")) {
502: NEXT_color = TRUE;
503: }
504: /*
505: else if (almost_equals(c_token,"auto$detect")) {
506: NEXT_color = NEXT_colordetect();
507: }
508: */
509:
510: else if (almost_equals(c_token, "so$lid")) {
511: NEXT_solid = TRUE;
512: } else if (almost_equals(c_token, "da$shed")) {
513: NEXT_solid = FALSE;
514: } else if (almost_equals(c_token, "si$mplex")) {
515: NEXT_duplex_state = FALSE;
516: NEXT_duplex_option = TRUE;
517: } else if (almost_equals(c_token, "du$plex")) {
518: NEXT_duplex_state = TRUE;
519: NEXT_duplex_option = TRUE;
520: } else if (almost_equals(c_token, "defaultp$lex")) {
521: NEXT_duplex_option = FALSE;
522: } else if (isstring(c_token)) {
523: quote_str(NEXT_font, c_token, MAX_LINE_LEN + 1);
524:
525: /* We must have font size specified */
526: copy_str(buf, ++c_token, 40);
527: NEXT_fontsize = atoi(buf);
528: term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
529: term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
530: sprintf(default_font, "%s,%d", NEXT_font, NEXT_fontsize);
531: } else if (almost_equals(c_token, "ti$tle")) {
532: if (!isstring(++c_token)) {
533: fprintf(stderr, "usage: set term next title \"newtitle\"\n");
534: --c_token;
535: }
536: quote_str(NEXT_title, c_token, MAX_LINE_LEN + 1);
537: } else if (almost_equals(c_token, "old")) {
538: NEXT_oldterminal = TRUE;
539: } else if (almost_equals(c_token, "new")) {
540: NEXT_oldterminal = FALSE;
541: }
542: }
543:
544:
545:
546: sprintf(term_options, "%s %s %s %s \"%s\" %d title \"%s\"",
547: NEXT_oldterminal ? "old" : "new",
548: NEXT_color ? "color" : "monochrome",
549: NEXT_solid ? "solid" : "dashed",
550: NEXT_duplex_option ? (NEXT_duplex_state ? "duplex" : "simplex")
551: : "defaultplex",
552: NEXT_font,
553: NEXT_fontsize,
554: NEXT_title);
555: }
556:
557: /* store settings passed to common_init() for use in NEXT_graphics()
558: * are reserved for storing the term options
559: */
560: static int NEXT_common_uses_fonts;
561: static unsigned int NEXT_common_xoff, NEXT_common_yoff;
562:
563:
564: TERM_PUBLIC void NEXT_common_init(uses_fonts, xoff, yoff, width, height, dict)
565: int uses_fonts; /* 0 for NEXT(la)tex */
566: unsigned int xoff, yoff; /* offset - 50 for /post, 0 for NEXT(la)tex */
567: unsigned int width, height; /* for bounding box */
568: char **dict; /* extra entries for the dictionary */
569: {
570: static char GPFAR NEXTi1[] = "%%%%Creator: gnuplot\n\
571: %%%%DocumentFonts: %s\n";
572: static char GPFAR NEXTi2[] = "%%%%EndComments\n\
573: /gnudict 120 dict def\ngnudict begin\n\
574: /Color %s def\n\
575: /Solid %s def\n\
576: /gnulinewidth %.3f def\n\
577: /vshift %d def\n\
578: /dl {%d mul} def\n\
579: /hpt %.1f def\n\
580: /vpt %.1f def\n";
581: static char GPFAR *NEXT_iso_8859_1_encoding[] =
582: {
583: "/reencodeISO {\n",
584: "dup dup findfont dup length dict begin\n",
585: "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
586: "/Encoding ISOLatin1Encoding def\n",
587: "currentdict end definefont\n",
588: "} def\n",
589: "/ISOLatin1Encoding [\n",
590: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
591: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
592: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
593: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
594: "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
595: "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
596: "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
597: "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
598: "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
599: "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
600: "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde\n",
601: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
602: "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
603: "/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve\n",
604: "/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut\n",
605: "/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar\n",
606: "/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot\n",
607: "/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior\n",
608: "/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine\n",
609: "/guillemotright/onequarter/onehalf/threequarters/questiondown\n",
610: "/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla\n",
611: "/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n",
612: "/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n",
613: "/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute\n",
614: "/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n",
615: "/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave\n",
616: "/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex\n",
617: "/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n",
618: "/yacute/thorn/ydieresis\n",
619: "] def\n",
620: NULL};
621:
622:
623: struct termentry *t = term;
624: int i;
625:
626: NEXT_common_uses_fonts = uses_fonts;
627: NEXT_common_xoff = xoff;
628: NEXT_common_yoff = yoff;
629:
630:
631: NEXTPrintf("%%!NEXT-Adobe-2.0\n");
632:
633: NEXTPrintf(NEXTi1, uses_fonts ? "(atend)" : "");
634:
635: NEXTPrintf("%%%%BoundingBox: %d %d %d %d\n", xoff, yoff,
636: (int) (xsize * width / NEXT_SC + 0.5 + xoff),
637: (int) (ysize * height / NEXT_SC + 0.5 + yoff));
638:
639: NEXTPrintf(NEXTi2,
640: NEXT_color ? "true" : "false",
641: NEXT_solid ? "true" : "false",
642: NEXT_LW, /* line width */
643: (int) (t->v_char) / (-3), /* shift for vertical centring */
644: NEXT_SC, /* dash length */
645: NEXT_HTIC / 2.0, /* half point width */
646: NEXT_VTIC / 2.0); /* half point height */
647:
648: if (uses_fonts && (encoding == ENCODING_ISO_8859_1)) {
649: for (i = 0; NEXT_iso_8859_1_encoding[i] != NULL; i++) {
650: NEXTPrintf("%s", NEXT_iso_8859_1_encoding[i]);
651: }
652: }
653: for (i = 0; NEXT_header[i] != NULL; i++)
654: NEXTPrintf("%s", NEXT_header[i]);
655: if (NEXT_duplex_option)
656: NEXTPrintf("statusdict begin %s setduplexmode end\n",
657: NEXT_duplex_state ? "true" : "false");
658: NEXT_RememberFont(NEXT_font);
659:
660: if (dict)
661: while (*dict)
662: NEXTPrintf("%s", *(dict++));
663:
664: NEXTPrintf("end\n%%%%EndProlog\n");
665: }
666:
667: /* the init fn for the NeXT Terminal driver */
668: TERM_PUBLIC void NEXT_init()
669: {
670:
671: /* Initialize output string */
672: NEXTsize = DEFAULTNEXTSIZE;
673: if ((NEXTBuffer = malloc(NEXTsize)) == NULL) {
674: printf("Malloc error in next filter init\n");
675: exit(1);
676: }
677: NEXTBufEnd = NEXTBuffer + NEXTsize;
678: NEXTBufAt = NEXTBuffer;
679:
680:
681: term->xmax = NEXT_XMAX;
682: term->ymax = NEXT_YMAX;
683:
684: #ifdef NEXT_OLDTERMINAL
685: if (NEXT_oldterminal)
686: window_create();
687: else
688: gnuTermAccess =[[GnuTermDriver alloc] init];
689: #else
690: gnuTermAccess =[[GnuTermDriver alloc] init];
691: #endif
692:
693:
694:
695: }
696:
697:
698: TERM_PUBLIC void NEXT_graphics()
699: {
700: static char GPFAR NEXTg1[] = "0 setgray\nnewpath\n";
701: struct termentry *t = term;
702:
703: *NEXTBuffer = 0;
704: NEXTBufAt = NEXTBuffer;
705:
706: NEXT_common_init(1, NEXT_XOFF, NEXT_YOFF, term->xmax, term->ymax,
707: ENHNEXT_header);
708:
709: NEXTPrintf("gnudict begin\ngsave\n");
710: NEXTPrintf("%d %d translate\n", NEXT_common_xoff, NEXT_common_yoff);
711: NEXTPrintf("%.3f %.3f scale\n", 1.0 / NEXT_SC, 1.0 / NEXT_SC);
712:
713:
714: NEXTPrintf(NEXTg1);
715: if (NEXT_common_uses_fonts)
716: NEXTPrintf("(%s) findfont %d scalefont setfont\n", NEXT_font, (t->v_char));
717: NEXT_path_count = 0;
718: NEXT_relative_ok = FALSE;
719: NEXT_pen_x = NEXT_pen_y = -4000;
720: NEXT_taken = 0;
721: NEXT_linetype_last = -1;
722:
723: #ifdef NEXT_OLDTERMINAL
724: if (NEXT_oldterminal) {
725: /* Fill window with white */
726: NEXTPrintf("1 setgray\n");
727: NEXTPrintf("0 0 %d %d rectfill\n", NEXT_XMAX, NEXT_YMAX);
728: NEXTPrintf("0 setgray\n");
729: }
730: #endif
731:
732:
733: }
734:
735:
736: TERM_PUBLIC void NEXT_text()
737: {
738: static DPSContext d;
739:
740: NEXT_path_count = 0;
741: NEXTPrintf("stroke\ngrestore\nend\n");
742:
743: /* Terminate string */
744: *NEXTBufAt = 0;
745:
746: if (NEXT_oldterminal) {
747: d = DPSGetCurrentContext();
748: DPSPrintf(d, NEXTBuffer);
749: DPSFlushContext(d);
750: } else {
751: /* Here's the call that dumps the string to the server */
752: [gnuTermAccess plot:NEXTBuffer];
753:
754: }
755:
756: }
757:
758:
759: TERM_PUBLIC void NEXT_reset()
760: {
761: NEXTPrintf("%%%%Trailer\n");
762: if (!NEXT_common_uses_fonts) {
763: NEXTPrintf("%%%%DocumentFonts: ");
764: while (NEXT_DocFonts) {
765: struct NEXT_FontName *fnp;
766: fnp = NEXT_DocFonts->next;
767: NEXTPrintf("%s%s", NEXT_DocFonts->name, fnp ? ", " : "\n");
768: free(NEXT_DocFonts->name);
769: free(NEXT_DocFonts);
770: NEXT_DocFonts = fnp;
771: }
772: }
773: }
774:
775:
776: TERM_PUBLIC void NEXT_linetype(linetype)
777: int linetype;
778: {
779: linetype = (linetype % 9) + 2;
780: if (linetype < 0)
781: linetype = 0;
782: NEXT_relative_ok = FALSE;
783: if (NEXT_linetype_last == linetype)
784: return;
785: NEXT_linetype_last = linetype;
786: NEXTPrintf("LT%c\n", "ba012345678"[linetype]);
787: NEXT_path_count = 0;
788: }
789:
790:
791: TERM_PUBLIC void NEXT_move(x, y)
792: unsigned int x, y;
793: {
794: int dx, dy;
795: char abso[20], rel[20];
796: dx = x - NEXT_pen_x;
797: dy = y - NEXT_pen_y;
798: /* can't cancel all null moves--need a move after stroke'ing */
799: if (dx == 0 && dy == 0 && NEXT_relative_ok)
800: return;
801: sprintf(abso, "%d %d M\n", x, y);
802: sprintf(rel, "%d %d R\n", dx, dy);
803: if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
804: NEXTPrintf("%s", rel);
805: NEXT_taken++;
806: } else
807: NEXTPrintf("%s", abso);
808: NEXT_relative_ok = TRUE;
809: NEXT_path_count += 1;
810:
811: NEXT_pen_x = x;
812: NEXT_pen_y = y;
813: }
814:
815: TERM_PUBLIC void NEXT_vector(x, y)
816: unsigned int x, y;
817: {
818: int dx, dy;
819: char abso[20], rel[20];
820: dx = x - NEXT_pen_x;
821: dy = y - NEXT_pen_y;
822: if (dx == 0 && dy == 0)
823: return;
824: sprintf(abso, "%d %d L\n", x, y);
825: sprintf(rel, "%d %d V\n", dx, dy);
826: if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
827: NEXTPrintf("%s", rel);
828: NEXT_taken++;
829: } else
830: NEXTPrintf("%s", abso);
831: NEXT_relative_ok = TRUE;
832: NEXT_path_count += 1;
833: NEXT_pen_x = x;
834: NEXT_pen_y = y;
835: if (NEXT_path_count >= 400) {
836: NEXTPrintf("currentpoint stroke M\n");
837: NEXT_path_count = 0;
838: }
839: }
840:
841:
842:
843:
844: TERM_PUBLIC int NEXT_text_angle(ang)
845: int ang;
846: {
847: NEXT_ang = ang;
848: return TRUE;
849: }
850:
851:
852: TERM_PUBLIC int NEXT_justify_text(mode)
853: enum JUSTIFY mode;
854: {
855: NEXT_justify = mode;
856: return TRUE;
857: }
858:
859:
860: TERM_PUBLIC int NEXT_set_font(font) /* Entry font added by DJL */
861: char *font;
862: {
863: char name[32];
864: int size, sep;
865:
866: sep = strcspn(font, ",");
867: strncpy(name, font, sep);
868: name[sep] = NUL;
869: size = NEXT_fontsize;
870: sscanf(&(font[sep + 1]), "%d", &size);
871: NEXTPrintf("/%s findfont %d scalefont setfont\n", name, size * NEXT_SC);
872: NEXT_RememberFont(name);
873: return TRUE;
874: }
875:
876:
877: /* postscript point routines */
878:
879: TERM_PUBLIC void NEXT_set_pointsize(size)
880: double size;
881: {
882: NEXTPrintf("/vpt %.1f def /hpt %.1f def /vpt2 vpt 2 mul def /hpt2 hpt 2 mul def\n",
883: pointsize * NEXT_VTIC * 0.5, pointsize * NEXT_HTIC * 0.5);
884: }
885:
886: TERM_PUBLIC void NEXT_point(x, y, number)
887: unsigned int x, y;
888: int number;
889: {
890: static char *pointFNS[] =
891: {"Pnt", "Pls", "Crs", "Star",
892: "Box", "BoxF", "Circle", "CircleF",
893: "TriU", "TriUF", "TriD", "TriDF",
894: "Dia", "DiaF", "Pent", "PentF",
895: "C0", "C1", "C2", "C3",
896: "C4", "C5", "C6", "C7",
897: "C8", "C9", "C10", "C11",
898: "C12", "C13", "C14", "C15",
899: "S0", "S1", "S2", "S3",
900: "S4", "S5", "S6", "S7",
901: "S8", "S9", "S10", "S11",
902: "S12", "S13", "S14", "S15",
903: "D0", "D1", "D2", "D3",
904: "D4", "D5", "D6", "D7",
905: "D8", "D9", "D10", "D11",
906: "D12", "D13", "D14", "D15"
907: };
908: if (number < 0)
909: number = -1; /* negative types are all 'dot' */
910: else
911: number %= sizeof(pointFNS) / sizeof(pointFNS[0]) - 1;
912: NEXTPrintf("%d %d %s\n", x, y, pointFNS[number + 1]);
913:
914: NEXT_relative_ok = 0;
915: NEXT_path_count = 0;
916: NEXT_linetype_last = -1; /* force next linetype change */
917: }
918:
919:
920:
921:
922: /* All lifted from the enhanced postscript driver */
923:
924:
925:
926: static TBOOLEAN NEXT_opened_string; /* try to cut out empty ()'s */
927:
928: /* used in determining height of processed text */
929:
930: static float NEXT_max_height, NEXT_min_height;
931:
932:
933: /* process a bit of string, and return the last character used.
934: * p is start of string
935: * brace is TRUE to keep processing to }, FALSE for do one character
936: * fontname & fontsize are obvious
937: * base is the current baseline
938: * widthflag is TRUE if the width of this should count,
939: * FALSE for zero width boxes
940: */
941:
942: static char *NEXT_recurse(p, brace, fontname, fontsize, base, widthflag)
943: char *p, *fontname;
944: TBOOLEAN brace, widthflag;
945: double fontsize, base;
946: {
947:
948: /* close a postscript string if it has been opened */
949: #define NEXT_FLUSH \
950: { if (NEXT_opened_string) \
951: { NEXTPrintf("%s", ")]\n"); \
952: NEXT_opened_string = FALSE; \
953: } \
954: }
955:
956: #define NEXT_OPEN \
957: { if (!NEXT_opened_string) \
958: { NEXTPrintf( "[(%s) %.1f %.1f %s (", \
959: fontname, fontsize, base, \
960: widthflag ? "true" : "false"); \
961: NEXT_opened_string = TRUE; \
962: } \
963: }
964:
965:
966: /* Start each recursion with a clean string */
967: NEXT_FLUSH
968:
969: if (base + fontsize > NEXT_max_height) {
970: NEXT_max_height = base + fontsize;
971: }
972: if (base < NEXT_min_height) {
973: NEXT_min_height = base;
974: }
975: for (; *p; ++p) {
976: float shift;
977: float f = 0; /* used for getting new font size */
978: char *localfontname, ch;
979:
980: switch (*p) {
981: case '}':
982: if (brace)
983: return (p);
984:
985: fprintf(stderr, "next driver - spurious }\n");
986: break;
987:
988: case '_':
989: case '^':
990: shift = (*p == '^') ? 0.5 : -0.3;
991:
992: NEXT_FLUSH
993:
994: p = NEXT_recurse(p + 1, FALSE, fontname, fontsize * 0.8, base + shift * fontsize, widthflag);
995:
996: break;
997:
998: case '{':
999: /*{{{ recurse (possibly with a new font) */
1000:
1001: if (*++p == '/') { /* then parse a fontname, optional fontsize */
1002: while (*++p == ' ');
1003: localfontname = p;
1004: while ((ch = *p) > ' ' && ch != '=')
1005: ++p;
1006: if (ch == '=') {
1007: *p++ = '\0';
1008: /*{{{ get optional font size */
1009: f = (float) strtod(p, &p);
1010:
1011: if (f)
1012: f *= NEXT_SC; /* remember the scaling */
1013: else
1014: f = fontsize;
1015:
1016: /*}}} */
1017: } else {
1018: *p++ = '\0';
1019: f = fontsize;
1020: }
1021:
1022: while (*p == ' ')
1023: ++p;
1024: if (*localfontname)
1025: localfontname = NEXT_RememberFont(localfontname);
1026: else
1027: localfontname = fontname;
1028: } else {
1029: localfontname = fontname;
1030: f = fontsize;
1031: }
1032: /*}}} */
1033:
1034:
1035: p = NEXT_recurse(p, TRUE, localfontname, f, base, widthflag);
1036:
1037:
1038: NEXT_FLUSH
1039:
1040: break;
1041:
1042: case '@':
1043: /*{{{ phantom box - prints next 'char', then restores currentpoint */
1044:
1045: NEXT_FLUSH
1046:
1047: p = NEXT_recurse(++p, FALSE, fontname, fontsize, base, FALSE);
1048:
1049: break;
1050: /*}}} */
1051:
1052: case '(':
1053: case ')':
1054: /* special cases */
1055: NEXT_OPEN
1056: NEXTPrintf("\\");
1057: NEXTPrintf("%c", *p);
1058: break;
1059: /*}}} */
1060:
1061: case '\\':
1062: /*{{{ is it an escape */
1063: /* special cases */
1064:
1065: if (p[1] == '\\' || p[1] == '(' || p[1] == ')') {
1066: NEXT_OPEN
1067: NEXTPrintf("%c", '\\');
1068: } else if ((ch = p[1]) >= '0' && ch <= '7') {
1069: /* up to 3 octal digits */
1070: NEXT_OPEN
1071: NEXTPrintf("%c", '\\');
1072: NEXTPrintf("%c", ch);
1073: ++p;
1074: if ((ch = p[1]) >= '0' && ch <= '7') {
1075: NEXTPrintf("%c", ch);
1076: ++p;
1077: if ((ch = p[1]) >= '0' && ch <= '7') {
1078: NEXTPrintf("%c", ch);
1079: ++p;
1080: }
1081: }
1082: break;
1083: }
1084: ++p;
1085: /* just go and print it (fall into the 'default' case) */
1086:
1087: /*}}} */
1088: default:
1089: NEXT_OPEN
1090:
1091: NEXTPrintf("%c", *p);
1092: }
1093:
1094: /* like TeX, we only do one character in a recursion, unless it's
1095: * in braces
1096: */
1097:
1098: if (!brace) {
1099: NEXT_FLUSH
1100: return (p); /* the ++p in the outer copy will increment us */
1101: }
1102: }
1103: NEXT_FLUSH
1104: return p;
1105: }
1106:
1107:
1108: TERM_PUBLIC void NEXT_put_text(x, y, str)
1109: unsigned int x, y;
1110: char *str;
1111: {
1112: /* flush any pending graphics (all the XShow routines do this...) */
1113:
1114: if (!strlen(str))
1115: return;
1116:
1117: if (NEXT_path_count) {
1118: NEXTPrintf(" stroke\n");
1119: NEXT_path_count = 0;
1120: NEXT_relative_ok = FALSE;
1121: }
1122: NEXT_move(x, y);
1123:
1124: if (NEXT_ang != 0)
1125: NEXTPrintf("currentpoint gsave translate %d rotate 0 0 moveto\n",
1126: NEXT_ang * 90);
1127:
1128: NEXTPrintf("[ ");
1129:
1130: /* set up the globals */
1131:
1132: NEXT_opened_string = FALSE;
1133: NEXT_max_height = -1000;
1134: NEXT_min_height = 1000;
1135:
1136: while (*(str = NEXT_recurse(str, TRUE, NEXT_font,
1137: (double) term->v_char,
1138: 0.0, TRUE)));
1139:
1140: NEXT_max_height += NEXT_min_height;
1141:
1142: NEXTPrintf("] %.1f ", -NEXT_max_height / 3);
1143:
1144: switch (NEXT_justify) {
1145: case LEFT:
1146: NEXTPrintf("MLshow\n");
1147: break;
1148: case CENTRE:
1149: NEXTPrintf("MCshow\n");
1150: break;
1151: case RIGHT:
1152: NEXTPrintf("MRshow\n");
1153: break;
1154: }
1155:
1156: if (NEXT_ang != 0)
1157: NEXTPrintf("grestore\n");
1158: NEXT_path_count = 0;
1159: NEXT_relative_ok = FALSE;
1160: }
1161:
1162:
1163:
1164: /*
1165: static TBOOLEAN NEXT_colordetect()
1166: {
1167: NXScreen * mainscreen;
1168:
1169: mainscreen = [Application mainScreen];
1170: if (mainscreen->depth == NX_TwoBitGrayDepth) return(FALSE);
1171: return(TRUE);
1172: }
1173: */
1174:
1175: /* This just packs all the postscript into one (possibly huge) string
1176: * which will be passed (as a fake pointer) via D.O. to the server
1177: */
1178:
1179: void NEXTPrintf(char *fmt,...)
1180: {
1181: va_list ap;
1182: char *pb;
1183: int NEXToff;
1184:
1185: /* Process formatting instructions */
1186: va_start(ap, fmt);
1187: vsprintf(NEXTTmpBuf, fmt, ap);
1188: va_end(ap);
1189:
1190: /* Add to buffer */
1191: for (pb = NEXTTmpBuf; (*pb != 0); ++pb, ++NEXTBufAt) {
1192: /* reallocate if necessary */
1193: if (NEXTBufAt >= NEXTBufEnd) {
1194: NEXToff = NEXTBufAt - NEXTBuffer;
1195: NEXTsize *= 2;
1196: NEXTBuffer = realloc(NEXTBuffer, NEXTsize);
1197: NEXTBufEnd = NEXTBuffer + NEXTsize;
1198: NEXTBufAt = NEXTBuffer + NEXToff;
1199: }
1200: *NEXTBufAt = *pb;
1201: }
1202:
1203: return;
1204:
1205: }
1206:
1207: /* This next section implements the GnuTermDriver object which manages
1208: the D.O. connection and interface to OBjC
1209: */
1210:
1211:
1212: @protocol GnuTermServerMethods
1213: /*- (oneway) executePScode:(in char *)PStext termTitle:(in char *)title;*/
1214: - executePScode:(in char *)
1215: PStext termTitle:(in char *) title;
1216: @end
1217:
1218:
1219: @ implementation GnuTermDriver
1220:
1221: - init
1222: {
1223: NXConnection *myConnection;
1224: char serverpath[100], *envstring;
1225: int GnuTermPathSet = 0;
1226:
1227:
1228: /* Ask OS for connection to server */
1229: server =[NXConnection connectToName:"gnuplotServer"];
1230:
1231: /* Server is running ready to go */
1232: if (server) /*printf("Connected to server\n") */
1233: ;
1234:
1235: /* Server isn't running, we must fire it up */
1236: else {
1237: /*printf("Launching GnuTerm\n"); */
1238: *serverpath = 0;
1239:
1240: /* Check for path set in environment */
1241: if ((envstring = getenv("GNUTERMPATH")) != (char *) NULL) {
1242: sprintf(serverpath, "%s/GnuTerm.app/GnuTerm", envstring);
1243: GnuTermPathSet = 1;
1244: }
1245: /* Not in environment */
1246: else
1247: strcpy(serverpath, "GnuTerm");
1248:
1249: /* Try to launch application */
1250: if ([[Application workspace] launchApplication:serverpath] == NO) {
1251: printf("Failed to launch %s.\n", serverpath);
1252: /* Offer a little advice */
1253: if (GnuTermPathSet) {
1254: printf("You must have setenv GNUTERMPATH to something wrong\n");
1255: printf("I recommend you exit gnuplot and fix this.\n");
1256: } else {
1257: printf("It must be located in ~/Apps or /LocalApps\n");
1258: printf("I recommend that you either\n");
1259: printf("- move GnuTerm.app to one of these locations\n");
1260: printf("- set GNUTERMPATH with host%% setenv GNUTERMPATH /directory/containing_GnuTerm.app\n");
1261: printf("- start GnuTerm ahead of the first plot command\n");
1262: #ifdef NEXT_OLDTERMINAL
1263: printf("- use the old driver version (set term next old)\n");
1264: #endif
1265: }
1266: }
1267: /* I wish the gnuplot terminal interface would
1268: let me return an error here.
1269: */
1270:
1271: /* Application is launching */
1272: else {
1273: /* Wait for it to register Server methods with OS */
1274: do {
1275: server =[NXConnection connectToName:"gnuplotServer"];
1276: } while (!server); /* This could result in a hang,
1277: but I've never seen it fail */
1278: }
1279: }
1280:
1281:
1282: /* By limiting ourselves to known protocol
1283: * we speed up the messaging
1284: */
1285: [server setProtocolForProxy:@protocol(GnuTermServerMethods)];
1286:
1287: myConnection =[server connectionForProxy];
1288:
1289: /* If the server dies we want to know about it */
1290: [myConnection registerForInvalidationNotification:self];
1291: /* In fact, we'll worry about it */
1292: [NXPort worryAboutPortInvalidation];
1293:
1294: return self;
1295: }
1296:
1297:
1298: -plot:(char *) PSstr;
1299: {
1300: /* If server has become invalid, re-initialize */
1301: if (!server)
1302: [self init];
1303:
1304: /* This is where we send the huge postscript string to the server
1305: Note:
1306: The D.O. system doesn't actually give this pointer to the server.
1307: The pointer is dereferenced on the client side and the
1308: resulting data is sent to the server. On the server side,
1309: space for the data is automatically allocated, and a pointer to
1310: the local data is received.
1311: For details check out:
1312: /NextLibrary/Documentation/NextDev/GeneralRef/06_DistributedObjects/IntroDistObjects.rtf
1313: */
1314:
1315: /*printf("Calling server..."); */
1316: [server executePScode: PSstr termTitle:NEXT_title];
1317: /*printf("returned\n"); */
1318: *NEXT_title = 0;
1319:
1320: return self;
1321: }
1322:
1323: /* This gets called by OS if server goes down */
1324: -senderIsInvalid:(id) sender
1325: {
1326: server = 0;
1327: }
1328:
1329: @end
1330:
1331: #ifdef NEXT_OLDTERMINAL
1332:
1333: static void window_create()
1334: {
1335: float width, height;
1336:
1337: width = (xsize * (NEXT_XMAX) / NEXT_SC + 0.5 + NEXT_XOFF);
1338: height = (ysize * (NEXT_YMAX) / NEXT_SC + 0.5 + NEXT_YOFF);
1339:
1340: NXApp =[EpsViewer new];
1341: [NXApp windowCreate: width Height:height];
1342: }
1343:
1344: @implementation EpsViewer
1345:
1346: - windowCreate:(NXCoord)
1347: width Height:(NXCoord) height
1348: {
1349:
1350: /* create the new window, in a good place */
1351: theNewWin =[Window
1352: newContent: [self nextRectForWidth: width Height:height]
1353: style: NX_TITLEDSTYLE
1354: backing: NX_RETAINED
1355: buttonMask: (NX_CLOSEBUTTONMASK | NX_MINIATURIZEBUTTONMASK)
1356: defer: NO];
1357: /* we need to receive windowDidBecomeMain: and windowDidResignMain: */
1358: [theNewWin setDelegate:self];
1359: /*
1360: * create a new View, make it the contentView of our new window,
1361: * and destroy the window's old contentView
1362: */
1363: [[theNewWin setContentView:[[View alloc] init]] free];
1364: /* display the window, and bring it forth */
1365: [theNewWin display];
1366: [theNewWin makeKeyAndOrderFront:self];
1367: /* [theNewWin orderBack:self]; */
1368: /* show the frame */
1369: return self;
1370: }
1371:
1372: /***************************************************************************/
1373: /* nextRectForWidth:Height: - return the next good content rectangle */
1374: /* from Carl F. Sutter's wonderful ViewGif2 'Controller' method... */
1375: /***************************************************************************/
1376: /* nextTopLeft - return the next good top left window position */
1377: /***************************************************************************/
1378:
1379: -(NXRect *) nextRectForWidth:(NXCoord)
1380: width Height:(NXCoord) height
1381: {
1382: #define OFFSET 10.0
1383: #define MAX_STEPS 20
1384: #define INITIAL_X 356.0
1385: #define INITIAL_Y 241.0
1386: NXPoint nxpTopLeft;
1387: NXRect nxrTemp; /* used to find window height */
1388: NXRect nxrWinHeight; /* bounds of enclosing window */
1389: NXSize nxsScreen; /* size of screen */
1390: static NXRect nxrResult; /* the Answer! */
1391: static int nCurStep = 0;
1392:
1393: /* find a good top-left coord */
1394: nxpTopLeft.x = INITIAL_X + nCurStep * OFFSET;
1395: nxpTopLeft.y = INITIAL_Y + nCurStep * OFFSET;
1396: if (++nCurStep > MAX_STEPS)
1397: nCurStep = 0;
1398: /* find window height using nxrTemp */
1399: nxrTemp.size.width = width;
1400: nxrTemp.size.height = height;
1401: nxrTemp.origin.x = nxrTemp.origin.y = 0;
1402: [Window getFrameRect: &nxrWinHeight forContentRect:&nxrTemp
1403: style:NX_TITLEDSTYLE];
1404: [NXApp getScreenSize:&nxsScreen];
1405: /* find the lower-left coord */
1406: nxrResult.origin.x = nxpTopLeft.x;
1407: nxrResult.origin.y = nxsScreen.height - nxrWinHeight.size.height - nxpTopLeft.y;
1408: nxrResult.size.width = width;
1409: nxrResult.size.height = height;
1410: return (&nxrResult);
1411: }
1412:
1413: @end
1414: #endif /* NEXT_OLDTERMINAL */
1415:
1416:
1417: #endif /* TERM_BODY */
1418:
1419: #ifdef TERM_TABLE
1420:
1421:
1422: TERM_TABLE_START(next_driver)
1423: "next",
1424: "Interface to GnuTerm.app under NeXTstep",
1425: NEXT_XMAX, NEXT_YMAX, NEXT_VCHAR, NEXT_HCHAR,
1426: NEXT_VTIC, NEXT_HTIC, NEXT_options, NEXT_init, NEXT_reset,
1427: NEXT_text, null_scale, NEXT_graphics, NEXT_move, NEXT_vector,
1428: NEXT_linetype, NEXT_put_text, NEXT_text_angle,
1429: NEXT_justify_text, NEXT_point, do_arrow, NEXT_set_font,
1430: NEXT_set_pointsize
1431: TERM_TABLE_END(next_driver)
1432:
1433: #undef LAST_TERM
1434: #define LAST_TERM next_driver
1435:
1436: #endif /* TERM_TABLE */
1437: #endif /* TERM_PROTO_ONLY */
1438:
1439:
1440:
1441: #ifdef TERM_HELP
1442: START_HELP(next)
1443: "1 next",
1444: "?commands set terminal next",
1445: "?set terminal next",
1446: "?set term next",
1447: "?terminal next",
1448: "?term next",
1449: "?next",
1450: "?NeXT",
1451: " Several options may be set in the next driver.",
1452: "",
1453: " Syntax:",
1454: " set terminal next {<mode>} {<type> } {<color>} {<dashed>}",
1455: " {\"<fontname>\"} {<fontsize>} title {\"<newtitle>\"}",
1456: "",
1457: " where <mode> is `default`, which sets all options to their defaults;",
1458: " <type> is either `new` or `old`, where `old` invokes the old single window;",
1459: " <color> is either `color` or `monochrome`;",
1460: " <dashed> is either `solid` or `dashed`;",
1461: " \"<fontname>\" is the name of a valid PostScript font;",
1462: " <fontsize> is the size of the font in PostScript points; and",
1463: " <title> is the title for the GnuTerm window.",
1464: " Defaults are `new`, `monochrome`, `dashed`, \"Helvetica\", 14pt.",
1465: "",
1466: " Examples:",
1467: " set term next default",
1468: " set term next 22",
1469: " set term next color \"Times-Roman\" 14",
1470: " set term next color \"Helvetica\" 12 title \"MyPlot\"",
1471: " set term next old",
1472: "",
1473: " Pointsizes may be changed with `set linestyle`."
1474: END_HELP(next)
1475: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>