[BACK]Return to openstep.trm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / term

Annotation of OpenXM_contrib/gnuplot/term/openstep.trm, Revision 1.1.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>