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