2 * $Id: openstep.trm,v 1.18 2006/07/21 02:35:47 sfeam Exp $
6 /* GNUPLOT - openstep.trm */
9 * Copyright 1991 - 1993, 1998, 2004
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.
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,
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
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.
34 * This software is provided "as is" without express or implied warranty
35 * to the extent permitted by applicable law.
39 * Name changed from "next" to "openstep" to distinguish the two different
40 * drivers. Also avoids duplications in the complete gnuplot documentation.
45 * This file is included by ../term.c via ../term.h.
47 * This terminal driver supports:
51 * Robert Lutwak from Russell Lang's post.trm
52 * 'old' option invokes Nick Strobel's original, single viewport terminal
54 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
56 * This terminal attempts to connect, via the NeXTstep Distributed
57 * Objects system, to the "gnuplotServer." If there is no such
58 * service registered with the OS, the terminal attempts to fire
59 * up GnuTerm.app. If the user has not set the environment variable
60 * GNUTERMPATH, the terminal uses the users ApplicationPaths Workspace
61 * dwrite to search for GnuTerm.app (Note: this is usually something
62 * like ~/Apps, ~/LocalApps, ~/NextApps, etc.).
63 * In order to use this filter, you MUST have GnuTerm.app installed
66 * Once connected to the server, this filter is basically Russell Lang's
67 * Postscript filter, except that the resultant postscript code
68 * is sent, via the D.O. system, to GnuTerm.app, which manages
69 * the windows which produce the postscript output on the screen.
73 * 'set term openstep new dashed auto "Helvetica" 14'
75 * To change font to Times-Roman and font size to 20pts use
76 * 'set term openstep "Times-Roman" 20'.
78 * to choose window by title
79 * 'set term openstep title "Window title"
84 * To invoke Nick Strobel's old terminal
85 * 'set term openstep old'
91 register_term(openstep)
96 #import <Foundation/Foundation.h>
97 #import <AppKit/AppKit.h>
101 TERM_PUBLIC void NEXT_options __PROTO((void));
102 TERM_PUBLIC void NEXT_common_init __PROTO((int uses_fonts, unsigned int xoff, unsigned int yoff, unsigned int xsize, unsigned int ysize, char **dict));
103 TERM_PUBLIC void NEXT_init __PROTO((void));
104 TERM_PUBLIC void NEXT_graphics __PROTO((void));
105 TERM_PUBLIC void NEXT_text __PROTO((void));
106 TERM_PUBLIC void NEXT_reset __PROTO((void));
107 TERM_PUBLIC void NEXT_linetype __PROTO((int linetype));
108 TERM_PUBLIC void NEXT_move __PROTO((unsigned int x, unsigned int y));
109 TERM_PUBLIC void NEXT_vector __PROTO((unsigned int x, unsigned int y));
110 TERM_PUBLIC void NEXT_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
111 TERM_PUBLIC int NEXT_text_angle __PROTO((int ang));
112 TERM_PUBLIC int NEXT_justify_text __PROTO((enum JUSTIFY mode));
113 TERM_PUBLIC void NEXT_point __PROTO((unsigned int x, unsigned int y, int number));
114 TERM_PUBLIC int NEXT_set_font __PROTO((const char *font));
115 TERM_PUBLIC char *NEXT_RememberFont __PROTO((char *fname));
116 TERM_PUBLIC void NEXT_set_pointsize __PROTO((double size));
119 #define NEXT_POINT_TYPES 8 /* div */
120 #define NEXT_XOFF 1 /* page offset in pts */
122 #define NEXT_XMAX 6400
123 #define NEXT_YMAX 4800
124 #define NEXT_XLAST (NEXT_XMAX - 1)
125 #define NEXT_YLAST (NEXT_YMAX - 1)
126 #define NEXT_VTIC (NEXT_YMAX/80)
127 #define NEXT_HTIC (NEXT_YMAX/80)
128 #define NEXT_SC (10) /* scale is 1pt = 10 units */
129 #define NEXT_LW (0.5*NEXT_SC) /* linewidth = 0.5 pts */
130 #define NEXT_VCHAR (14*NEXT_SC) /* default is 14 point characters */
131 #define NEXT_HCHAR (14*NEXT_SC*6/10)
133 #define GOT_NEXT_PROTO
137 #ifndef TERM_PROTO_ONLY
141 @interface GnuTermDriver:NSObject
146 - (void)senderIsInvalid:(NSNotification *)sender;
147 - (void)plot:(char *)PSstr;
152 #define DEFAULTNEXTSIZE 10000
154 static NSAutoreleasePool *arpool; /* our autorelease pool */
155 static id gnuTermAccess; /* local object manages the D.O. connection */
157 static char *NEXTBuffer, *NEXTBufAt, *NEXTBufEnd;
159 static char NEXTTmpBuf[1000];
160 static void NEXTPrintf(char *,...);
161 static TBOOLEAN NEXT_oldterminal = FALSE;
162 /*static TBOOLEAN NEXT_colordetect();*/
164 static char NEXT_title[MAX_LINE_LEN + 1]; /* name of font */
166 static char NEXT_font[MAX_LINE_LEN + 1] = "Helvetica"; /* name of font */
167 static int NEXT_fontsize = 14; /* size of font in pts */
168 static int NEXT_default_font[MAX_ID_LEN+1] = {'\0'};
169 static TBOOLEAN NEXT_color = FALSE;
170 static TBOOLEAN NEXT_solid = FALSE; /* use dashed lines */
171 static int NEXT_path_count = 0; /* count of lines in path */
172 static int NEXT_ang = 0; /* text angle */
173 static enum JUSTIFY NEXT_justify = LEFT; /* text is flush left */
175 static TBOOLEAN NEXT_duplex_state = FALSE;
176 static TBOOLEAN NEXT_duplex_option = FALSE;
178 static char GPFAR *GPFAR NEXT_header[] =
180 "/M {moveto} bind def\n",
181 "/L {lineto} bind def\n",
182 "/R {rmoveto} bind def\n",
183 "/V {rlineto} bind def\n",
184 "/vpt2 vpt 2 mul def\n",
185 "/hpt2 hpt 2 mul def\n",
186 /* flush left show */
187 "/Lshow { currentpoint stroke M\n",
188 " 0 vshift R show } def\n",
189 /* flush right show */
190 "/Rshow { currentpoint stroke M\n",
191 " dup stringwidth pop neg vshift R show } def\n",
193 "/Cshow { currentpoint stroke M\n",
194 " dup stringwidth pop -2 div vshift R show } def\n",
195 /* Dash or Color Line */
196 "/DL { Color {setrgbcolor Solid {pop []} if 0 setdash }\n",
197 " {pop pop pop Solid {pop []} if 0 setdash} ifelse } def\n",
199 "/BL { stroke gnulinewidth 2 mul setlinewidth } def\n",
201 "/AL { stroke gnulinewidth 2 div setlinewidth } def\n",
203 "/PL { stroke gnulinewidth setlinewidth } def\n",
205 "/LTb { BL [] 0 0 0 DL } def\n", /* border */
206 "/LTa { AL [1 dl 2 dl] 0 setdash 0 0 0 setrgbcolor } def\n", /* axes */
207 "/LT0 { PL [] 0 1 0 DL } def\n",
208 "/LT1 { PL [4 dl 2 dl] 0 0 1 DL } def\n",
209 "/LT2 { PL [2 dl 3 dl] 1 0 0 DL } def\n",
210 "/LT3 { PL [1 dl 1.5 dl] 1 0 1 DL } def\n",
211 "/LT4 { PL [5 dl 2 dl 1 dl 2 dl] 0 1 1 DL } def\n",
212 "/LT5 { PL [4 dl 3 dl 1 dl 3 dl] 1 1 0 DL } def\n",
213 "/LT6 { PL [2 dl 2 dl 2 dl 4 dl] 0 0 0 DL } def\n",
214 "/LT7 { PL [2 dl 2 dl 2 dl 2 dl 2 dl 4 dl] 1 0.3 0 DL } def\n",
215 "/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",
216 /* Point (Round) */ /* Matt Heffron make it round */
217 "/Pnt { stroke [] 0 setdash\n",
218 " gsave 1 setlinecap M 0 0 V stroke grestore } def\n",
221 "/Dia { stroke [] 0 setdash 2 copy vpt add M\n",
222 " hpt neg vpt neg V hpt vpt neg V\n",
223 " hpt vpt V hpt neg vpt V closepath stroke\n",
227 "/Pls { stroke [] 0 setdash vpt sub M 0 vpt2 V\n",
228 " currentpoint stroke M\n",
229 " hpt neg vpt neg R hpt2 0 V stroke\n",
233 "/Box { stroke [] 0 setdash 2 copy exch hpt sub exch vpt add M\n",
234 " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
235 " hpt2 neg 0 V closepath stroke\n",
239 "/Crs { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
240 " hpt2 vpt2 neg V currentpoint stroke M\n",
241 " hpt2 neg 0 R hpt2 vpt2 V stroke } def\n",
244 "/TriU { stroke [] 0 setdash 2 copy vpt 1.12 mul add M\n",
245 " hpt neg vpt -1.62 mul V\n",
247 " hpt neg vpt 1.62 mul V closepath stroke\n",
251 "/Star { 2 copy Pls Crs } def\n",
253 /* div added filed box */
255 "/BoxF { stroke [] 0 setdash exch hpt sub exch vpt add M\n",
256 " 0 vpt2 neg V hpt2 0 V 0 vpt2 V\n",
257 " hpt2 neg 0 V closepath fill } def\n",
259 /* div added filled triangle */
260 /* Triangle Up, Filled */
261 "/TriUF { stroke [] 0 setdash vpt 1.12 mul add M\n",
262 " hpt neg vpt -1.62 mul V\n",
264 " hpt neg vpt 1.62 mul V closepath fill } def\n",
266 /* Matt Heffron: added a few more types */
268 "/TriD { stroke [] 0 setdash 2 copy vpt 1.12 mul sub M\n",
269 " hpt neg vpt 1.62 mul V\n",
271 " hpt neg vpt -1.62 mul V closepath stroke\n",
274 /* Triangle Down, Filled*/
275 "/TriDF { stroke [] 0 setdash vpt 1.12 mul sub M\n",
276 " hpt neg vpt 1.62 mul V\n",
278 " hpt neg vpt -1.62 mul V closepath fill} def\n",
280 /* Diamond, Filled */
281 "/DiaF { stroke [] 0 setdash vpt add M\n",
282 " hpt neg vpt neg V hpt vpt neg V\n",
283 " hpt vpt V hpt neg vpt V closepath fill } def\n",
286 "/Pent { stroke [] 0 setdash 2 copy gsave\n",
287 " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
288 " closepath stroke grestore Pnt } def\n",
290 /* Pentagon, Filled */
291 "/PentF { stroke [] 0 setdash gsave\n",
292 " translate 0 hpt M 4 {72 rotate 0 hpt L} repeat\n",
293 " closepath fill grestore } def\n",
296 "/Circle { stroke [] 0 setdash 2 copy\n",
297 " hpt 0 360 arc stroke Pnt } def\n",
300 "/CircleF { stroke [] 0 setdash hpt 0 360 arc fill } def\n",
301 /* 16 differently filled circles */
302 "/C0 { BL [] 0 setdash 2 copy moveto vpt 90 450 arc } bind def\n",
303 "/C1 { BL [] 0 setdash 2 copy moveto\n",
304 " 2 copy vpt 0 90 arc closepath fill\n",
305 " vpt 0 360 arc closepath } bind def\n",
306 "/C2 { BL [] 0 setdash 2 copy moveto\n",
307 " 2 copy vpt 90 180 arc closepath fill\n",
308 " vpt 0 360 arc closepath } bind def\n",
309 "/C3 { BL [] 0 setdash 2 copy moveto\n",
310 " 2 copy vpt 0 180 arc closepath fill\n",
311 " vpt 0 360 arc closepath } bind def\n",
312 "/C4 { BL [] 0 setdash 2 copy moveto\n",
313 " 2 copy vpt 180 270 arc closepath fill\n",
314 " vpt 0 360 arc closepath } bind def\n",
315 "/C5 { BL [] 0 setdash 2 copy moveto\n",
316 " 2 copy vpt 0 90 arc\n",
318 " 2 copy vpt 180 270 arc closepath fill\n",
319 " vpt 0 360 arc } bind def\n",
320 "/C6 { BL [] 0 setdash 2 copy moveto\n",
321 " 2 copy vpt 90 270 arc closepath fill\n",
322 " vpt 0 360 arc closepath } bind def\n",
323 "/C7 { BL [] 0 setdash 2 copy moveto\n",
324 " 2 copy vpt 0 270 arc closepath fill\n",
325 " vpt 0 360 arc closepath } bind def\n",
326 "/C8 { BL [] 0 setdash 2 copy moveto\n",
327 " 2 copy vpt 270 360 arc closepath fill\n",
328 " vpt 0 360 arc closepath } bind def\n",
329 "/C9 { BL [] 0 setdash 2 copy moveto\n",
330 " 2 copy vpt 270 450 arc closepath fill\n",
331 " vpt 0 360 arc closepath } bind def\n",
332 "/C10 { BL [] 0 setdash 2 copy 2 copy moveto vpt 270 360 arc closepath fill\n",
334 " 2 copy vpt 90 180 arc closepath fill\n",
335 " vpt 0 360 arc closepath } bind def\n",
336 "/C11 { BL [] 0 setdash 2 copy moveto\n",
337 " 2 copy vpt 0 90 arc closepath fill\n",
339 " 2 copy vpt 180 360 arc closepath fill\n",
340 " vpt 0 360 arc closepath } bind def\n",
341 "/C12 { BL [] 0 setdash 2 copy moveto\n",
342 " 2 copy vpt 180 360 arc closepath fill\n",
343 " vpt 0 360 arc closepath } bind def\n",
344 "/C13 { BL [] 0 setdash 2 copy moveto\n",
345 " 2 copy vpt 0 90 arc closepath fill\n",
347 " 2 copy vpt 180 360 arc closepath fill\n",
348 " vpt 0 360 arc closepath } bind def\n",
349 "/C14 { BL [] 0 setdash 2 copy moveto\n",
350 " 2 copy vpt 90 360 arc closepath fill\n",
351 " vpt 0 360 arc } bind def\n",
352 "/C15 { BL [] 0 setdash 2 copy vpt 0 360 arc closepath fill\n",
353 " vpt 0 360 arc closepath } bind def\n",
355 /* Auxiliary definitions for rectangles */
357 "/Rec { newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n",
358 " neg 0 rlineto closepath } bind def\n",
359 "/Square { dup Rec } bind def\n",
360 "/Bsquare { vpt sub exch vpt sub exch vpt2 Square } bind def\n",
362 /* 16 differently filled squares */
364 "/S0 { BL [] 0 setdash 2 copy moveto 0 vpt rlineto BL Bsquare } bind def\n",
365 "/S1 { BL [] 0 setdash 2 copy vpt Square fill Bsquare } bind def\n",
366 "/S2 { BL [] 0 setdash 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
367 "/S3 { BL [] 0 setdash 2 copy exch vpt sub exch vpt2 vpt Rec fill Bsquare } bind def\n",
368 "/S4 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
369 "/S5 { BL [] 0 setdash 2 copy 2 copy vpt Square fill\n",
370 " exch vpt sub exch vpt sub vpt Square fill Bsquare } bind def\n",
371 "/S6 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
372 "/S7 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt vpt2 Rec fill\n",
373 " 2 copy vpt Square fill\n",
374 " Bsquare } bind def\n",
375 "/S8 { BL [] 0 setdash 2 copy vpt sub vpt Square fill Bsquare } bind def\n",
376 "/S9 { BL [] 0 setdash 2 copy vpt sub vpt vpt2 Rec fill Bsquare } bind def\n",
377 "/S10 { BL [] 0 setdash 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt Square fill\n",
378 " Bsquare } bind def\n",
379 "/S11 { 2 copy vpt sub vpt Square fill 2 copy exch vpt sub exch vpt2 vpt Rec fill\n",
380 " Bsquare } bind def\n",
381 "/S12 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill Bsquare } bind def\n",
382 "/S13 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
383 " 2 copy vpt Square fill Bsquare } bind def\n",
384 "/S14 { BL [] 0 setdash 2 copy exch vpt sub exch vpt sub vpt2 vpt Rec fill\n",
385 " 2 copy exch vpt sub exch vpt Square fill Bsquare } bind def\n",
386 "/S15 { BL [] 0 setdash 2 copy Bsquare fill Bsquare } bind def\n",
388 /* 16 different diamonds (actually just rotated squares) */
390 "/D0 { gsave translate 45 rotate 0 0 Box stroke grestore } bind def\n",
391 "/D1 { gsave translate 45 rotate 0 0 S1 stroke grestore } bind def\n",
392 "/D2 { gsave translate 45 rotate 0 0 S2 stroke grestore } bind def\n",
393 "/D3 { gsave translate 45 rotate 0 0 S3 stroke grestore } bind def\n",
394 "/D4 { gsave translate 45 rotate 0 0 S4 stroke grestore } bind def\n",
395 "/D5 { gsave translate 45 rotate 0 0 S5 stroke grestore } bind def\n",
396 "/D6 { gsave translate 45 rotate 0 0 S6 stroke grestore } bind def\n",
397 "/D7 { gsave translate 45 rotate 0 0 S7 stroke grestore } bind def\n",
398 "/D8 { gsave translate 45 rotate 0 0 S8 stroke grestore } bind def\n",
399 "/D9 { gsave translate 45 rotate 0 0 S9 stroke grestore } bind def\n",
400 "/D10 { gsave translate 45 rotate 0 0 S10 stroke grestore } bind def\n",
401 "/D11 { gsave translate 45 rotate 0 0 S11 stroke grestore } bind def\n",
402 "/D12 { gsave translate 45 rotate 0 0 S12 stroke grestore } bind def\n",
403 "/D13 { gsave translate 45 rotate 0 0 S13 stroke grestore } bind def\n",
404 "/D14 { gsave translate 45 rotate 0 0 S14 stroke grestore } bind def\n",
405 "/D15 { gsave translate 45 rotate 0 0 S15 stroke grestore } bind def\n",
410 static char GPFAR *GPFAR ENHNEXT_header[] =
412 /* For MFshow and MFwidth the tos is an array with the string and font info: */
413 /* [<fontname (a string)> <fontsize> <vertical offset> <width significant?> <text string>] */
415 "/MFshow {{dup dup 0 get findfont exch 1 get scalefont setfont\n",
416 " [ currentpoint ] exch dup 2 get 0 exch rmoveto dup 4 get show dup\n",
417 " 3 get {2 get neg 0 exch rmoveto pop} {pop aload pop moveto}ifelse} forall} bind def\n",
418 "/MFwidth {0 exch {dup 3 get{dup dup 0 get findfont exch 1 get scalefont setfont\n",
419 " 4 get stringwidth pop add}\n",
420 " {pop} ifelse} forall} bind def\n",
422 /* flush left show */
423 "/MLshow { currentpoint stroke M\n",
424 " 0 exch R MFshow } bind def\n",
426 /* flush right show */
427 "/MRshow { currentpoint stroke M\n",
428 " exch dup MFwidth neg 3 -1 roll R MFshow } def\n",
431 "/MCshow { currentpoint stroke M\n",
432 " exch dup MFwidth -2 div 3 -1 roll R MFshow } def\n",
436 /* added to post by Matt Heffron <heffron@falstaff.css.beckman.com> */
437 /* moved to post.trm by drd */
439 struct NEXT_FontName {
441 struct NEXT_FontName *next;
442 } *NEXT_DocFonts = NULL;
445 NEXT_DEFAULT, NEXT_MONOCHROME, NEXT_COLOR,
446 NEXT_SOLID, NEXT_DASHED,
447 NEXT_SIMPLEX, NEXT_DUPLEX, NEXT_DEFAULTPLEX,
448 NEXT_OLD, NEXT_NEW, NEXT_TITLE,
452 static struct gen_table NEXT_opts[] =
454 { "d$efault", NEXT_DEFAULT },
455 { "mono$chrome", NEXT_MONOCHROME },
456 { "col$or", NEXT_COLOR },
457 { "col$our", NEXT_COLOR },
458 { "so$lid", NEXT_SOLID },
459 { "da$shed", NEXT_DASHED },
460 { "si$mplex", NEXT_SIMPLEX },
461 { "du$plex", NEXT_DUPLEX },
462 { "defaultp$lex", NEXT_DEFAULTPLEX },
465 { "ti$tle", NEXT_TITLE },
475 while (!END_OF_COMMAND) {
476 switch(lookup_table(&NEXT_opts[0],c_token)) {
478 NEXT_oldterminal = FALSE;
479 /*NEXT_color=NEXT_colordetect(); */
482 NEXT_duplex_option = FALSE;
483 strcpy(NEXT_font, "Helvetica");
485 term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
486 term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
487 term->put_text = NEXT_put_text;
490 case NEXT_MONOCHROME:
507 NEXT_duplex_state = FALSE;
508 NEXT_duplex_option = TRUE;
512 NEXT_duplex_state = TRUE;
513 NEXT_duplex_option = TRUE;
516 case NEXT_DEFAULTPLEX:
517 NEXT_duplex_option = FALSE;
521 NEXT_oldterminal = TRUE;
525 NEXT_oldterminal = FALSE;
530 if (!isstring(c_token)) {
531 fprintf(stderr, "usage: set term openstep title \"newtitle\"\n");
533 quote_str(NEXT_title, c_token, MAX_LINE_LEN + 1);
537 if (isstring(c_token)) {
538 quote_str(NEXT_font, c_token, MAX_LINE_LEN + 1);
540 /* We must have font size specified */
541 NEXT_fontsize = (int) real(const_express(&a));
542 term->v_char = (unsigned int) (NEXT_fontsize * NEXT_SC);
543 term->h_char = (unsigned int) (NEXT_fontsize * NEXT_SC * 6 / 10);
544 sprintf(NEXT_default_font, "%s,%d", NEXT_font, NEXT_fontsize);
550 sprintf(term_options, "%s %s %s %s \"%s\" %d title \"%s\"",
551 NEXT_oldterminal ? "old" : "new",
552 NEXT_color ? "color" : "monochrome",
553 NEXT_solid ? "solid" : "dashed",
554 NEXT_duplex_option ? (NEXT_duplex_state ? "duplex" : "simplex")
563 NEXT_RememberFont(char *fname)
565 struct NEXT_FontName *fnp;
567 for (fnp = NEXT_DocFonts; fnp && strcmp(fnp->name, fname); fnp = fnp->next);
569 return fnp->name; /* we must have found it in the list */
571 if (encoding == S_ENC_ISO8859_1) {
572 NEXTPrintf("/%s reencodeISO def\n", fname);
574 fnp = (struct NEXT_FontName *) gp_alloc(sizeof(struct NEXT_FontName), "PostScript Font record");
575 fnp->name = gp_alloc(1 + strlen(fname), "PostScript Font name");
576 strcpy(fnp->name, fname);
577 fnp->next = NEXT_DocFonts;
582 int NEXT_pen_x, NEXT_pen_y;
584 int NEXT_linetype_last;
585 TBOOLEAN NEXT_relative_ok;
588 /* store settings passed to common_init() for use in NEXT_graphics()
589 * are reserved for storing the term options
591 static int NEXT_common_uses_fonts;
592 static unsigned int NEXT_common_xoff, NEXT_common_yoff;
597 int uses_fonts, /* 0 for NEXT(la)tex */
598 unsigned int xoff, unsigned int yoff, /* offset - 50 for /post, 0 for NEXT(la)tex */
599 unsigned int width, unsigned int height, /* for bounding box */
600 char **dict) /* extra entries for the dictionary */
602 static char GPFAR NEXTi1[] = "%%%%Creator: gnuplot\n\
603 %%%%DocumentFonts: %s\n";
604 static char GPFAR NEXTi2[] = "%%%%EndComments\n\
605 /gnudict 120 dict def\ngnudict begin\n\
608 /gnulinewidth %.3f def\n\
613 static char GPFAR *NEXT_iso_8859_1_encoding[] =
616 "dup dup findfont dup length dict begin\n",
617 "{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n",
618 "/Encoding ISOLatin1Encoding def\n",
619 "currentdict end definefont\n",
621 "/ISOLatin1Encoding [\n",
622 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
623 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
624 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
625 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
626 "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n",
627 "/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n",
628 "/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n",
629 "/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n",
630 "/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n",
631 "/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n",
632 "/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde\n",
633 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
634 "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n",
635 "/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve\n",
636 "/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut\n",
637 "/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar\n",
638 "/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot\n",
639 "/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior\n",
640 "/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine\n",
641 "/guillemotright/onequarter/onehalf/threequarters/questiondown\n",
642 "/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla\n",
643 "/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n",
644 "/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n",
645 "/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute\n",
646 "/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n",
647 "/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave\n",
648 "/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex\n",
649 "/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n",
650 "/yacute/thorn/ydieresis\n",
655 struct termentry *t = term;
658 NEXT_common_uses_fonts = uses_fonts;
659 NEXT_common_xoff = xoff;
660 NEXT_common_yoff = yoff;
663 NEXTPrintf("%%!NEXT-Adobe-2.0\n");
665 NEXTPrintf(NEXTi1, uses_fonts ? "(atend)" : "");
667 NEXTPrintf("%%%%BoundingBox: %d %d %d %d\n", xoff, yoff,
668 (int) (xsize * width / NEXT_SC + 0.5 + xoff),
669 (int) (ysize * height / NEXT_SC + 0.5 + yoff));
672 NEXT_color ? "true" : "false",
673 NEXT_solid ? "true" : "false",
674 NEXT_LW, /* line width */
675 (int) (t->v_char) / (-3), /* shift for vertical centring */
676 NEXT_SC, /* dash length */
677 NEXT_HTIC / 2.0, /* half point width */
678 NEXT_VTIC / 2.0); /* half point height */
680 if (uses_fonts && (encoding == S_ENC_ISO8859_1)) {
681 for (i = 0; NEXT_iso_8859_1_encoding[i] != NULL; i++) {
682 NEXTPrintf("%s", NEXT_iso_8859_1_encoding[i]);
685 for (i = 0; NEXT_header[i] != NULL; i++)
686 NEXTPrintf("%s", NEXT_header[i]);
687 if (NEXT_duplex_option)
688 NEXTPrintf("statusdict begin %s setduplexmode end\n",
689 NEXT_duplex_state ? "true" : "false");
690 NEXT_RememberFont(NEXT_font);
694 NEXTPrintf("%s", *(dict++));
696 NEXTPrintf("end\n%%%%EndProlog\n");
699 /* the init fn for the NeXT Terminal driver */
703 /* is this called more than once? */
704 arpool = [[NSAutoreleasePool alloc] init];
706 /* Initialize output string */
707 NEXTsize = DEFAULTNEXTSIZE;
708 if ((NEXTBuffer = malloc(NEXTsize)) == NULL) {
709 printf("Malloc error in openstep filter init\n");
712 NEXTBufEnd = NEXTBuffer + NEXTsize;
713 NEXTBufAt = NEXTBuffer;
716 term->xmax = NEXT_XMAX;
717 term->ymax = NEXT_YMAX;
719 gnuTermAccess = [[GnuTermDriver alloc] init];
720 /* [gnuTermAccess retain]; -- since we hold it privately. */
727 static char GPFAR NEXTg1[] = "0 setgray\nnewpath\n";
728 struct termentry *t = term;
731 NEXTBufAt = NEXTBuffer;
733 NEXT_common_init(1, NEXT_XOFF, NEXT_YOFF, term->xmax, term->ymax,
736 NEXTPrintf("gnudict begin\ngsave\n");
737 NEXTPrintf("%d %d translate\n", NEXT_common_xoff, NEXT_common_yoff);
738 NEXTPrintf("%.3f %.3f scale\n", 1.0 / NEXT_SC, 1.0 / NEXT_SC);
742 if (NEXT_common_uses_fonts)
743 NEXTPrintf("(%s) findfont %d scalefont setfont\n", NEXT_font, (t->v_char));
745 NEXT_relative_ok = FALSE;
746 NEXT_pen_x = NEXT_pen_y = -4000;
748 NEXT_linetype_last = LT_UNDEFINED;
752 TERM_PUBLIC voidNEXT_text()
757 NEXTPrintf("stroke\ngrestore\nend\n");
759 /* Terminate string */
762 if (NEXT_oldterminal) {
763 d = DPSGetCurrentContext();
764 DPSPrintf(d, NEXTBuffer);
768 /* Here's the call that dumps the string to the server */
769 [gnuTermAccess plot:NEXTBuffer];
777 NEXTPrintf("%%%%Trailer\n");
778 if (!NEXT_common_uses_fonts) {
779 NEXTPrintf("%%%%DocumentFonts: ");
780 while (NEXT_DocFonts) {
781 struct NEXT_FontName *fnp;
782 fnp = NEXT_DocFonts->next;
783 NEXTPrintf("%s%s", NEXT_DocFonts->name, fnp ? ", " : "\n");
784 free(NEXT_DocFonts->name);
793 NEXT_linetype(int linetype)
795 linetype = (linetype % 9) + 2;
798 NEXT_relative_ok = FALSE;
799 if (NEXT_linetype_last == linetype)
801 NEXT_linetype_last = linetype;
802 NEXTPrintf("LT%c\n", "ba012345678"[linetype]);
808 NEXT_move(unsigned int x, unsigned int y)
811 char abso[20], rel[20];
814 /* can't cancel all null moves--need a move after stroke'ing */
815 if (dx == 0 && dy == 0 && NEXT_relative_ok)
817 sprintf(abso, "%d %d M\n", x, y);
818 sprintf(rel, "%d %d R\n", dx, dy);
819 if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
820 NEXTPrintf("%s", rel);
823 NEXTPrintf("%s", abso);
824 NEXT_relative_ok = TRUE;
825 NEXT_path_count += 1;
832 NEXT_vector(unsigned int x, unsigned int y)
835 char abso[20], rel[20];
838 if (dx == 0 && dy == 0)
840 sprintf(abso, "%d %d L\n", x, y);
841 sprintf(rel, "%d %d V\n", dx, dy);
842 if (strlen(rel) < strlen(abso) && NEXT_relative_ok) {
843 NEXTPrintf("%s", rel);
846 NEXTPrintf("%s", abso);
847 NEXT_relative_ok = TRUE;
848 NEXT_path_count += 1;
851 if (NEXT_path_count >= 400) {
852 NEXTPrintf("currentpoint stroke M\n");
861 NEXT_text_angle(int ang)
869 NEXT_justify_text(enum JUSTIFY mode)
877 NEXT_set_font(const char *font)
882 if (!font || !(*font))
883 font = NEXT_default_font;
884 sep = strcspn(font, ",");
885 strncpy(name, font, sep);
887 size = NEXT_fontsize;
888 if (font[sep] == ',')
889 sscanf(&(font[sep + 1]), "%d", &size);
890 NEXTPrintf("/%s findfont %d scalefont setfont\n", name, size * NEXT_SC);
891 NEXT_RememberFont(name);
892 term->v_char = (unsigned int) (size * NEXT_SC);
893 term->h_char = (unsigned int) (size * NEXT_SC * 6 / 10);
898 /* postscript point routines */
901 NEXT_set_pointsize(double size)
903 NEXTPrintf("/vpt %.1f def /hpt %.1f def /vpt2 vpt 2 mul def /hpt2 hpt 2 mul def\n",
904 pointsize * NEXT_VTIC * 0.5, pointsize * NEXT_HTIC * 0.5);
908 NEXT_point(unsigned int x, unsigned int y, int number)
910 static char *pointFNS[] =
911 {"Pnt", "Pls", "Crs", "Star",
912 "Box", "BoxF", "Circle", "CircleF",
913 "TriU", "TriUF", "TriD", "TriDF",
914 "Dia", "DiaF", "Pent", "PentF",
915 "C0", "C1", "C2", "C3",
916 "C4", "C5", "C6", "C7",
917 "C8", "C9", "C10", "C11",
918 "C12", "C13", "C14", "C15",
919 "S0", "S1", "S2", "S3",
920 "S4", "S5", "S6", "S7",
921 "S8", "S9", "S10", "S11",
922 "S12", "S13", "S14", "S15",
923 "D0", "D1", "D2", "D3",
924 "D4", "D5", "D6", "D7",
925 "D8", "D9", "D10", "D11",
926 "D12", "D13", "D14", "D15"
929 number = -1; /* negative types are all 'dot' */
931 number %= sizeof(pointFNS) / sizeof(pointFNS[0]) - 1;
932 NEXTPrintf("%d %d %s\n", x, y, pointFNS[number + 1]);
934 NEXT_relative_ok = 0;
936 NEXT_linetype_last = LT_UNDEFINED; /* force next linetype change */
939 /* All lifted from the enhanced postscript driver */
941 static TBOOLEAN NEXT_opened_string; /* try to cut out empty ()'s */
943 /* used in determining height of processed text */
945 static float NEXT_max_height, NEXT_min_height;
948 /* process a bit of string, and return the last character used.
949 * p is start of string
950 * brace is TRUE to keep processing to }, FALSE for do one character
951 * fontname & fontsize are obvious
952 * base is the current baseline
953 * widthflag is TRUE if the width of this should count,
954 * FALSE for zero width boxes
962 double fontsize, double basem,
966 /* close a postscript string if it has been opened */
968 { if (NEXT_opened_string) \
969 { NEXTPrintf("%s", ")]\n"); \
970 NEXT_opened_string = FALSE; \
975 { if (!NEXT_opened_string) \
976 { NEXTPrintf( "[(%s) %.1f %.1f %s (", \
977 fontname, fontsize, base, \
978 widthflag ? "true" : "false"); \
979 NEXT_opened_string = TRUE; \
984 /* Start each recursion with a clean string */
987 if (base + fontsize > NEXT_max_height) {
988 NEXT_max_height = base + fontsize;
990 if (base < NEXT_min_height) {
991 NEXT_min_height = base;
995 float f = 0; /* used for getting new font size */
996 char *localfontname, ch;
1003 fprintf(stderr, "openstep driver - spurious }\n");
1008 shift = (*p == '^') ? 0.5 : -0.3;
1012 p = NEXT_recurse(p + 1, FALSE, fontname, fontsize * 0.8, base + shift * fontsize, widthflag);
1017 /*{{{ recurse (possibly with a new font) */
1019 if (*++p == '/') { /* then parse a fontname, optional fontsize */
1020 while (*++p == ' ');
1022 while ((ch = *p) > ' ' && ch != '=')
1026 /*{{{ get optional font size */
1027 f = (float) strtod(p, &p);
1030 f *= NEXT_SC; /* remember the scaling */
1043 localfontname = NEXT_RememberFont(localfontname);
1045 localfontname = fontname;
1047 localfontname = fontname;
1053 p = NEXT_recurse(p, TRUE, localfontname, f, base, widthflag);
1061 /*{{{ phantom box - prints next 'char', then restores currentpoint */
1065 p = NEXT_recurse(++p, FALSE, fontname, fontsize, base, FALSE);
1075 NEXTPrintf("%c", *p);
1080 /*{{{ is it an escape */
1083 if (p[1] == '\\' || p[1] == '(' || p[1] == ')') {
1085 NEXTPrintf("%c", '\\');
1086 } else if ((ch = p[1]) >= '0' && ch <= '7') {
1087 /* up to 3 octal digits */
1089 NEXTPrintf("%c", '\\');
1090 NEXTPrintf("%c", ch);
1092 if ((ch = p[1]) >= '0' && ch <= '7') {
1093 NEXTPrintf("%c", ch);
1095 if ((ch = p[1]) >= '0' && ch <= '7') {
1096 NEXTPrintf("%c", ch);
1103 /* just go and print it (fall into the 'default' case) */
1109 NEXTPrintf("%c", *p);
1112 /* like TeX, we only do one character in a recursion, unless it's
1118 return (p); /* the ++p in the outer copy will increment us */
1127 NEXT_put_text(unsigned int x, unsigned int y, const char *str)
1129 /* flush any pending graphics (all the XShow routines do this...) */
1134 if (NEXT_path_count) {
1135 NEXTPrintf(" stroke\n");
1136 NEXT_path_count = 0;
1137 NEXT_relative_ok = FALSE;
1142 NEXTPrintf("currentpoint gsave translate %d rotate 0 0 moveto\n",
1147 /* set up the globals */
1149 NEXT_opened_string = FALSE;
1150 NEXT_max_height = -1000;
1151 NEXT_min_height = 1000;
1153 while (*(str = NEXT_recurse(str, TRUE, NEXT_font,
1154 (double) term->v_char,
1157 NEXT_max_height += NEXT_min_height;
1159 NEXTPrintf("] %.1f ", -NEXT_max_height / 3);
1161 switch (NEXT_justify) {
1163 NEXTPrintf("MLshow\n");
1166 NEXTPrintf("MCshow\n");
1169 NEXTPrintf("MRshow\n");
1174 NEXTPrintf("grestore\n");
1175 NEXT_path_count = 0;
1176 NEXT_relative_ok = FALSE;
1185 NXScreen * mainscreen;
1187 mainscreen = [Application mainScreen];
1188 if (mainscreen->depth == NX_TwoBitGrayDepth) return(FALSE);
1193 /* This just packs all the postscript into one (possibly huge) string
1194 * which will be passed (as a fake pointer) via D.O. to the server
1198 NEXTPrintf(char *fmt,...)
1204 /* Process formatting instructions */
1206 vsprintf(NEXTTmpBuf, fmt, ap);
1210 for (pb = NEXTTmpBuf; (*pb != 0); ++pb, ++NEXTBufAt) {
1211 /* reallocate if necessary */
1212 if (NEXTBufAt >= NEXTBufEnd) {
1213 NEXToff = NEXTBufAt - NEXTBuffer;
1215 NEXTBuffer = realloc(NEXTBuffer, NEXTsize);
1216 NEXTBufEnd = NEXTBuffer + NEXTsize;
1217 NEXTBufAt = NEXTBuffer + NEXToff;
1226 /* This next section implements the GnuTermDriver object which manages
1227 the D.O. connection and interface to Obj-C
1231 @protocol GnuTermServerMethods
1232 /*- (oneway) executePScode:(in char *)PStext termTitle:(in char *)title;*/
1233 - (void) executePScode:(NSString *) PStext termTitle:(NSString *) title;
1237 @implementation GnuTermDriver
1241 NSConnection *myConnection;
1242 char serverpath[100], *envstring;
1243 int GnuTermPathSet = 0;
1246 /* Ask OS for connection to server */
1247 server = [NSConnection rootProxyForConnectionWithRegisteredName: @"gnuplotServer" host:nil];
1251 /* Server is running ready to go */
1252 if (server) printf("Connected to server\n")
1255 /* Server isn't running, we must fire it up */
1257 printf("Launching GnuTerm\n");
1260 /* Check for path set in environment */
1261 if ((envstring = getenv("GNUTERMPATH")) != (char *) NULL) {
1262 sprintf(serverpath, "%s/GnuTerm.app/GnuTerm", envstring);
1265 /* Not in environment */
1267 strcpy(serverpath, "GnuTerm");
1269 /* Try to launch application */
1270 if ([[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithCString:serverpath]] == NO) {
1271 printf("Failed to launch %s.\n", serverpath);
1272 /* Offer a little advice */
1273 if (GnuTermPathSet) {
1274 printf("You must have setenv GNUTERMPATH to something wrong\n");
1275 printf("I recommend you exit gnuplot and fix this.\n");
1277 printf("It must be located in ~/Apps or /LocalApps\n");
1278 printf("I recommend that you either\n");
1279 printf("- move GnuTerm.app to one of these locations\n");
1280 printf("- set GNUTERMPATH with host%% setenv GNUTERMPATH /directory/containing_GnuTerm.app\n");
1281 printf("- start GnuTerm ahead of the first plot command\n");
1284 /* I wish the gnuplot terminal interface would
1285 let me return an error here.
1288 /* Application is launching */
1290 /* Wait for it to register Server methods with OS */
1292 server =[[NSConnection
1293 rootProxyForConnectionWithRegisteredName: @"gnuplotServer" host:nil] retain];
1294 } while (!server); /* This could result in a hang,
1295 but I've never seen it fail */
1300 /* By limiting ourselves to known protocol
1301 * we speed up the messaging
1303 [server setProtocolForProxy:@protocol(GnuTermServerMethods)];
1305 myConnection = [server connectionForProxy];
1307 /* If the server dies we want to know about it */
1308 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(senderIsInvalid:) name:NSConnectionDidDieNotification object:myConnection];
1309 /* In fact, we'll worry about it */
1316 - (void) plot:(char *)PSstr;
1318 /* If server has become invalid, re-initialize */
1322 /* This is where we send the huge postscript string to the server
1324 The D.O. system doesn't actually give this pointer to the server.
1325 The pointer is dereferenced on the client side and the
1326 resulting data is sent to the server. On the server side,
1327 space for the data is automatically allocated, and a pointer to
1328 the local data is received.
1329 For details check out:
1330 /NextLibrary/Documentation/NextDev/GeneralRef/06_DistributedObjects/IntroDistObjects.rtf
1333 printf("Calling server...");
1334 [server executePScode: [NSString stringWithCString: PSstr]
1335 termTitle: [NSString stringWithCString: NEXT_title]];
1336 printf("returned\n");
1340 /* This gets called by OS if server goes down */
1341 - (void) senderIsInvalid: (NSNotification *) sender
1350 #endif /* TERM_BODY */
1355 TERM_TABLE_START(openstep_driver)
1357 "Interface to GnuTerm.app under OpenStep",
1358 NEXT_XMAX, NEXT_YMAX, NEXT_VCHAR, NEXT_HCHAR,
1359 NEXT_VTIC, NEXT_HTIC, NEXT_options, NEXT_init, NEXT_reset,
1360 NEXT_text, null_scale, NEXT_graphics, NEXT_move, NEXT_vector,
1361 NEXT_linetype, NEXT_put_text, NEXT_text_angle,
1362 NEXT_justify_text, NEXT_point, do_arrow, NEXT_set_font,
1364 TERM_TABLE_END(openstep_driver)
1367 #define LAST_TERM openstep_driver
1369 #endif /* TERM_TABLE */
1370 #endif /* TERM_PROTO_ONLY */
1375 START_HELP(openstep)
1376 "1 Openstep (next)",
1377 #ifndef TERM_HELP_OPENSTEP
1378 "?commands set terminal openstep",
1379 "?set terminal openstep",
1380 "?set term openstep",
1381 "?terminal openstep",
1391 " Several options may be set in the openstep (next) driver.",
1394 " set terminal openstep {<mode>} {<type> } {<color>} {<dashed>}",
1395 " {\"<fontname>\"} {<fontsize>} title {\"<newtitle>\"}",
1397 " where <mode> is `default`, which sets all options to their defaults;",
1398 " <type> is either `new` or `old`, where `old` invokes the old single window;",
1399 " <color> is either `color` or `monochrome`;",
1400 " <dashed> is either `solid` or `dashed`;",
1401 " \"<fontname>\" is the name of a valid PostScript font;",
1402 " <fontsize> is the size of the font in PostScript points; and",
1403 " <title> is the title for the GnuTerm window.",
1404 " Defaults are `new`, `monochrome`, `dashed`, \"Helvetica\", 14pt.",
1407 " set term openstep default",
1408 " set term openstep 22",
1409 " set term openstep color \"Times-Roman\" 14",
1410 " set term openstep color \"Helvetica\" 12 title \"MyPlot\"",
1411 " set term openstep old",
1413 " Pointsizes may be changed with `set linestyle`."
1415 #endif /* TERM_HELP */