#define VERSION "2.1" /* don't touch this */ #define VDATE "December 13, 1992" /* Name: vs2ps --------------------------------------------------------------------------- Purpose: --------------------------------------------------------------------------- To produce a PostScript file containing one of the following: 1. a contour plot of data defined on a two-dimensional "rectangular" grid and/or a line drawing of this grid. Input data is given in a single HDF file. 2. a contour plot of data defined on a two-dimensional "curvilinear" grid and/or a line drawing of this grid. Input data is given by two regular HDF files (grid only) or three HDF files (contour plot and/or grid). 3. a contour plot of data defined on a two-dimensional "finite element" grid consisting of triangles and/or quadrangles. Also a line drawing of the vertex set can be produced. Input data is given in a single HDF Vset file. --------- floating point data | | contour plot and/or line (single HDF Vset file ---> | vs2ps | ------> drawing of grid or two/three HDF files | | (PostScript file) or single HDF file) --------- Presently, only float32 data and coordinates are supported. Connectivity lists must have the type int16 or int32. The main advantages of this tool are (I think): a. The contouring algorithm rules out an artificial directional bias by a special "saddle point" strategy. Especially sharp/steep "ridges" in the data (not aligned with the grid) are handled more accurate than usual for linear methods. Don't expect miracles from a linear technique though. b. Contourplots of data defined on curvilinear or finite element grids are generated directly from this grid/data. No artificial interpolation to an intermediate rectangular grid is used. c. The output (Encapsulated) PostScript file can be edited with Adobe's Illustrator 3. Direct routing to a PostScript printer is possible also. --------------------------------------------------------------------------- Source Availability: --------------------------------------------------------------------------- This software was developed and made available by: Fred Walsteijn Institute for Marine and Atmospheric Research Utrecht University Princetonplein 5 3584 CC Utrecht The Netherlands E-mail: walsteyn@fys.ruu.nl You are free to use this software, however all commercial rights are reserved by Fred Walsteijn. This software may not be sold or distributed for profit, or included with other software which is sold or distributed for profit without the prior permission of the author Fred Walsteijn. HDF and HDF Vset file format and interface developed at the National Center for Supercomputing Applications at the University of Illinois at Urbana-Champaign. FRED WALSTEIJN AND THE UNIVERSITIES OF ILLINOIS AND UTRECHT GIVE NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. --------------------------------------------------------------------------- Syntax: --------------------------------------------------------------------------- Read the source of function usage(), or compile this tool and execute it without arguments. --------------------------------------------------------------------------- Implementation Notes -1- : --------------------------------------------------------------------------- The interpretation of the scale arrays in a common HDF file (to be used for generation of a rectangular grid) is ambiguous. vs2ps follows the interpretation as made in other NCSA tools if the -asris option is used, i.e. element data[0,0] is plotted in the upper left corner of the raster. Otherwise in the *lower* left corner, which is the natural way IMHO. Usage of the BEGIN_LN macro may result in compiler warnings. You should ignore these. Here is a list of preprocessor constants which modify the behaviour of vs2ps. Use them in the C compile command/Makefile if necessary: -DAI3BUG -------- This affects the output only if both options -vs and -grid are used. The closepath-and-stroke PostScript macro ('s') as defined in the Adobe resources (version 1.1 and 3.0) is not handled correctly by Illustrator 3.0: for each vertex set triangle/quadrangle drawn the closing line segment generated by Illustrator is a strange Bezier curve which gobbles up the last straight line segment plotted. Therefore the preprocessor macros PLOT_TRIANGLE and PLOT_QUADRANGLE given below should explicitly draw three resp four line segments if Illustrator readable/editable PostScript is wanted. This is done if you define AI3BUG at compile time. Even if you leave AI3BUG undefined the output files contain correct PostScript and print OK. Also, without -DAI3BUG, Aldus Freehand 2.02 correctly reads/edits an Illustrator 1.1 version of the file (if its creator is set to 'ARTY') ! -DNO_VSET --------- If NO_VSET is defined the Vset functions are not accessed: then only curvilinear data can be used as input. Useful on systems where the Vset library functions are not implemented but the regular HDF functions are. -DPRE_C89 --------- Some compilers cannot handle "const void *" casts. For these you should define PRE_C89: then a "void *" cast is used instead. -DUNIX ------ If UNIX is defined then statements are enabled which determine the login name of the user. This is used in the %%For line of the PostScript output file. -DDEBUGGING ----------- Writes some uninteresting info to stdout. Don't enable it. -DRESOURCES_FROM_FILE --------------------- Get Illustrator resource defs from the file 'Adobe_resources'. By default the resources are included in vs2ps itself. Don't define this constant. -DMAC, -DMPW ------------ On the Mac, vs2ps does some handy things: sets the output file type/creator to that of Adobe Illustrator-3; rotates the cursor; does some necessary segmentation; puts your Chooser-name in the %%For line of the output file. --------------------------------------------------------------------------- Implementation Notes -2- : --------------------------------------------------------------------------- VSsizeof() is used to distinguish "int16" from "int32" connectivity lists. The total vdata element size returned in arg vsize by VSinquire() includes the size of other fields if present. Therefore the conn list element size cannot be obtained from VSinquire() in general. VSsizeof() is also used to verify that only float32 input is present. --------------------------------------------------------------------------- "To do": --------------------------------------------------------------------------- 1. True line clipping (=expensive) instead of PS clip (=easy, but expensive ---and yieds large files---if only a tiny part of domain is visualized). 2. (vset_)contour: a. Handle non-convex quadrangles correctly (test as in vs2ris). b. New option -accu -> subdivides each quad into 4 tri. Then saddle points coinciding with gridlines contoured most accurate. Leads to huge output files ! 3. (vset_)labels: Labeling with values not implemented. 4. captions: Centering of text strings instead of flush-left. 5. (rect_,curvi_)grid: -iskip, -jskip options not implemented. 6. captions, inittext, centertext: Check if PS output needs polishing. Options -fontsize -labelfontsize ? -> then automatic fontsize-dependent (Hor & Vert) centering needed also ! 7. Allow specification of different penwidths for grid/boundary/contours. 8. Option -verbose: write contour levels and CI to stdout. 9. Option -zero Draw contours with value>val in black; other contours in grey. This needs another contouring order: loop over contour value instead of over grid-cells. 10. Use something better than VSsizeof() to determine the integral type of the connectivity lists and float sizes in read_vset(). 11. Include support for float64 scales, data, ...; and other ints too ? --------------------------------------------------------------------------- Limitations & Bugs & ...: --------------------------------------------------------------------------- 1. The -vs option combined with -grid yields a PostScript file which is read incorrectly by Illustrator 3.0 (= Illustrator bug !?). See "Implementation Notes". File prints OK. Workaround is -DAI3BUG. 2. Labeling of Vsets (option -labels) and drawing of Vset boundaries (option -boundary ) are correct only if each vertex occurs only once in the vdatas, i.e. if indices are unique. See vset_boundary(), vset_labels(). 3. Plateaux are not labeled. If you encounter a bug, report it to: Fred Walsteijn walsteyn@fys.ruu.nl --------------------------------------------------------------------------- History: --------------------------------------------------------------------------- Oct 5, 1991 -- last development version Oct 23, 1991 -- second beta version Nov 1, 1991 -- declaration of connectivity lists modified: now runs on Cray Mar 4, 1992 -- missing SET_GREYs inserted in rect_grid(), curvi_grid(), vset_grid() Apr 20, 1992 -- every strcpy() replaced by pointer assignment: fixes problems with long pathnames/args. FNAME_MAX removed; STR_MAX replaced by "vg.h" constants. Mac cursor now rotates. NO_VSET, AI3BUG introduced. Jul 18, 1992 -- parse_cmd() does more checks. Bug fixes in rotate(), read_rect(), read_crv(), read_vset(): fixes problems if -nocontour is combined with -values or -labels (``nobody'' does that...). Sep 24, 1992 -- vs2ps now interfaces to NCSA's HDF 3.2r1 library. Dec 13, 1992 -- vs2ps now interfaces to NCSA's HDF 3.2r2 library; read_vset(): uses Vinitialize(), Vfinish(), DFACC_READ; checks float size with VSsizeof(); read_rect(), read_crv(): check float size with DFSDgetNT(). (by Fred Walsteijn -- walsteyn@fys.ruu.nl) */ /* ---------------------------- includes --------------------------- */ #include #include #include #include #include #include #ifdef NO_VSET #include "hdf.h" #else #include "vg.h" #endif #include "dfsd.h" #if ( defined(MAC) && defined(MPW) ) #include /* InitCursorCtl(), RotateCursor() */ #endif /* ---------------------------- macros --------------------------- */ #undef malloc #undef free /* ^ the NCSA def of free(p) for the Mac fails if p==NULL */ #define DATA(i,j) *(in.data + (i)*in.dim1 + (j)) #define X(i,j) *(in.x + (i)*in.dim1 + (j)) #define Y(i,j) *(in.y + (i)*in.dim1 + (j)) /* These macros are efficient for complex args. * Calling routines should define float32 tmp. */ #define ROUNDUP( x ) ( tmp=(x), tmp<0? (int32)tmp :(int32)tmp+1 ) #define ROUNDDOWN( x ) ( tmp=(x), tmp<0? (int32)tmp-1 :(int32)tmp ) #define SMALL 0.001 /* Needed to avoid rounding problems */ /* These min/max macros are efficient only if invoked with simple first args * (second may be complex): */ #define MIN(a,b) ( tmp=(b), (a)tmp?(a):tmp ) /* These min/max macros should only be invoked with simple args: */ #define MIN2(a,b) ( (a)<(b)?(a):(b) ) #define MAX2(a,b) ( (a)>(b)?(a):(b) ) #define MIN3(a,b,c) ( (a)<(b)? MIN2(a,c) : MIN2(b,c) ) #define MAX3(a,b,c) ( (a)>(b)? MAX2(a,c) : MAX2(b,c) ) #define MIN4(a,b,c,d) ( (a)<(b)? \ ((a)<(c)? ((a)<(d)?(a):(d)) : ((c)<(d)?(c):(d)) ) \ : \ ((b)<(c)? ((b)<(d)?(b):(d)) : ((c)<(d)?(c):(d)) ) ) #define MAX4(a,b,c,d) ( (a)>(b)? \ ((a)>(c)? ((a)>(d)?(a):(d)) : ((c)>(d)?(c):(d)) ) \ : \ ((b)>(c)? ((b)>(d)?(b):(d)) : ((c)>(d)?(c):(d)) ) ) /* ---------------------------- types, consts --------------------------- */ #define CMAX 10 /* maximum number of connectivity lists to look for */ #undef FALSE #undef TRUE #undef RECT #undef CRV #undef VSET #undef INT16TYPE #undef INT32TYPE enum boolean { FALSE, TRUE }; enum filetype { RECT, CRV, VSET }; /* input file(s) type: RECT==1*HDF, CRV==3*HDF, VSET==1*HDF_Vset */ enum elmtype { INT16TYPE, INT32TYPE }; /* integral type of HDF Vset connectivity lists */ struct Box { int32 xlo, xhi, ylo, yhi; /* bounding box in integer default PS coords */ }; /* * structure definition for the input data */ struct Input { enum filetype ftyp; /* ftyp == RECT then rectangular grid/data (from single HDF file) ftyp == CRV then curvilinear grid/data (from two/three HDF files) ftyp == VSET then vertex set (from single HDF Vset file) */ int32 dim0, dim1; /* input dimensions - ncols, nrows; RECT and CRV only */ float32 *x, /* horizontal coords of vertices */ *y, /* vertical coords of vertices */ *data; /* vertex data values */ /* RECT: x[dim0], y[dim1], data[dim0][dim1] * CRV: x[dim0][dim1], y[dim0][dim1], data[dim0][dim1] * VSET: x[nv], y[nv], data[nv] */ int32 nv, /* number of vertices, VSET only */ ntri, nquad; /* number of triangles, quadrangles in (s)plist3, (s)plist4 */ enum elmtype etyp3, /* etyp3 == INT16TYPE then triangles in splist3; otherwise plist3 */ etyp4; /* etyp4 == INT16TYPE then quadrangles in splist4; otherwise plist4 */ int32 *plist3, *plist4; /* pointers to int32 connectivity lists */ int16 *splist3, *splist4; /* pointers to int16 connectivity lists */ }; /* * structure definition for command line options */ struct Options { char *infile, /* input rect-data or curvi-scalar HDF file name || input HDF Vset file name */ *gridx, *gridy, /* input curvi-coordinate HDF file names, CRV only */ *outfile; /* output PostScript file name */ FILE *psfile; /* output file pointer */ int32 ncon; /* number of connectivity lists specified, VSET only */ char *groupname, *pxname, *pyname, *connectname[CMAX], *scalarname; /* vgroup name and vdata field names to use, VSET only */ enum boolean domain, /* spatial (x,y-) domain is specified */ asris, /* put SDS[0][0] in upper left corner, RECT only */ minmax, /* datamin and datamax specified, contour==TRUE only */ ratio, /* output domain ratio of PostScript output is specified */ connect, /* connectivity list(s) was specified by user */ contour, /* generate contour plot */ grid, /* generate line drawing of grid */ boundary, /* draw boundary in contourplot */ labels, /* draw 'L','H'-label at local min,max in contourplot */ values, /* draw value-label at local extremes in contourplot */ threshold, /* threshold values for labeling specified by user */ caption; /* draw caption strings & box around line drawing/contourplot */ char *topstring, *botstring; /* caption strings */ int32 ncontours, /* number of contourlevels to plot */ iskip, jskip; /* number of gridlines to skip in grid linedrawing */ float32 grid_grey, /* PostScript greylevel of grid line drawing */ boun_grey; /* PostScript greylevel of boundary line drawing */ float32 xmin, xmax, ymin, ymax, /* domain geometry if domain==TRUE */ ydivx, /* requested domain ratio if ratio==TRUE */ min_threshold, max_threshold, /* thresholds for contour labeling */ scalefactor; /* multiplicative scalefactor for values to be plotted at extremes */ }; /* ---------------------------- globals --------------------------- */ float32 datamin, datamax; /* selected data range */ struct Box bound, /* union of plot,tops,bots: == PostScript %%BoundingBox */ plot, /* plot domain BB */ tops, /* topstring BB */ bots; /* botstring BB */ /* ---------------------------- prototypes --------------------------- */ void quit( char *msg ); void clear( struct Input *in, struct Options *opt ); void atexit_free( struct Input *in ); void free_mem( void ); void usage( char *tool ); void parse_cmd( int argc, char *argv[], struct Input *in, struct Options *opt ); #ifdef DEBUGGING void write_opt( struct Options opt ); void write_in( struct Input in ); #endif void rotate( struct Input *in, struct Options *opt ); void read_rect( struct Input *in, struct Options *opt ); void read_crv( struct Input *in, struct Options *opt ); void read_vset( struct Input *in, struct Options *opt ); void gminmax( float32 *xmin, float32 *xmax, float32 *x, int32 dim ); void rect_grid( struct Input in, struct Options opt ); void rect_boundary( struct Input in, struct Options opt ); void curvi_grid( struct Input in, struct Options opt ); void curvi_boundary( struct Input in, struct Options opt ); void contour( struct Input in, struct Options opt ); void vset_grid( struct Input in, struct Options opt ); void vset_contour( struct Input in, struct Options opt ); void vset_boundary( struct Input in, struct Options opt ); int listcomp( int32 a[2], int32 b[2] ); void labels( struct Input in, struct Options opt ); void vset_labels( struct Input in, struct Options opt ); void inittext( FILE *psfile ); void centertext( FILE *psfile, float32 x, float32 y, char *text ); void pshead( struct Options opt ); void pstail( struct Options opt ); void captions( struct Options opt ); void beginobject( FILE *psfile, char *objname ); void endobject( FILE *psfile ); void ps_coords( struct Input in, struct Options opt ); void adobe( FILE *psfile ); void adobe_part1( FILE *psfile ); void adobe_part2( FILE *psfile ); /* --------------------------------------------------------------------------- HDF 3.2r2 prototypes // function result --------------------------------------------------------------------------- In "hdf.h": #define SUCCEED 0 #define FAIL (-1) In "vg.h": typedef int32 HFILEID; --------------------------------------------------------------------------- hproto.h <- hdf.h <- vg.h --------------------------------------------------------------------------- int32 Hopen (char *path, intn access, int16 ndds); // FAIL, file_id intn Hclose (int32 file_id); // FAIL, SUCCEED --------------------------------------------------------------------------- dfsd.h --------------------------------------------------------------------------- int DFSDgetdims (char *filename, intn *prank, int32 sizes[], intn maxrank); // FAIL, SUCCEED int DFSDgetrange (void *pmax, void *pmin); // FAIL || -1, 0 int DFSDgetdata (char *filename, intn rank, int32 maxsizes[], void *data); // FAIL, SUCCEED int DFSDgetdimscale (int dim, int32 maxsize, void *scale); // FAIL || -1, 0 int DFSDgetNT(int32 *pnumbertype); // FAIL, 0 --------------------------------------------------------------------------- *VSET* vproto.h <- vg.h --------------------------------------------------------------------------- void Vinitialize(HFILEID f); void Vfinish(HFILEID f); VGROUP *Vattach (HFILEID f, int32 vgid, char *accesstype); // NULL, ptr void Vdetach (VGROUP *vg); void Vgetname (VGROUP *vg, char *vgname); int32 Visvs (VGROUP *vg, int32 id); // 0, 1 (=="id refers to vdata") int32 Vgetid (HFILEID f, int32 vgid); // FAIL, >=0 (==id of next vgroup) int32 Vgetnext (VGROUP *vg, int32 id); // FAIL, >=0 (==id of next entry) VDATA * VSattach (HFILEID f, int32 vsid, char *accesstype); // NULL, ptr void VSdetach (VDATA *vs); int32 VSread (VDATA *vs, BYTE buf[], int32 nelt, int32 interlace); // FAIL, >=0 (==nr elems read) int32 VSfexist (VDATA *vs, char *fields); // FAIL, 1 int32 VSinquire (VDATA *vs,int32 *nelt, int32 *interlace, char *fields, int32 *eltsize, char *vsname); // FAIL, SUCCEED int32 VSsetfields (VDATA *vs, char *fields); // FAIL, SUCCEED int32 VSsizeof (VDATA *vs, char *fields); // FAIL, >0 (==fieldssize) --------------------------------------------------------------------------- */ /************************************************************************************************* * main: Read a rectangular grid/data from a single HDF file, or a curvilinear grid/data * * ---- from two/three HDF input files, or a finite element grid from a single HDF Vset file. * * Write a contourplot of the data and/or a line drawing of the grid to a PostScript file. * *************************************************************************************************/ main( int argc, char *argv[] ) { static struct Input in; /* rectangular, curvilinear, or vset input data */ struct Options opt; /* command line options */ #if ( defined(MAC) && defined(MPW) ) InitCursorCtl(NULL); RotateCursor(32); #endif clear( &in, &opt ); /* set all fields to 0, NULL, ... */ atexit_free( &in ); /* remember to free malloc-ed stuff */ parse_cmd( argc, argv, &in, &opt ); /* get switches, filenames, ... */ #ifdef DEBUGGING write_opt( opt ); #endif if ( in.ftyp == RECT ) read_rect( &in, &opt ); /* read 1 HDF file */ else if ( in.ftyp == CRV ) read_crv( &in, &opt ); /* read 2/3 HDF files */ else if ( in.ftyp == VSET ) read_vset( &in, &opt ); /* read single HDF Vset file */ else quit("main: Internal error: unknown 'in.ftyp' value."); ps_coords( in, opt ); /* scale the input grid coords to output PS coordinate system */ pshead( opt ); /* write header of PS file: comment, prolog, setup sections including caption strings if requested */ if ( opt.grid == TRUE ) /* generate linedrawing of grid */ { beginobject( opt.psfile, "Grid Line Drawing" ); if ( in.ftyp == RECT ) rect_grid( in, opt ); else if ( in.ftyp == CRV ) curvi_grid( in, opt ); else if ( in.ftyp == VSET ) vset_grid( in, opt ); endobject( opt.psfile ); } if ( opt.contour == TRUE ) /* generate contourplot of data */ { beginobject( opt.psfile, "Contour Plot" ); if ( in.ftyp == RECT ) contour( in, opt ); else if ( in.ftyp == CRV ) contour( in, opt ); else if ( in.ftyp == VSET ) vset_contour( in, opt ); endobject( opt.psfile ); } if ( opt.boundary == TRUE ) /* draw boundary of domain */ { beginobject( opt.psfile, "Grid Boundary Line Drawing" ); if ( in.ftyp == RECT ) rect_boundary( in, opt ); else if ( in.ftyp == CRV ) curvi_boundary( in, opt ); else if ( in.ftyp == VSET ) vset_boundary( in, opt ); endobject( opt.psfile ); } if ( opt.labels == TRUE || opt.values == TRUE ) /* label maxima and minima of contourplot */ { beginobject( opt.psfile, "Contour Labels" ); if ( in.ftyp == RECT ) labels( in, opt ); else if ( in.ftyp == CRV ) labels( in, opt ); else if ( in.ftyp == VSET ) vset_labels( in, opt ); endobject( opt.psfile ); } pstail( opt ); /* write trailer of PostScript file, and close it */ #ifdef DEBUGGING write_in( in ); #endif return 0; } /**************************************************** * quit: Write message and terminate program. * ****************************************************/ void quit( char *msg ) { printf("%s\n", msg ); exit(EXIT_FAILURE); } /******************************************************* * clear: Sets struct fields and globals to 'zero'. * *******************************************************/ void clear( struct Input *in, struct Options *opt ) { in->ftyp = CRV; in->x = in->y = in->data = NULL; in->plist3 = in->plist4 = NULL; in->splist3 = in->splist4 = NULL; in->etyp3 = in->etyp4 = INT16TYPE; in->dim0 = in->dim1 = in->ntri = in->nquad = in->nv = 0; opt->psfile = NULL; opt->topstring = opt->botstring = "*EMPTY*"; opt->infile = opt->gridx = opt->gridy = opt->outfile = ""; opt->scalefactor = opt->xmin = opt->xmax = opt->ymin = opt->ymax = opt->ydivx = opt->min_threshold = opt->max_threshold = 0.0; } /**************************************************************************** * atexit_free: Store pointers to struct which will contain malloc-ed * * data. By an atexit() call these data will automatically * * be free-ed on exit. * ****************************************************************************/ /* Global for atexit_free() and free_mem(): */ struct Input *ptr_in; void atexit_free( struct Input *in ) { extern struct Input *ptr_in; ptr_in = in; if ( 0 != atexit( free_mem ) ) quit("atexit_free: atexit() failed."); } /************************************************************************** * free_mem: Free malloc-ed stuff. * * ASSUMES: every pointer has been malloc-ed, or equals NULL. * **************************************************************************/ void free_mem( void ) { extern struct Input *ptr_in; free( (void *) ptr_in->data ); free( (void *) ptr_in->y ); free( (void *) ptr_in->x ); free( (void *) ptr_in->splist3 ); free( (void *) ptr_in->plist3 ); free( (void *) ptr_in->splist4 ); free( (void *) ptr_in->plist4 ); } /*************************************************************** * usage: Give command line syntax and terminate program. * ***************************************************************/ void usage( char *tool ) { printf( "\n\n"); printf( "This is vs2ps (version: %s, dated: %s).\n", VERSION, VDATE ); printf( "Generates a PostScript contourplot of float32 data defined on a two-dimensional\n"); printf( "finite element, curvilinear, or rectangular grid and/or a line drawing of the grid.\n"); printf( "By: Fred Walsteijn, Utrecht University, The Netherlands (walsteyn@fys.ruu.nl)\n\n"); printf( "SYNTAX:\n" ); printf( " %s -vs \n", tool ); printf( " -o [OPTIONS ...] [VS-OPTIONS ...]\n\n" ); printf( "OR:\n" ); printf( " %s -crv2 \n", tool ); printf( " -o [OPTIONS ...] [CR-OPTIONS ...]\n\n" ); printf( "OR:\n" ); printf( " %s -crv \n", tool ); printf( " -o [OPTIONS ...] [CR-OPTIONS ...]\n\n" ); printf( "OR:\n" ); printf( " %s -rect \n", tool ); printf( " -o [OPTIONS ...] [CR-OPTIONS ...] [-asris]\n\n" ); printf( "where:\n" ); printf( " -vs \n" ); printf( " Input HDF Vset file containing 2-D vertex grid & data.\n" ); printf( " -crv2 \n" ); printf( " Two HDF input files specifying a curvilinear 2-D grid.\n" ); printf( " The first file contains a single SDS describing the x coordinates,\n" ); printf( " the second file specifies the y coordinates of the gridpoints.\n" ); printf( " -crv \n" ); printf( " Three HDF input files specifying data on a curvilinear 2-D grid.\n" ); printf( " Each file contains a single SDS describing respectively the data values,\n" ); printf( " x coordinates, and y coordinates of the gridpoints.\n" ); printf( " -rect \n" ); printf( " Single HDF input file specifying data on a 2-D rectangular grid.\n" ); printf( " If scale arrays are present these are used to define the rectangular grid.\n" ); printf( " -asris\n" ); printf( " Always put first element of -rect SDS in upper left corner, as in NCSA tools\n"); printf( " generating a RIS. Default: interpret scale arrays as true x,y coords.\n" ); printf( " -o \n" ); printf( " PostScript output file containing contour plot and/or grid line drawing.\n" ); printf( "OPTIONS:\n" ); printf( " -domain \n" ); printf( " Specifies the domain part to be visualized. Allows zooming in/out.\n" ); printf( " Also determines the output line drawing aspect ratio if this\n" ); printf( " ratio is not set explicitly using the option -ratio.\n" ); printf( " Default: min/max of coordinates in input file(s).\n" ); printf( " -ratio \n" ); printf( " Ratio of output plot domain/line drawing. Default: (ymax-ymin)/(xmax-xmin).\n" ); printf( " -range \n" ); printf( " Minimum resp maximum contour level. Default: min/max of input data.\n" ); printf( " -boundary | -noboundary\n" ); printf( " Draw grid boundary with PostScript greylevel | do not draw it.\n" ); printf( " Default: -boundary 0.0 (=black).\n" ); printf( " -grid | -nogrid\n" ); printf( " Draw grid with PostScript greylevel | do not draw it.\n" ); printf( " Default: for the -crv2 option: -grid 0.0 (=black), otherwise -nogrid.\n" ); printf( " -contour | -nocontour\n" ); printf( " Draw 'ncontours' contours | do not generate contour plot.\n" ); printf( " Default: the -crv2 option always implies -nocontour, otherwise -contour 11\n" ); printf( " -labels\n" ); printf( " Put labels 'L', 'H' at local minima, maxima outside the threshold-range.\n" ); printf( " -values \n" ); printf( " -threshold \n" ); printf( " The threshold floats are used to determine if an extremum is to be labeled.\n" ); printf( " Default: datamin+0.3*(datamax-datamin), datamin+0.7*(datamax-datamin)\n" ); printf( " -caption \n" ); printf( " Puts plot in box with a string above and below it.\n\n" ); printf( "CR-OPTIONS:\n" ); printf( " -iskip \n" ); printf( " -jskip \n" ); printf( " Number of gridlines to skip. Default: -iskip 0 -jskip 0\n\n" ); printf( "VS-OPTIONS:\n" ); printf( " -group \n" ); printf( " Name of vgroup in the Vset input file to read the vertex vdata(s)\n" ); printf( " from. Default: the first vgroup encountered in the Vset file.\n" ); printf( " -px \n" ); printf( " Name of vdata field containing x coords. Default: 'px'.\n" ); printf( " -py \n" ); printf( " Name of vdata field containing y coords. Default: 'py'.\n" ); printf( " { -connect } ...\n" ); printf( " Name(s) of vdata field(s) containing a triangle and/or quadrangle\n" ); printf( " connectivity list of type int16 or int32. Each field name must be\n" ); printf( " preceded by the flag -connect. From the specified connectivity\n" ); printf( " lists only the first two of different type encountered in the\n" ); printf( " Vset file are read: one list of triangles and/or a list of\n" ); printf( " quadrangles, which may contain triangles also (as in PolyView\n" ); printf( " the 4th vertex id should be zero). Other field names are skipped.\n" ); printf( " Default: -connect plist -connect plist3 -connect plist4\n" ); printf( " -scalar \n" ); printf( " Name of vdata field containing scalar values. Default: 'scalar'.\n\n" ); printf( "NOTE: all options may be specified in an arbitrary order.\n\n" ); exit(EXIT_FAILURE); } /********************************************************* * parse_cmd: Parse the command line. Defines: * * opt: ALL fields, * * in: ftyp field only. * * globals: datamin, datamax. * *********************************************************/ void parse_cmd( int argc, char *argv[], struct Input *in, struct Options *opt ) { enum boolean is_rect, is_crv, is_crv2, is_vs, outp; /* mandatory switches */ int i; /* argv-loop index */ double x0, x1, y0, y1, d0, d1, ydivx; /* for sscanf() */ /* * Option defaults: */ opt->domain = opt->minmax = opt->ratio = opt->connect = opt->grid = opt->asris = opt->values = opt->labels = opt->caption = opt->threshold = FALSE; opt->contour = opt->boundary = TRUE; opt->ncontours = 11; /* odd number so that zero contour will be plotted if datamin == -datamax */ opt->iskip = opt->jskip = 0; /* draw all gridlines */ opt->grid_grey = opt->boun_grey = 0.0; /* PostScript black */ /* * Default vgroup name and vdata fieldnames similar (not identical) to PolyView defaults: */ opt->groupname = ""; /* "the 1st vgroup" */ opt->pxname = "px"; opt->pyname = "py"; opt->scalarname = "scalar"; opt->connectname[0] = "plist"; opt->connectname[1] = "plist3"; opt->connectname[2] = "plist4"; opt->ncon = 0; /* init for loop below; final assignment is done later */ /* * Local var init: */ is_rect = is_crv = is_crv2 = is_vs = outp = FALSE; if (argc<2) usage( argv[0] ); for ( i=1; iinfile = argv[++i]; opt->gridx = argv[++i]; opt->gridy = argv[++i]; } else if ( !strcmp(argv[i],"-crv2") && icontour = FALSE; /* the defaults are */ opt->grid = TRUE; /* different in this case */ opt->gridx = argv[++i]; opt->gridy = argv[++i]; } else if ( !strcmp(argv[i],"-vs") && iinfile = argv[++i]; } else if ( !strcmp(argv[i],"-rect") && iinfile = argv[++i]; } else if ( !strcmp(argv[i],"-o") && ioutfile = argv[++i]; if ( (opt->psfile = fopen( opt->outfile, "w")) == NULL ) quit("parse_cmd: Cannot create PostScript file."); } else if ( !strcmp(argv[i],"-domain") && idomain = TRUE; if ( sscanf(argv[++i], "%lf", &x0) != 1 || sscanf(argv[++i], "%lf", &x1) != 1 || sscanf(argv[++i], "%lf", &y0) != 1 || sscanf(argv[++i], "%lf", &y1) != 1 ) /* more checks below */ quit("parse_cmd: Error in domain spec."); opt->xmin = x0; opt->xmax = x1; opt->ymin = y0; opt->ymax = y1; } else if ( !strcmp(argv[i],"-ratio") && iratio = TRUE; if ( sscanf(argv[++i], "%lf", &ydivx) != 1 ) quit("parse_cmd: Error in ratio spec."); opt->ydivx = ydivx; } else if ( !strcmp(argv[i],"-range") && iminmax = TRUE; if ( sscanf(argv[++i], "%lf", &d0) != 1 || sscanf(argv[++i], "%lf", &d1) != 1 || d0 >= d1 ) quit("parse_cmd: Error in range spec."); datamin = d0; datamax = d1; } else if ( !strcmp(argv[i],"-boundary") && iboundary = TRUE; if ( sscanf(argv[++i], "%lf", &d0) != 1 || d0 < 0.0 || d0 > 1.0 ) quit("parse_cmd: Error in boundary grey level."); opt->boun_grey = d0; } else if ( !strcmp(argv[i],"-noboundary") ) opt->boundary = FALSE; else if ( !strcmp(argv[i],"-grid") && igrid = TRUE; if ( sscanf(argv[++i], "%lf", &d0) != 1 || d0 < 0.0 || d0 > 1.0 ) quit("parse_cmd: Error in grid grey level."); opt->grid_grey = d0; } else if ( !strcmp(argv[i],"-nogrid") ) opt->grid = FALSE; else if ( !strcmp(argv[i],"-contour") && icontour = TRUE; if ( sscanf(argv[++i], "%d", &opt->ncontours) != 1 || opt->ncontours < 1 || opt->ncontours > 1000 ) quit("parse_cmd: Error in contour spec."); } else if ( !strcmp(argv[i],"-nocontour") ) opt->contour = FALSE; else if ( !strcmp(argv[i],"-asris") ) opt->asris = TRUE; else if ( !strcmp(argv[i],"-labels") ) opt->labels = TRUE; else if ( !strcmp(argv[i],"-values") && ivalues = TRUE; if ( sscanf(argv[++i], "%lf", &d0) != 1 || d0 == 0.0 ) quit("parse_cmd: Error in scalefactor spec."); opt->scalefactor = d0; } else if ( !strcmp(argv[i],"-threshold") && ithreshold = TRUE; if ( sscanf(argv[++i], "%lf", &d0) != 1 || sscanf(argv[++i], "%lf", &d1) != 1 || d0 >= d1 ) quit("parse_cmd: Error in threshold spec."); opt->min_threshold = d0; opt->max_threshold = d1; } else if ( !strcmp(argv[i],"-caption") && icaption = TRUE; opt->topstring = argv[++i]; opt->botstring = argv[++i]; } else if ( !strcmp(argv[i],"-iskip") && iiskip) != 1 || opt->iskip < 0 ) quit("parse_cmd: Error in iskip spec."); } else if ( !strcmp(argv[i],"-jskip") && ijskip) != 1 || opt->jskip < 0 ) quit("parse_cmd: Error in jskip spec."); } else if (!strcmp(argv[i],"-group") && igroupname = argv[++i]; else if (!strcmp(argv[i],"-px") && ipxname = argv[++i]; else if (!strcmp(argv[i],"-py") && ipyname = argv[++i]; else if (!strcmp(argv[i],"-scalar") && iscalarname = argv[++i]; else if (!strcmp(argv[i],"-connect") && incon < CMAX ) { opt->connect = TRUE; opt->connectname[opt->ncon++] = argv[++i]; } else { printf("parse_cmd: Unknown flag(s) encountered.\n"); usage( argv[0] ); } } /* * Do final checks on the input: */ if ( outp == FALSE ) quit("parse_cmd: Output file is mandatory. Use option -o.\n"); if ( opt->connect == FALSE ) opt->ncon = 3; /* use the three default connectivity lists */ else if ( opt->ncon > 2 ) printf("parse_cmd: Warning: at most 2 connectivity lists will be used.\n"); if ( is_crv == TRUE ) /* Three straight HDF files specified. */ { if ( is_crv2 == TRUE || is_vs == TRUE || is_rect == TRUE ) quit("parse_cmd: Use only one of -vs, -crv, -crv2, -rect.\n"); in->ftyp = CRV; } else if ( is_crv2 == TRUE ) /* Two straight HDF files specified. */ { if ( is_vs == TRUE || is_rect == TRUE ) quit("parse_cmd: Use only one of -vs, -crv, -crv2, -rect.\n"); in->ftyp = CRV; if ( opt->contour == TRUE || opt->labels == TRUE || opt->values == TRUE ) quit("parse_cmd: You cannot use -contour,-labels,-values with -crv2.\n"); } else if ( is_vs == TRUE ) /* Single HDF Vset file specified. */ { if ( is_rect == TRUE ) quit("parse_cmd: Use only one of -vs, -crv, -crv2, -rect.\n"); in->ftyp = VSET; } else if ( is_rect == TRUE ) /* Single HDF file specified. */ in->ftyp = RECT; else quit("parse_cmd: Input file(s) are mandatory. Use one of -vs, -crv, -crv2, -rect.\n"); if ( opt->domain == TRUE && (in->ftyp != RECT || opt->asris == FALSE) && /* case asris==TRUE: checked in read_rect() */ (opt->xmin >= opt->xmax || opt->ymin >= opt->ymax) ) quit("parse_cmd: Error in domain spec."); if ( opt->threshold == TRUE && opt->values == FALSE && opt->labels == FALSE ) quit("parse_cmd: -threshold is meaningless without either -values or -labels."); if ( opt->grid == FALSE && opt->contour == FALSE && opt->boundary == FALSE && opt->labels == FALSE && opt->values == FALSE && opt->caption == FALSE ) quit("parse_cmd: You disabled all output options."); } #ifdef DEBUGGING /*********************************************************************** * write_opt: Write contents of 'opt' and some global vars to stdout. * * For debugging. * ***********************************************************************/ #define pr_bool( arg ) printf(#arg " = %s\n", (arg==FALSE)?"FALSE":((arg==TRUE)?"TRUE":"*TRASH*") ) #define pr_float( arg ) printf(#arg " = %lf\n", (double)arg ) #define pr_int( arg ) printf(#arg " = %ld\n", (long)arg ) #define pr_string( arg ) printf(#arg " = %s\n", arg ) #define pr_ftyp( arg ) printf(#arg " = %s\n", (arg==RECT)?"RECT":((arg==CRV)?"CRV":((arg==VSET)?"VSET":"*TRASH*")) ) #define pr_etyp( arg ) printf(#arg " = %s\n", (arg==INT16TYPE)?"INT16TYPE":((arg==INT32TYPE)?"INT32TYPE":"*TRASH*") ) void write_opt( struct Options opt ) { int32 i; printf("\n\n"); printf("write_opt: --- globals ---\n"); pr_float( datamin ); pr_float( datamax ); printf("\n\n"); printf("write_opt: --- contents of 'struct Options opt' ---\n"); pr_string( opt.infile ); pr_string( opt.gridx ); pr_string( opt.gridy ); pr_string( opt.outfile ); pr_string( opt.groupname ); pr_string( opt.pxname ); pr_string( opt.pyname ); pr_string( opt.scalarname ); pr_int( opt.ncon ); for (i=0; idata + (newdim1-(j)-1)*newdim0 + (i)) /* == DATA(newdim1-(j)-1,i) */ void rotate( struct Input *in, struct Options *opt ) { float32 *rot, *rotcp, *datcp, *swap, s; int incr; int32 newdim0, newdim1, i, j; if ( in->ftyp != RECT ) quit("rotate: Illegal input data type."); newdim0 = in->dim1; newdim1 = in->dim0; if ( opt->contour == TRUE || opt->values == TRUE || opt->labels == TRUE ) { /* * Step 1: Rotate 'in->data' such that element [0][0] becomes [...][...] */ /* rotation needs temp array: */ if ((rot = (float32 *) malloc((size_t) (in->dim0*in->dim1*sizeof(float32)) )) == NULL) quit("read_rect: Cannot allocate mem for temporary array 'rot'."); rotcp = rot; for ( i=0; idata in rot */ for ( j=0; jdata; for ( i=0; idata */ *datcp++ = *rotcp++; free( (void *) rot ); } in->dim0 = newdim0; in->dim1 = newdim1; /* * Step 2: 'rotate' the scale arrays (exchange them; modify their monotonicity properties) */ /* first, simply swap pointers (dim0 and dim1 fields have been swapped already): */ swap = in->x; in->x = in->y; in->y = swap; /* only the y-scale must be physically 'mirrored': */ for ( j=0; jdim1/2; j++ ) { s = in->y[j]; /* s: swap var */ in->y[j] = in->y[in->dim1-j-1]; in->y[in->dim1-j-1] = s; } /* If either scale array is decreasing with its index, flip its sign such that it will be monotonically increasing. Modify xmin, xmax, ymin, ymax -fields of opt correspondingly: */ incr = in->x[0] < in->x[1]; for ( i=1; idim0-1; i++ ) /* this check should be redundant */ if ( incr != (in->x[i] < in->x[i+1]) ) quit("read_rect: Hor-scale array not strictly monotonic."); if ( !incr ) { for ( i=0; idim0; i++ ) in->x[i] = - in->x[i]; /* now the x-array is monot.increasing */ if ( opt->domain == TRUE ) { opt->xmin = - opt->xmin; opt->xmax = - opt->xmax; } } incr = in->y[0] < in->y[1]; for ( j=1; jdim1-1; j++ ) if ( incr != (in->y[j] < in->y[j+1]) ) quit("read_rect: Vert-scale array not strictly monotonic."); if ( !incr ) { for ( j=0; jdim1; j++ ) in->y[j] = - in->y[j]; if ( opt->domain == TRUE ) { opt->ymin = - opt->ymin; opt->ymax = - opt->ymax; } } } /************************************************************************** * read_rect: Reads rectangular grid from single HDF file containing * * two scale arrays. * **************************************************************************/ void read_rect( struct Input *in, struct Options *opt ) { int rank; int32 hdfdims[2], i, j, numtype; int read_scalar = (opt->contour == TRUE || opt->values == TRUE || opt->labels == TRUE ); /* boolean */ if ( DFSDgetdims(opt->infile, &rank, hdfdims, 2) ) quit("read_rect: Unable to get dimensions from input file."); if (DFSDgetNT(&numtype)==FAIL || numtype!=DFNT_FLOAT32) quit("read_rect: Sorry, I can only read float32 data."); if( rank != 2) quit("read_rect: Invalid array rank in input file."); if ((hdfdims[0] < 2) || (hdfdims[1] < 2)) quit("read_rect: Dimension(s) less than '2' in input file."); in->dim0 = hdfdims[0]; in->dim1 = hdfdims[1]; if ( read_scalar && opt->minmax == FALSE && !DFSDgetrange(&datamax, &datamin) && datamax > datamin) opt->minmax = TRUE; if ((in->x = (float32 *) malloc((size_t) (in->dim0*sizeof(float32)) )) == NULL || (in->y = (float32 *) malloc((size_t) (in->dim1*sizeof(float32)) )) == NULL || read_scalar && (in->data = (float32 *) malloc((size_t) (in->dim0*in->dim1*sizeof(float32)) )) == NULL) quit("read_rect: Cannot allocate mem for scale arrays and/or data."); if (DFSDgetdimscale(1, in->dim0, in->x) || DFSDgetdimscale(2, in->dim1, in->y) ) { printf("read_rect: Warning: Unable to get TWO scale arrays from input file. Using equidistant scales instead." ); for ( i=0; idim0; i++ ) in->x[i] = i; for ( j=0; jdim1; j++ ) in->y[j] = j; } if ( read_scalar ) { if ( DFSDgetdata(opt->infile, 2, hdfdims, in->data) ) quit("read_rect: Unable to get SDS from input file." ); if ( opt->minmax == FALSE ) gminmax( &datamin, &datamax, in->data, in->dim0*in->dim1 ); if (datamin >= datamax) quit("read_rect: Data max/min err."); if ( opt->threshold == FALSE ) { opt->min_threshold = datamin + 0.3*(datamax-datamin); opt->max_threshold = datamin + (1-0.3)*(datamax-datamin); } } if ( opt->asris == TRUE ) /* ensures that contourplot/griddrawing has orientation */ rotate( in, opt ); /* of NCSA-RIS output */ if ( opt->domain == FALSE ) { gminmax( &opt->xmin, &opt->xmax, in->x, in->dim0 ); gminmax( &opt->ymin, &opt->ymax, in->y, in->dim1 ); } if (opt->xmin >= opt->xmax || opt->ymin >= opt->ymax) quit("read_rect: Domain spec err."); if ( opt->ratio == FALSE ) opt->ydivx = (opt->ymax - opt->ymin) / (opt->xmax - opt->xmin); if ( opt->ydivx < 1E-3 || opt->ydivx > 1E3) quit("read_rect: Ratio too small/large."); } /*********************************************************************************** * read_crv: Reads curvilinear data from two/three straight HDF files containing * * one SDS each: data and/or gridx, gridy. * ***********************************************************************************/ void read_crv( struct Input *in, struct Options *opt ) { int rank; int32 hdfdims[2], numtype; int read_scalar = (opt->contour == TRUE || opt->values == TRUE || opt->labels == TRUE ); /* boolean */ if ( DFSDgetdims(opt->gridx, &rank, hdfdims, 2) ) quit("read_crv: Unable to get dimensions from gridx file."); if (DFSDgetNT(&numtype)==FAIL || numtype!=DFNT_FLOAT32) quit("read_crv: Sorry, I can only read float32 gridx-data."); if( rank != 2) quit("read_crv: Invalid array rank in gridx file."); if ((hdfdims[0] < 2) || (hdfdims[1] < 2)) quit("read_crv: Dimension(s) less than '2' in gridx file."); in->dim0 = hdfdims[0]; in->dim1 = hdfdims[1]; if ( DFSDgetdims(opt->gridy, &rank, hdfdims, 2) || rank != 2 || hdfdims[0] != in->dim0 || hdfdims[1] != in->dim1 ) quit("read_crv: Gridy file incompatible with gridx file."); if (DFSDgetNT(&numtype)==FAIL || numtype!=DFNT_FLOAT32) quit("read_crv: Sorry, I can only read float32 gridy-data."); if ( read_scalar ) { if( DFSDgetdims(opt->infile, &rank, hdfdims, 2) || rank != 2 || hdfdims[0] != in->dim0 || hdfdims[1] != in->dim1 ) quit("read_crv: Data file incompatible with grid files."); if (DFSDgetNT(&numtype)==FAIL || numtype!=DFNT_FLOAT32) quit("read_crv: Sorry, I can only read float32 scalar-data."); if ( opt->minmax == FALSE && !DFSDgetrange(&datamax, &datamin) && datamax > datamin ) opt->minmax = TRUE; } if ((in->x = (float32 *) malloc((size_t) (in->dim0*in->dim1*sizeof(float32)) )) == NULL || (in->y = (float32 *) malloc((size_t) (in->dim0*in->dim1*sizeof(float32)) )) == NULL || read_scalar && (in->data = (float32 *) malloc((size_t) (in->dim0*in->dim1*sizeof(float32)) )) == NULL) quit("read_crv: Cannot allocate mem for grid/data."); if (read_scalar && DFSDgetdata(opt->infile, 2, hdfdims, in->data) || DFSDgetdata(opt->gridx, 2, hdfdims, in->x) || DFSDgetdata(opt->gridy, 2, hdfdims, in->y) ) quit("read_crv: Unable to get SDS from input file(s)." ); if ( opt->domain == FALSE ) { gminmax( &opt->xmin, &opt->xmax, in->x, in->dim0*in->dim1 ); gminmax( &opt->ymin, &opt->ymax, in->y, in->dim0*in->dim1 ); } if ( read_scalar ) { if ( opt->minmax == FALSE ) gminmax( &datamin, &datamax, in->data, in->dim0*in->dim1 ); if ( datamin >= datamax) quit("read_crv: Data max/min err."); if ( opt->threshold == FALSE ) { opt->min_threshold = datamin + 0.3*(datamax-datamin); opt->max_threshold = datamin + (1-0.3)*(datamax-datamin); } } if (opt->xmin >= opt->xmax || opt->ymin >= opt->ymax) quit("read_crv: Domain spec err."); if ( opt->ratio == FALSE ) opt->ydivx = (opt->ymax - opt->ymin) / (opt->xmax - opt->xmin); if ( opt->ydivx < 1E-3 || opt->ydivx > 1E3) quit("read_crv: Ratio too small/large."); } /**************************************************** * read_vset: Read HDF Vset file. * ****************************************************/ #ifdef NO_VSET void read_vset( struct Input *in, struct Options *opt ) { quit("read_vset: Sorry, your system does not support Vset files."); } #else /* NO_VSET */ void read_vset( struct Input *in, struct Options *opt ) { VGROUP *vg; VDATA *vs; int32 f; char vgname[VGNAMELENMAX+1], vsname[VSNAMELENMAX+1], fields[VSFIELDMAX*(FIELDNAMELENMAX+1)]; int32 vgid, vsid; enum boolean found, pxfound, pyfound, scalarfound, connectfound[CMAX], confound, oneconfound, con3found, con4found; int32 i, csize, vsize, interlace, nelements, npx, npy, nscalar; int read_scalar = (opt->contour == TRUE || opt->values == TRUE || opt->labels == TRUE ); /* boolean */ if ( (f = Hopen( opt->infile, DFACC_READ, 0 )) == FAIL) quit("read_vset: Cannot open input file."); Vinitialize(f); /* * Now try to find vgroup with name opt->groupname. * If it equals "" (empty string) then the first vgroup is taken. */ found = FALSE; vgid = -1; while ((vgid = Vgetid(f,vgid)) != FAIL) { if ((vg = Vattach(f, vgid, "r")) != NULL) { Vgetname(vg, vgname); if (strcmp(vgname,opt->groupname) == 0 || strcmp(opt->groupname,"") == 0 ) { found = TRUE; break; } } Vdetach(vg); } if ( found == FALSE ) quit("read_vset: Group not found."); /* * Now scan all the vdatas in the vgroup found. * Read the px, py, connect, scalar fields if encountered. */ pxfound = pyfound = scalarfound = confound = oneconfound = con3found = con4found = FALSE; for (i=0; i 0 ) { #ifdef DEBUGGING printf("vdata %s has %d elements of size %d, and fields %s\n", vsname, nelements, vsize, fields ); #endif if ( pxfound == FALSE && VSfexist(vs, opt->pxname) == 1 && VSsetfields(vs, opt->pxname) == SUCCEED && (csize = VSsizeof(vs, opt->pxname)) > 0) { if ( csize != sizeof(float32) ) quit("read_vset: Sorry, I can only read float32 px-data."); if ((in->x = (float32 *) malloc((size_t) (nelements*sizeof(float32)))) == NULL) quit("read_vset: Cannot allocate mem for px."); VSread(vs, (BYTE *)in->x, nelements, NO_INTERLACE ); pxfound = TRUE; npx = nelements; #ifdef DEBUGGING printf(" px read\n" ); #endif } if ( pyfound == FALSE && VSfexist(vs, opt->pyname) == 1 && VSsetfields(vs, opt->pyname) == SUCCEED && (csize = VSsizeof(vs, opt->pyname)) > 0) { if ( csize != sizeof(float32) ) quit("read_vset: Sorry, I can only read float32 py-data."); if ((in->y = (float32 *) malloc((size_t) (nelements*sizeof(float32)))) == NULL) quit("read_vset: Cannot allocate mem for py."); VSread(vs, (BYTE *)in->y, nelements, NO_INTERLACE ); pyfound = TRUE; npy = nelements; #ifdef DEBUGGING printf(" py read\n" ); #endif } if ( read_scalar && scalarfound == FALSE && VSfexist(vs, opt->scalarname) == 1 && VSsetfields(vs, opt->scalarname) == SUCCEED && (csize = VSsizeof(vs, opt->scalarname)) > 0) { if ( csize != sizeof(float32) ) quit("read_vset: Sorry, I can only read float32 scalar-data."); if ((in->data = (float32 *) malloc((size_t) (nelements*sizeof(float32)))) == NULL) quit("read_vset: Cannot allocate mem for scalar."); VSread(vs, (BYTE *)in->data, nelements, NO_INTERLACE ); scalarfound = TRUE; nscalar = nelements; #ifdef DEBUGGING printf(" scalar read\n" ); #endif } for (i=0; i < opt->ncon; i++) if ( connectfound[i] == FALSE && VSfexist(vs, opt->connectname[i]) == 1 && VSsetfields(vs, opt->connectname[i]) == SUCCEED && (csize = VSsizeof(vs, opt->connectname[i])) > 0) { #ifdef DEBUGGING printf(" attempting conn list named %s\n", opt->connectname[i] ); printf(" size found %d\n", csize ); #endif if ( con3found == FALSE && csize == 3*sizeof(int16) ) /* int16 triangle conn list */ { if ((in->splist3 = (int16 *) malloc((size_t) (nelements*csize))) == NULL) quit("read_vset: Cannot allocate mem for connectivity list."); VSread(vs, (BYTE *)in->splist3, nelements, NO_INTERLACE ); in->etyp3 = INT16TYPE; in->ntri = nelements; con3found = TRUE; #ifdef DEBUGGING printf(" it's a tri-INT16TYPE\n" ); #endif } else if ( con4found == FALSE && csize == 4*sizeof(int16) ) /* int16 quadrangle conn list */ { if ((in->splist4 = (int16 *) malloc((size_t) (nelements*csize))) == NULL) quit("read_vset: Cannot allocate mem for connectivity list."); VSread(vs, (BYTE *)in->splist4, nelements, NO_INTERLACE ); in->etyp4 = INT16TYPE; in->nquad = nelements; con4found = TRUE; #ifdef DEBUGGING printf(" it's a quad-INT16TYPE\n" ); #endif } else if ( con3found == FALSE && csize == 3*sizeof(int32) ) /* int32 triangle conn list */ { if ((in->plist3 = (int32 *) malloc((size_t) (nelements*csize))) == NULL) quit("read_vset: Cannot allocate mem for connectivity list."); VSread(vs, (BYTE *)in->plist3, nelements, NO_INTERLACE ); in->etyp3 = INT32TYPE; in->ntri = nelements; con3found = TRUE; #ifdef DEBUGGING printf(" it's a tri-INT32TYPE\n" ); #endif } else if ( con4found == FALSE && csize == 4*sizeof(int32) ) /* int32 quadrangle conn list */ { if ((in->plist4 = (int32 *) malloc((size_t) (nelements*csize))) == NULL) quit("read_vset: Cannot allocate mem for connectivity list."); VSread(vs, (BYTE *)in->plist4, nelements, NO_INTERLACE ); in->etyp4 = INT32TYPE; in->nquad = nelements; con4found = TRUE; #ifdef DEBUGGING printf(" it's a quad-INT32TYPE\n" ); #endif } else quit("read_vset: Illegal or duplicate connectivity list."); connectfound[i] = TRUE; } confound = TRUE; oneconfound = FALSE; for (i=0; i < opt->ncon; i++) { confound = confound && connectfound[i]; oneconfound = oneconfound || connectfound[i]; } confound = confound || ( con3found && con4found ); } VSdetach(vs); } } Vdetach(vg); Vfinish(f); Hclose(f); if ( pxfound == FALSE ) quit("read_vset: Cannot find px field."); if ( pyfound == FALSE ) quit("read_vset: Cannot find py field."); if ( read_scalar && scalarfound == FALSE ) quit("read_vset: Cannot find scalar field."); if ( oneconfound == FALSE ) quit("read_vset: Cannot find any connect field."); if ( confound == FALSE && opt->connect == TRUE ) printf("read_vset: Warning: Couldn't load/find all connect lists you specified.\n"); if ( npx != npy ) quit("read_vset: (px, py) have unequal lengths."); else if ( read_scalar && npx != nscalar ) quit("read_vset: (px, py, scalar) have unequal lengths."); else in->nv = npx; if ( opt->domain == FALSE ) { gminmax( &opt->xmin, &opt->xmax, in->x, in->nv ); gminmax( &opt->ymin, &opt->ymax, in->y, in->nv ); } if ( read_scalar ) { if ( opt->minmax == FALSE ) gminmax( &datamin, &datamax, in->data, in->nv ); if ( datamin >= datamax) quit("read_vset: Data max/min err."); if ( opt->threshold == FALSE ) { opt->min_threshold = datamin + 0.3*(datamax-datamin); opt->max_threshold = datamin + (1-0.3)*(datamax-datamin); } } if (opt->xmin >= opt->xmax || opt->ymin >= opt->ymax) quit("read_vset: Domain spec err."); if ( opt->ratio == FALSE ) opt->ydivx = (opt->ymax - opt->ymin) / (opt->xmax - opt->xmin); if ( opt->ydivx < 1E-3 || opt->ydivx > 1E3) quit("read_vset: Ratio too small/large."); } #endif /* NO_VSET */ /***************************************************************** * gminmax: Determines min and max of float32 array x[dim]. * *****************************************************************/ void gminmax( float32 *xmin, float32 *xmax, float32 *x, int32 dim ) { for ( *xmin = *x, *xmax = *x; dim>1; dim-- ) { x++; if (*x < *xmin) *xmin = *x; else if (*x > *xmax) *xmax = *x; } } /*********************************************************************** * PostScript (Adobe Illustrator-3) defines * ***********************************************************************/ #if ( defined(MAC) && defined(MPW) ) #pragma segment PSpart #endif /* * BEGIN_LN, LN, END_LN: flushes textlines to PS file. (for resources, etc) */ #define BEGIN_LN (void)( 0 /* dirty "do nothing" */ #define LN ); (void) fprintf( psfile, "%s\n", #define END_LN ); #define NEWPATH /* NEWPATH == nothing for ILLUSTRATOR */ #define MOVETO( x, y ) (void) fprintf(psfile, "%3.2f %3.2f m\n", x, y ) #define LINETO( x, y ) (void) fprintf(psfile, "%3.2f %3.2f l\n", x, y ) #define CLOSE_AND_STROKE (void) fprintf(psfile, "s\n") #define STROKE (void) fprintf(psfile, "S\n") #define SET_GREY( val ) (void) fprintf(psfile, "%3.3f G\n", val ) /*----------------------------------------------------------------- SEG: Draws the line xp,yp[i]--xp,yp[j]. -----------------------------------------------------------------*/ #define SEG( i,j ) { NEWPATH; \ MOVETO( xp[i], yp[i] ); \ LINETO( xp[j], yp[j] ); \ STROKE; \ } /*----------------------------------------------------------------- SEG2: Draws the lines xp,yp[i]--xp,yp[j]--xp,yp[k]. -----------------------------------------------------------------*/ #define SEG2( i,j,k ) { NEWPATH; \ MOVETO( xp[i], yp[i] ); \ LINETO( xp[j], yp[j] ); \ LINETO( xp[k], yp[k] ); \ STROKE; \ } /*----------------------------------------------------------------- PLOT_TRIANGLE: Draws the triangle specified by x[3],y[3]. -----------------------------------------------------------------*/ #ifdef AI3BUG #define PLOT_TRIANGLE( x, y ) { NEWPATH; \ MOVETO( x[0], y[0] ); \ LINETO( x[1], y[1] ); \ LINETO( x[2], y[2] ); \ LINETO( x[0], y[0] ); \ CLOSE_AND_STROKE; \ } #else #define PLOT_TRIANGLE( x, y ) { NEWPATH; \ MOVETO( x[0], y[0] ); \ LINETO( x[1], y[1] ); \ LINETO( x[2], y[2] ); \ CLOSE_AND_STROKE; \ } #endif /* AI3BUG */ /*----------------------------------------------------------------- PLOT_QUADRANGLE: Draws the quadrangle specified by x[4],y[4]. ASSUMES: THE FOUR VERTICES ARE ORDERED. -----------------------------------------------------------------*/ #ifdef AI3BUG #define PLOT_QUADRANGLE( x, y ) { NEWPATH; \ MOVETO( x[0], y[0] ); \ LINETO( x[1], y[1] ); \ LINETO( x[2], y[2] ); \ LINETO( x[3], y[3] ); \ LINETO( x[0], y[0] ); \ CLOSE_AND_STROKE; \ } #else #define PLOT_QUADRANGLE( x, y ) { NEWPATH; \ MOVETO( x[0], y[0] ); \ LINETO( x[1], y[1] ); \ LINETO( x[2], y[2] ); \ LINETO( x[3], y[3] ); \ CLOSE_AND_STROKE; \ } #endif /* AI3BUG */ /* Note: using a semi-colon (;) after invocations of PLOT_TRIANGLE or PLOT_QUADRANGLE is fatal in the context below. */ /************************************************************************ * rect_grid: Generates PostScript line drawing of rectangular grid. * * ************************************************************************/ void rect_grid( struct Input in, struct Options opt ) { FILE *psfile=opt.psfile; int32 i, j; SET_GREY( opt.grid_grey ); /* * First draw the gridlines i = const: */ for ( i=0; i in.nv-1 ) quit("vset_grid: Connectivity list element out of range."); x[j] = in.x[ptr]; y[j] = in.y[ptr]; } PLOT_TRIANGLE( x, y ) #if ( defined(MAC) && defined(MPW) ) if ( i % cursor3 == 0 ) RotateCursor(-32); #endif } /* * Finally the quadrangles. */ for (i=0; i < in.nquad; i++) { for (j=0; j<4; j++) { ptr = (in.etyp4==INT16TYPE)? in.splist4[4*i+j] - 1 : in.plist4[4*i+j] - 1; if ( ptr < -1 || (ptr==-1 && j!=3) || ptr > in.nv-1 ) quit("vset_grid: Connectivity list element out of range."); x[j] = in.x[ptr]; y[j] = in.y[ptr]; } if ( ptr != -1 ) PLOT_QUADRANGLE( x, y ) else /* last ptr == -1 means triangle stored in quadr conn list */ PLOT_TRIANGLE( x, y ) #if ( defined(MAC) && defined(MPW) ) if ( i % cursor4 == 0 ) RotateCursor(-32); #endif } SET_GREY( 0.0 ); /* restore to black */ } /************************************************************************************** * vset_contour: * * Generates contourplot of two dimensional vertex set. * * USES GLOBALS: * * float32 datamin, datamax; (requested min/max contour level) * * ASSUMES: * * quadrangles (if present) are convex. * **************************************************************************************/ void vset_contour( struct Input in, struct Options opt ) { FILE *psfile=opt.psfile; int32 ptr, ilo, ihi, i, j, ip, np, n, interv = opt.ncontours - 1; float32 xp[6], yp[6], x[6], y[6], c[6]; float32 dz, clo, chi, elev, pdif, tmp; #if ( defined(MAC) && defined(MPW) ) int32 cursor3 = sqrt(1.1+fabs((double)in.ntri)), cursor4 = sqrt(1.1+fabs((double)in.nquad)); #endif /* * First some checks: */ if (in.ftyp != VSET) quit("vset_contour: Illegal input data type."); if (in.ntri < 1 && in.nquad < 1) quit("vset_contour: Not enough triangles/quadrangles."); if (datamax <= datamin) quit("vset_contour: datamax <= datamin."); if (interv < 0) quit("vset_contour: Nr contours < 1."); dz = (datamax-datamin) / MAX2(1,interv); SET_GREY( 0.0 ); /* all contours are drawn black */ /* * First the triangles. */ for (i=0; i < in.ntri; i++) { for (j=0; j<3; j++) { ptr = (in.etyp3==INT16TYPE)? in.splist3[3*i+j] - 1 : in.plist3[3*i+j] - 1; if ( ptr < 0 || ptr > in.nv-1 ) quit("vset_contour: Connectivity list element out of range."); x[j] = in.x[ptr]; y[j] = in.y[ptr]; c[j] = in.data[ptr]; } /* --------------------- contour the TRIANGLE ------------------- */ x[3] = x[0]; y[3] = y[0]; c[3] = c[0]; clo = MIN3(c[0],c[1],c[2]); chi = MAX3(c[0],c[1],c[2]); ilo = MAX(0, ROUNDUP( (clo - datamin)/dz - SMALL) ); /* CHECK NECESSITY OF SMALL */ ihi = MIN(interv, ROUNDDOWN((chi - datamin)/dz + SMALL) ); for ( ip=ilo; ip<=ihi; ip++ ) { elev = ip*dz + datamin; np = 0; /* number of contour intersections with the triangle perimeter */ /* Calculate the x,y coords of the contour intersections with the triangle perimeter: */ for ( n=0; n<3; n++ ) { if ( elev > MIN2(c[n],c[n+1]) && elev <= MAX2(c[n],c[n+1]) ) /* what about rounding ??? */ { pdif = ( elev - c[n] )/( c[n+1] - c[n] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] -- copes with severe rounding problems */ xp[np] = x[n] + ( x[n+1] - x[n] ) * pdif; yp[np] = y[n] + ( y[n+1] - y[n] ) * pdif; np++; } } if (np==2) SEG( 0,1 ) #ifdef DEBUGGING else if (np != 0) quit("vset_contour: This cannot happen (np not in {0,2,4})."); #endif } #if ( defined(MAC) && defined(MPW) ) if ( i % cursor3 == 0 ) RotateCursor(32); #endif } /* * Finally the quadrangles. */ for (i=0; i < in.nquad; i++) { for (j=0; j<4; j++) { ptr = (in.etyp4==INT16TYPE)? in.splist4[4*i+j] - 1 : in.plist4[4*i+j] - 1; if ( ptr < -1 || (ptr==-1 && j!=3) || ptr > in.nv-1 ) quit("vset_contour: Connectivity list element out of range."); x[j] = in.x[ptr]; y[j] = in.y[ptr]; c[j] = in.data[ptr]; } if ( ptr != -1 ) { /* ---------------- contour the QUADRANGLE (comments: see contour() block) ------- */ x[4] = x[0]; x[5] = (x[0]+x[1]+x[2]+x[3])/4; y[4] = y[0]; y[5] = (y[0]+y[1]+y[2]+y[3])/4; c[4] = c[0]; c[5] = (c[0]+c[1]+c[2]+c[3])/4; clo = MIN4(c[0],c[1],c[2],c[3]); chi = MAX4(c[0],c[1],c[2],c[3]); ilo = MAX(0, ROUNDUP( (clo - datamin)/dz - SMALL) ); ihi = MIN(interv, ROUNDDOWN((chi - datamin)/dz + SMALL) ); for ( ip=ilo; ip<=ihi; ip++ ) { elev = ip*dz + datamin; np = 0; for ( n=0; n<4; n++ ) { if ( elev > MIN2(c[n],c[n+1]) && elev <= MAX2(c[n],c[n+1]) ) { pdif = ( elev - c[n] )/( c[n+1] - c[n] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[np] = x[n] + ( x[n+1] - x[n] ) * pdif; yp[np] = y[n] + ( y[n+1] - y[n] ) * pdif; np++; } } if (np==2) SEG( 0,1 ) else if (np==4) { if( MIN2(c[5],c[1]) >= elev || MAX2(c[5],c[1]) < elev ) { pdif = ( elev - c[0] )/( c[5] - c[0] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[4] = x[0] + ( x[5] - x[0] ) * pdif; yp[4] = y[0] + ( y[5] - y[0] ) * pdif; pdif = ( elev - c[2] )/( c[5] - c[2] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[5] = x[2] + ( x[5] - x[2] ) * pdif; yp[5] = y[2] + ( y[5] - y[2] ) * pdif; SEG2( 0,4,3 ) SEG2( 1,5,2 ) } else { pdif = ( elev - c[1] )/( c[5] - c[1] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[4] = x[1] + ( x[5] - x[1] ) * pdif; yp[4] = y[1] + ( y[5] - y[1] ) * pdif; pdif = ( elev - c[3] )/( c[5] - c[3] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[5] = x[3] + ( x[5] - x[3] ) * pdif; yp[5] = y[3] + ( y[5] - y[3] ) * pdif; SEG2( 0,4,1 ) SEG2( 2,5,3 ) } } #ifdef DEBUGGING else if (np != 0) quit("vset_contour: This cannot happen (np not in {0,2,4})."); #endif } } else /* last ptr == -1 means triangle stored in quadr conn list */ { /* ------------------ contour the TRIANGLE (comments: see tri-block above) ------- */ x[3] = x[0]; y[3] = y[0]; c[3] = c[0]; clo = MIN3(c[0],c[1],c[2]); chi = MAX3(c[0],c[1],c[2]); ilo = MAX(0, ROUNDUP( (clo - datamin)/dz - SMALL) ); ihi = MIN(interv, ROUNDDOWN((chi - datamin)/dz + SMALL) ); for ( ip=ilo; ip<=ihi; ip++ ) { elev = ip*dz + datamin; np = 0; for ( n=0; n<3; n++ ) { if ( elev > MIN2(c[n],c[n+1]) && elev <= MAX2(c[n],c[n+1]) ) { pdif = ( elev - c[n] )/( c[n+1] - c[n] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; xp[np] = x[n] + ( x[n+1] - x[n] ) * pdif; yp[np] = y[n] + ( y[n+1] - y[n] ) * pdif; np++; } } if (np==2) SEG( 0,1 ) #ifdef DEBUGGING else if (np != 0) quit("vset_contour: This cannot happen (np not in {0,2})."); #endif } } #if ( defined(MAC) && defined(MPW) ) if ( i % cursor4 == 0 ) RotateCursor(32); #endif } } /************************************************************************************** * vset_boundary: * * Draws the boundary of two dimensional vertex set. * * ASSUMES: * * - Each vertex (px,py) occurs only once in the coordinate vdatas. * * - The interior sides (called "line-segments" in this function) of any two * * elements are EITHER disjunct OR identical. * **************************************************************************************/ #define EMPTY -99 /* value of empty segment-entry in 'list' */ void vset_boundary( struct Input in, struct Options opt ) { FILE *psfile=opt.psfile; int32 i, j, iseg, nseg, ptr[4]; int32 (*list)[2]; /* array of line-segment indices */ enum boolean interior; /* "current line-segment is interior to domain" */ nseg = 3*in.ntri + 4*in.nquad; /* max number of line segments we can expect */ if ( (list = (int32 (*)[2]) malloc( (size_t) (2*nseg*sizeof(int32)) )) == NULL ) quit("vset_boundary: Cannot allocate mem for boundary connectivity list."); /* * Step 1: Fill 'list' with ALL segments as specified in the connectivity list(s): */ iseg = 0; /* true nr of segments -- iseg in [0..nseg] Differs from nseg iff triangles are specified in the quadrangle connectivity list */ for (i=0; i < in.ntri; i++) /* First the triangles. */ { for (j=0; j<3; j++) { ptr[j] = (in.etyp3==INT16TYPE)? in.splist3[3*i+j] - 1 : in.plist3[3*i+j] - 1; if ( ptr[j] < 0 || ptr[j] > in.nv-1 ) quit("vset_boundary: Connectivity list element out of range."); } list[iseg][0] = MIN2( ptr[0], ptr[1] ); /* order each pair of list -- facilitates listcomp() */ list[iseg++][1] = MAX2( ptr[0], ptr[1] ); list[iseg][0] = MIN2( ptr[1], ptr[2] ); list[iseg++][1] = MAX2( ptr[1], ptr[2] ); list[iseg][0] = MIN2( ptr[2], ptr[0] ); list[iseg++][1] = MAX2( ptr[2], ptr[0] ); } for (i=0; i < in.nquad; i++) /* Finally the quadrangles. */ { for (j=0; j<4; j++) { ptr[j] = (in.etyp4==INT16TYPE)? in.splist4[4*i+j] - 1 : in.plist4[4*i+j] - 1; if ( ptr[j] < -1 || (ptr[j]==-1 && j!=3) || ptr[j] > in.nv-1 ) quit("vset_boundary: Connectivity list element out of range."); } if ( ptr[3] != -1 ) /* indeed a quadrangle */ { list[iseg][0] = MIN2( ptr[0], ptr[1] ); list[iseg++][1] = MAX2( ptr[0], ptr[1] ); list[iseg][0] = MIN2( ptr[1], ptr[2] ); list[iseg++][1] = MAX2( ptr[1], ptr[2] ); list[iseg][0] = MIN2( ptr[2], ptr[3] ); list[iseg++][1] = MAX2( ptr[2], ptr[3] ); list[iseg][0] = MIN2( ptr[3], ptr[0] ); list[iseg++][1] = MAX2( ptr[3], ptr[0] ); } else /* ptr[3] == -1 means triangle stored in quadr conn list */ /* The difference between nseg and iseg originates here */ { list[iseg][0] = MIN2( ptr[0], ptr[1] ); list[iseg++][1] = MAX2( ptr[0], ptr[1] ); list[iseg][0] = MIN2( ptr[1], ptr[2] ); list[iseg++][1] = MAX2( ptr[1], ptr[2] ); list[iseg][0] = MIN2( ptr[2], ptr[0] ); list[iseg++][1] = MAX2( ptr[2], ptr[0] ); } } /* * Step 2: Sort the list containing iseg segments. */ #ifdef PRE_C89 /* some compilers cannot handle "const void *" casts */ qsort( (void *)list, iseg, 2*sizeof(int32), (int (*)(void*,void*))listcomp ); #else qsort( (void *)list, iseg, 2*sizeof(int32), (int (*)(const void*,const void*))listcomp ); #endif /* * Step 3: Strip the list from all multiply occuring identical segments. */ interior = FALSE; /* loop init */ for ( i=0; ib[0] ) return 1; else if ( a[1]b[1] ) return 1; else return 0; } /************************************************************************************** * contour: * * Generates contourplot of two dimensional rectangular or curvilinear data. * * USES GLOBALS: * * float32 datamin, datamax; (requested min/max contour level) * * ASSUMES: * * quadrangles are convex. * **************************************************************************************/ void contour( struct Input in, struct Options opt ) { FILE *psfile = opt.psfile; int32 ilo, ihi, i, j, ip, np, n, interv = opt.ncontours - 1; float32 xp[6], yp[6], x[6], y[6], c[6]; float32 dz, clo, chi, elev, pdif, tmp; /* * First some checks: */ if (in.ftyp != RECT && in.ftyp != CRV) quit("contour: Illegal input data type."); if (in.dim0 < 2 || in.dim1 < 2) quit("contour: Dim(s) too small."); if (datamax <= datamin) quit("contour: datamax <= datamin."); if (interv < 0) quit("contour: Nr contours < 1."); dz = (datamax-datamin) / MAX2(1,interv); /* * Loop on cells to draw contours: */ SET_GREY( 0.0 ); /* all contours are drawn black */ for ( i=0; i= ilo) { if (in.ftyp==RECT) { x[0] = in.x[i]; x[1] = in.x[i+1]; x[2] = x[1]; x[3] = x[0]; x[4] = x[0]; x[5] = (x[0]+x[1]+x[2]+x[3])/4; y[0] = in.y[j]; y[1] = y[0]; y[2] = in.y[j+1]; y[3] = y[2]; y[4] = y[0]; y[5] = (y[0]+y[1]+y[2]+y[3])/4; } else { x[0] = X(i ,j ); x[1] = X(i+1,j ); x[2] = X(i+1,j+1); x[3] = X(i ,j+1); x[4] = x[0]; x[5] = (x[0]+x[1]+x[2]+x[3])/4; y[0] = Y(i ,j ); y[1] = Y(i+1,j ); y[2] = Y(i+1,j+1); y[3] = Y(i ,j+1); y[4] = y[0]; y[5] = (y[0]+y[1]+y[2]+y[3])/4; } for ( ip=ilo; ip<=ihi; ip++ ) { /* Contours in greylevels: 0. -- 0.5, use something like: * SET_GREY( 0.5 * ip/(float)interv ); */ elev = ip*dz + datamin; np = 0; /* number of contour intersections with the quadrangle perimeter */ /* Calculate the x,y coords of the contour intersections with the quadrangle perimeter: */ for ( n=0; n<4; n++ ) { if ( elev > MIN2(c[n],c[n+1]) && elev <= MAX2(c[n],c[n+1]) ) /* what about rounding ??? */ { pdif = ( elev - c[n] )/( c[n+1] - c[n] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] -- copes with severe rounding problems */ xp[np] = x[n] + ( x[n+1] - x[n] ) * pdif; yp[np] = y[n] + ( y[n+1] - y[n] ) * pdif; np++; } } if (np==2) SEG( 0,1 ) else if (np==4) { /* Saddle point strategy: subdivide the quadrangle into * four triangles: (centre point has index '5') */ if( MIN2(c[5],c[1]) >= elev || MAX2(c[5],c[1]) < elev ) { /* Interconnect point on side 0/1 with point on side 3/0 * via an intersection on side 0/5, point on side 1/2 with * point on side 2/3 via an intersection on side 2/5: */ pdif = ( elev - c[0] )/( c[5] - c[0] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] */ xp[4] = x[0] + ( x[5] - x[0] ) * pdif; yp[4] = y[0] + ( y[5] - y[0] ) * pdif; pdif = ( elev - c[2] )/( c[5] - c[2] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] */ xp[5] = x[2] + ( x[5] - x[2] ) * pdif; yp[5] = y[2] + ( y[5] - y[2] ) * pdif; SEG2( 0,4,3 ) SEG2( 1,5,2 ) } else { /* Interconnect point on side 0/1 with point on side 1/2 * via an intersection on side 1/5, point on side 2/3 with * point on side 3/0 via an intersection on side 3/5: */ pdif = ( elev - c[1] )/( c[5] - c[1] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] */ xp[4] = x[1] + ( x[5] - x[1] ) * pdif; yp[4] = y[1] + ( y[5] - y[1] ) * pdif; pdif = ( elev - c[3] )/( c[5] - c[3] ); if ( pdif < 0.0 ) pdif = 0.0; if ( pdif > 1.0 ) pdif = 1.0; /* force pdif in [0..1] */ xp[5] = x[3] + ( x[5] - x[3] ) * pdif; yp[5] = y[3] + ( y[5] - y[3] ) * pdif; SEG2( 0,4,1 ) SEG2( 2,5,3 ) } } #ifdef DEBUGGING else if (np != 0) quit("contour: This cannot happen (np not in {0,2,4})."); /* This may happen due to rounding problems ??? */ #endif } } } #if ( defined(MAC) && defined(MPW) ) RotateCursor(32); #endif } } /********************************************************************* * rect_boundary: Draws two dimensional rectangular grid. * *********************************************************************/ void rect_boundary( struct Input in, struct Options opt ) { FILE *psfile = opt.psfile; int32 i, j; SET_GREY( opt.boun_grey ); NEWPATH; MOVETO( in.x[0], in.y[0] ); for ( j=1; j opt.max_threshold ) { if ( DATA(i,j) > DATA(i+1,j) && DATA(i,j) > DATA(i,j+1) && DATA(i,j) > DATA(i+1,j+1) && DATA(i,j) > DATA(i+1,j-1) && DATA(i,j) > DATA(i-1,j) && DATA(i,j) > DATA(i,j-1) && DATA(i,j) > DATA(i-1,j+1) && DATA(i,j) > DATA(i-1,j-1) ) { if ( in.ftyp == RECT ) { x = in.x[i]; y = in.y[j]; } else { x = X(i,j); y = Y(i,j); } centertext( psfile, x, y, "H" ); /* does horizontal and vertical alignment */ } } else if ( DATA(i,j) < opt.min_threshold ) { if ( DATA(i,j) < DATA(i+1,j) && DATA(i,j) < DATA(i,j+1) && DATA(i,j) < DATA(i+1,j+1) && DATA(i,j) < DATA(i+1,j-1) && DATA(i,j) < DATA(i-1,j) && DATA(i,j) < DATA(i,j-1) && DATA(i,j) < DATA(i-1,j+1) && DATA(i,j) < DATA(i-1,j-1) ) { if ( in.ftyp == RECT ) { x = in.x[i]; y = in.y[j]; } else { x = X(i,j); y = Y(i,j); } centertext( psfile, x, y, "L" ); /* does horizontal and vertical alignment */ } } fprintf( psfile, "%s\n", "Q % Illustrator equiv of: grestore" ); } /********************************************************************* * vset_labels: Draws labels at local extremes of vertex set. * * ASSUMES: Each vertex occurs only once in the vdatas. * *********************************************************************/ #define DAT(i) in.data[ptr[i]] /* handy abbreviations */ #define PTYP(i) ptyp[ptr[i]] /* ^ indices of DAT and PTYP correspond to a local vertex numbering: i=0,1,2(,3) */ void vset_labels( struct Input in, struct Options opt ) { FILE *psfile=opt.psfile; int32 i, j, ptr[4]; enum point_typ { IS_MIN, NONE, IS_MAX }; enum point_typ *ptyp; /* array */ if ( opt.values == TRUE ) printf( "vset_labels: Labeling with values not implemented.\n" ); if ( opt.labels == FALSE ) return; if ( in.ftyp != VSET ) quit( "vset_labels: Incorrect datatype." ); if ( opt.max_threshold < opt.min_threshold ) quit( "vset_labels: Thresholds corrupt." ); if ( (ptyp = (enum point_typ *) malloc( (size_t) (in.nv*sizeof(enum point_typ)) )) == NULL ) quit("vset_labels: Cannot allocate mem for ptyp array."); for ( i=0; i opt.max_threshold ) ptyp[i] = IS_MAX; else if ( in.data[i] < opt.min_threshold ) ptyp[i] = IS_MIN; else ptyp[i] = NONE; } for (i=0; i < in.ntri; i++) /* First the triangles. */ { for (j=0; j<3; j++) { ptr[j] = (in.etyp3==INT16TYPE)? in.splist3[3*i+j] - 1 : in.plist3[3*i+j] - 1; if ( ptr[j] < 0 || ptr[j] > in.nv-1 ) quit("vset_labels: Connectivity list element out of range."); } if ( PTYP(0)==IS_MAX ) { if ( DAT(0) <= DAT(1) || DAT(0) <= DAT(2) ) PTYP(0) = NONE; } else if ( PTYP(0)==IS_MIN ) { if ( DAT(0) >= DAT(1) || DAT(0) >= DAT(2) ) PTYP(0) = NONE; } if ( PTYP(1)==IS_MAX ) { if ( DAT(1) <= DAT(0) || DAT(1) <= DAT(2) ) PTYP(1) = NONE; } else if ( PTYP(1)==IS_MIN ) { if ( DAT(1) >= DAT(0) || DAT(1) >= DAT(2) ) PTYP(1) = NONE; } if ( PTYP(2)==IS_MAX ) { if ( DAT(2) <= DAT(0) || DAT(2) <= DAT(1) ) PTYP(2) = NONE; } else if ( PTYP(2)==IS_MIN ) { if ( DAT(2) >= DAT(0) || DAT(2) >= DAT(1) ) PTYP(2) = NONE; } } for (i=0; i < in.nquad; i++) /* Finally the quadrangles. */ { for (j=0; j<4; j++) { ptr[j] = (in.etyp4==INT16TYPE)? in.splist4[4*i+j] - 1 : in.plist4[4*i+j] - 1; if ( ptr[j] < -1 || (ptr[j]==-1 && j!=3) || ptr[j] > in.nv-1 ) quit("vset_labels: Connectivity list element out of range."); } if ( ptr[3] != -1 ) /* indeed a quadrangle */ { if ( PTYP(0)==IS_MAX ) { if ( DAT(0) <= DAT(1) || DAT(0) <= DAT(2) || DAT(0) <= DAT(3) ) PTYP(0) = NONE; } else if ( PTYP(0)==IS_MIN ) { if ( DAT(0) >= DAT(1) || DAT(0) >= DAT(2) || DAT(0) >= DAT(3) ) PTYP(0) = NONE; } if ( PTYP(1)==IS_MAX ) { if ( DAT(1) <= DAT(0) || DAT(1) <= DAT(2) || DAT(1) <= DAT(3) ) PTYP(1) = NONE; } else if ( PTYP(1)==IS_MIN ) { if ( DAT(1) >= DAT(0) || DAT(1) >= DAT(2) || DAT(1) >= DAT(3) ) PTYP(1) = NONE; } if ( PTYP(2)==IS_MAX ) { if ( DAT(2) <= DAT(0) || DAT(2) <= DAT(1) || DAT(2) <= DAT(3) ) PTYP(2) = NONE; } else if ( PTYP(2)==IS_MIN ) { if ( DAT(2) >= DAT(0) || DAT(2) >= DAT(1) || DAT(2) >= DAT(3) ) PTYP(2) = NONE; } if ( PTYP(3)==IS_MAX ) { if ( DAT(3) <= DAT(0) || DAT(3) <= DAT(1) || DAT(3) <= DAT(2) ) PTYP(3) = NONE; } else if ( PTYP(3)==IS_MIN ) { if ( DAT(3) >= DAT(0) || DAT(3) >= DAT(1) || DAT(3) >= DAT(2) ) PTYP(3) = NONE; } } else /* ptr[3] == -1 means triangle stored in quadr conn list */ { if ( PTYP(0)==IS_MAX ) { if ( DAT(0) <= DAT(1) || DAT(0) <= DAT(2) ) PTYP(0) = NONE; } else if ( PTYP(0)==IS_MIN ) { if ( DAT(0) >= DAT(1) || DAT(0) >= DAT(2) ) PTYP(0) = NONE; } if ( PTYP(1)==IS_MAX ) { if ( DAT(1) <= DAT(0) || DAT(1) <= DAT(2) ) PTYP(1) = NONE; } else if ( PTYP(1)==IS_MIN ) { if ( DAT(1) >= DAT(0) || DAT(1) >= DAT(2) ) PTYP(1) = NONE; } if ( PTYP(2)==IS_MAX ) { if ( DAT(2) <= DAT(0) || DAT(2) <= DAT(1) ) PTYP(2) = NONE; } else if ( PTYP(2)==IS_MIN ) { if ( DAT(2) >= DAT(0) || DAT(2) >= DAT(1) ) PTYP(2) = NONE; } } } /* * Now the extremes can be labeled: */ fprintf( psfile, "%s\n", "q % Illustrator equiv of: gsave" ); inittext( psfile ); for ( i=0; i #include #include #endif #define SMAX 128 void pshead( struct Options opt ) { FILE *psfile=opt.psfile; time_t tim; struct tm t; char timestr[SMAX+1]; char *username; #ifdef UNIX struct passwd *pw; #endif /* * Write the first part of the comment header: */ fprintf( psfile, "%s\n", "%!PS-Adobe-3.0 EPSF-3.0" ); fprintf( psfile, "%s%s%s%s%s\n", "%%Creator: (Fred Walsteijn's vs2ps -- version: ", VERSION, ", dated: ", VDATE, ")" ); /* ^ don't change the line above */ fprintf( psfile, "%s%s%s\n", "%%Title: (", opt.outfile, ")" ); /* * This should find your username (UNIX and MAC/MPW systems only): */ /* -- alternate way under UNIX (less robust ?): -- */ /* if ( (username = cuserid(NULL)) != NULL ) */ /* fprintf( psfile, "%s %s\n", "%%For:", username ); */ /* else */ #ifdef UNIX if ( (username = getlogin()) != NULL ) fprintf( psfile, "%s %s\n", "%%For:", username ); else if ( (pw = getpwuid(getuid())) != NULL ) fprintf( psfile, "%s %s\n", "%%For:", (*pw).pw_name ); else #elif ( defined(MAC) && defined(MPW) ) if ( (username = getenv("user")) != NULL ) fprintf( psfile, "%s %s\n", "%%For:", username ); else #endif fprintf( psfile, "%s\n", "%%For: (Fred Walsteijn) (University of Utrecht, The Netherlands)" ); /* ^ default username in case I cannot get it from OS --- you may change this line */ /* * Write the date and time: */ if ( (tim = time(NULL)) == -1 || localtime(&tim) == NULL || ( t = *localtime(&tim), (strftime( timestr, (size_t)SMAX, "(%a, %b %d, %Y) (%H:%M:%S)", &t ) == 0 )) ) printf("pshead: Cannot get the date/time.\n"); else fprintf( psfile, "%s %s\n", "%%CreationDate:", timestr ); /* * Write the rest of the comment header: */ BEGIN_LN LN "%%DocumentProcessColors: Black" LN "%%DocumentFonts: Times-Bold" LN "%%+ Times-BoldItalic" LN "%%DocumentSuppliedResources: procset Adobe_packedarray 2.0 0" LN "%%+ procset Adobe_cmykcolor 1.1 0" LN "%%+ procset Adobe_cshow 1.1 0" LN "%%+ procset Adobe_customcolor 1.0 0" LN "%%+ procset Adobe_typography_AI3 1.0 0" LN "%%+ procset Adobe_IllustratorA_AI3 1.0 0" END_LN fprintf( psfile, "%s %1d %1d %1d %1d\n", "%%BoundingBox:", bound.xlo, bound.ylo, bound.xhi, bound.yhi ); fprintf( psfile, "%s %1d %1d %1d %1d\n", "%AI3_TemplateBox:", (bound.xhi+bound.xlo)/2, (bound.yhi+bound.ylo)/2, (bound.xhi+bound.xlo)/2, (bound.yhi+bound.ylo)/2 ); BEGIN_LN LN "%AI3_TileBox: 0 0 0 0" LN "%AI3_DocumentPreview: None" LN "%AI3_ColorUsage: Black&White" LN "%%EndComments" LN "%%BeginProlog" END_LN /* * The prolog contains Adobe Illustrator resources: */ adobe( psfile ); /* * The setup section: */ BEGIN_LN LN "%%EndProlog" LN "%%BeginSetup" LN "%%IncludeFont: Times-Bold" LN "%%IncludeFont: Times-BoldItalic" LN "Adobe_cmykcolor /initialize get exec" LN "Adobe_cshow /initialize get exec" LN "Adobe_customcolor /initialize get exec" LN "Adobe_typography_AI3 /initialize get exec" LN "Adobe_IllustratorA_AI3 /initialize get exec" LN "[" LN "39/quotesingle 96/grave 128/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis" LN "/Udieresis/aacute/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute" LN "/egrave/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde" LN "/oacute/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex" LN "/udieresis/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls" LN "/registered/copyright/trademark/acute/dieresis/.notdef/AE/Oslash" LN "/.notdef/plusminus/.notdef/.notdef/yen/mu/.notdef/.notdef" LN "/.notdef/.notdef/.notdef/ordfeminine/ordmasculine/.notdef/ae/oslash" LN "/questiondown/exclamdown/logicalnot/.notdef/florin/.notdef/.notdef" LN "/guillemotleft/guillemotright/ellipsis/.notdef/Agrave/Atilde/Otilde/OE/oe" LN "/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide" LN "/.notdef/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright" LN "/fi/fl/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand" LN "/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex" LN "/Idieresis/Igrave/Oacute/Ocircumflex/.notdef/Ograve/Uacute/Ucircumflex" LN "/Ugrave/dotlessi/circumflex/tilde/macron/breve/dotaccent/ring/cedilla" LN "/hungarumlaut/ogonek/caron" LN "TE" LN "%AI3_BeginEncoding: _Times-Bold Times-Bold" LN "[/_Times-Bold/Times-Bold 0 0 1 TZ" LN "%AI3_EndEncoding" LN "%AI3_BeginEncoding: _Times-BoldItalic Times-BoldItalic" LN "[/_Times-BoldItalic/Times-BoldItalic 0 0 1 TZ" LN "%AI3_EndEncoding" LN "%%EndSetup" END_LN /* * Illustrator's default init: */ BEGIN_LN LN "0 A" LN "0 R" LN "0 G" LN "0 i 0 J 0 j 0.5 w 4 M []0 d" LN "%AI3_Note:" LN "0 D % Illustrator needs this" END_LN if ( opt.caption == TRUE ) captions( opt ); fprintf( psfile, "%s\n", "q % Illustrator equiv of: gsave" ); beginobject( psfile, "Plot domain clipping path" ); fprintf( psfile, "%1d %1d %s\n", plot.xlo, plot.ylo, "m" ); fprintf( psfile, "%1d %1d %s\n", plot.xhi, plot.ylo, "L" ); fprintf( psfile, "%1d %1d %s\n", plot.xhi, plot.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", plot.xlo, plot.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", plot.xlo, plot.ylo, "L" ); fprintf( psfile, "%s\n", "h % Illustrator equiv of: closepath" ); endobject( psfile ); fprintf( psfile, "%s\n", "W n % Illustrator equiv of: clip newpath" ); } /*************************************************************************** * pstail: Generates (Illustrator 3.0) PostScript file trailer. * ***************************************************************************/ void pstail( struct Options opt ) { FILE *psfile=opt.psfile; BEGIN_LN LN "Q % Illustrator equiv of: grestore (This matches the gsave just before the plot domain clip)" LN "%%PageTrailer" LN "gsave annotatepage grestore showpage" LN "%%Trailer" LN "Adobe_IllustratorA_AI3 /terminate get exec" LN "Adobe_typography_AI3 /terminate get exec" LN "Adobe_customcolor /terminate get exec" LN "Adobe_cshow /terminate get exec" LN "Adobe_cmykcolor /terminate get exec" LN "Adobe_packedarray /terminate get exec" LN "%%EOF" END_LN if ( fclose( opt.psfile ) != 0 ) quit("pstail: Cannot close PostScript file."); #if ( defined(MAC) && defined(MPW) ) fsetfileinfo( opt.outfile, 'ART3', 'TEXT' ); /* creator resp type of Illustrator-3 EPS */ #endif } /****************************************************************************** * captions: Puts the bot and top strings, as specified in 'opt', below * * and atop the plot domain. Should this function do some parsing * * of these strings ? (\flushleft, \flushright, \psi_1, etc ...) * ******************************************************************************/ #define DEPTH 8 /* Margin of baseline above clip-box lower side (unit=points) */ void captions( struct Options opt ) { FILE *psfile=opt.psfile; if ( opt.caption == FALSE ) return; /* * First the topstring. For safety, clip it: */ fprintf( psfile, "%s\n", "q % Illustrator equiv of: gsave" ); beginobject( psfile, "Top string clipping path" ); fprintf( psfile, "%1d %1d %s\n", tops.xlo, tops.ylo, "m" ); fprintf( psfile, "%1d %1d %s\n", tops.xhi, tops.ylo, "L" ); fprintf( psfile, "%1d %1d %s\n", tops.xhi, tops.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", tops.xlo, tops.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", tops.xlo, tops.ylo, "L" ); fprintf( psfile, "%s\n", "h % Illustrator equiv of: closepath" ); endobject( psfile ); fprintf( psfile, "%s\n", "W n % Illustrator equiv of: clip newpath" ); beginobject( psfile, "Top string" ); BEGIN_LN LN "0 O" LN "0 g" LN "0 To % begin text" END_LN fprintf( psfile, "%s %1d %1d %s\n", "1 0 0 1", tops.xlo, tops.ylo+DEPTH, "0 Tp % begin text path" ); BEGIN_LN LN "TP % end text path" LN "0 Tr % begin render" LN "0 Ts % set super/subscripting (rise)" LN "100 Tz % set horizontal scaling" LN "0 Tt % set user tracking" LN "0 TA % set pairwise kerning" LN "0 0 5 TC % set character spacing" LN "100 100 200 TW % set word spacing" LN "0 0 0 Ti % set indentation" LN "0 Ta % set alignment, 0=flushleft, 1=center, 2=flushright" LN "0 Tq % set hanging quotes" LN "0 0 Tl % set leading" LN "0 Tc % set computed char spacing" LN "0 Tw % set computed word spacing" LN "/_Times-Bold 24 Tf % set font name and size" END_LN fprintf( psfile, "%s%s%s\n", "(", opt.topstring, "\\r) Tx % text" ); fprintf( psfile, "%s\n", "TO % end text" ); endobject( psfile ); fprintf( psfile, "%s\n", "Q % Illustrator equiv of: grestore (This matches the gsave just before the topstring clip)" ); /* * Finally the botstring. For safety, clip it: */ fprintf( psfile, "%s\n", "q % Illustrator equiv of: gsave" ); beginobject( psfile, "Bot string clipping path" ); fprintf( psfile, "%1d %1d %s\n", bots.xlo, bots.ylo, "m" ); fprintf( psfile, "%1d %1d %s\n", bots.xhi, bots.ylo, "L" ); fprintf( psfile, "%1d %1d %s\n", bots.xhi, bots.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", bots.xlo, bots.yhi, "L" ); fprintf( psfile, "%1d %1d %s\n", bots.xlo, bots.ylo, "L" ); fprintf( psfile, "%s\n", "h % Illustrator equiv of: closepath" ); endobject( psfile ); fprintf( psfile, "%s\n", "W n % Illustrator equiv of: clip newpath" ); beginobject( psfile, "Bot string" ); BEGIN_LN LN "0 O" LN "0 g" LN "0 To % begin text" END_LN fprintf( psfile, "%s %1d %1d %s\n", "1 0 0 1", bots.xlo, bots.ylo+DEPTH, "0 Tp % begin text path" ); BEGIN_LN LN "TP % end text path" LN "0 Tr % begin render" LN "0 Ts % set super/subscripting (rise)" LN "100 Tz % set horizontal scaling" LN "0 Tt % set user tracking" LN "0 TA % set pairwise kerning" LN "0 0 5 TC % set character spacing" LN "100 100 200 TW % set word spacing" LN "0 0 0 Ti % set indentation" LN "0 Ta % set alignment, 0=flushleft, 1=center, 2=flushright" LN "0 Tq % set hanging quotes" LN "0 0 Tl % set leading" LN "0 Tc % set computed char spacing" LN "0 Tw % set computed word spacing" LN "/_Times-Bold 24 Tf % set font name and size" END_LN fprintf( psfile, "%s%s%s\n", "(", opt.botstring, "\\r) Tx % text" ); fprintf( psfile, "%s\n", "TO % end text" ); endobject( psfile ); fprintf( psfile, "%s\n", "Q % Illustrator equiv of: grestore (This matches the gsave just before the botstring clip)" ); } /***************************************************************************/ void beginobject( FILE *psfile, char *objname ) { fprintf( psfile, "%s%s%s\n", "%AI3_Note: (", objname, ")" ); fprintf( psfile, "%s%s%s\n", "%%BeginObject: (", objname, ")" ); } /***************************************************************************/ void endobject( FILE *psfile ) { fprintf( psfile, "%s\n", "%%EndObject" ); } /*************************************************************************** * ps_coords: Incorporates the requested domain clipping and * * plot domain ratio as specified in struct 'opt' * * (fields: xmin, xmax, ymin, ymax, ydivx) by modifying: * * in.x and in.y * * as well as the GLOBALS: * * struct Box plot, tops, bots; (bounding boxes) * ***************************************************************************/ /* * The maximum area available in default PostScript coordinates: */ #define XMIN 72 /* 1 inch */ #define XMAX 540 /* 7.5 inch */ #define YMIN 72 #define YMAX 720 /* 10 inch */ #define CAPTION 36 /* 0.5 inch */ #define MARGIN 3 /* distance of plot bounding box to selected domain. Needed because lines will have non-zero thickness */ /* ............................ : Box tops : <--- present only if opt.caption == TRUE :..........................: : ------------------------ : : | | : : | | : : | Box plot | : <--- MARGIN for plot domain BB : | | : : | | : : ------------------------ : :..........................: : Box bots : <--- present only if opt.caption == TRUE :..........................: */ void ps_coords( struct Input in, struct Options opt ) { int32 i, dimx, dimy; float32 ratio, xlo, xhi, ylo, yhi, tmp; /* * First set 'xlo, xhi, ylo, yhi, ratio' to the values of the max PS domain avail for the plot: */ xlo = XMIN + MARGIN; xhi = XMAX - MARGIN; if ( opt.caption == TRUE ) /* substract space for caption strings */ { ylo = YMIN + CAPTION + MARGIN; yhi = YMAX - CAPTION - MARGIN; } else /* all PS space can be used for the plot */ { ylo = YMIN + MARGIN; yhi = YMAX - MARGIN; } ratio = (yhi-ylo)/(xhi-xlo); /* * Now fit in the max PS subdomain with the correct ratio (opt.ydivx) of the domain sides: */ if ( opt.ydivx > ratio ) /* reduce x-size */ { tmp = (xlo + xhi - (yhi-ylo)/opt.ydivx) / 2; xhi = (xlo + xhi + (yhi-ylo)/opt.ydivx) / 2; xlo = tmp; } else /* reduce y-size */ { tmp = (ylo + yhi - (xhi-xlo)*opt.ydivx) / 2; yhi = (ylo + yhi + (xhi-xlo)*opt.ydivx) / 2; ylo = tmp; } /* * Scale the vertex coordinates so that the selected domain (opt.xmin, ...) maps to the * box with PostScript box 'xlo, xhi, ylo, yhi' (in default PS coord system): */ if (in.ftyp == RECT) { dimx = in.dim0; dimy = in.dim1; } else if (in.ftyp == CRV) dimx = dimy = in.dim0*in.dim1; else if (in.ftyp == VSET) dimx = dimy = in.nv; else quit("ps_coords: Unknown ftyp."); for ( i=0; i [ modified array ]" LN "/modifyEncoding" LN "{" LN " /_tempEncode exch ddef" LN "" LN " % pointer for sequential encodings" LN " /_pntr 0 ddef" LN "" LN " {" LN " % get bottom object" LN " counttomark -1 roll" LN " % is it a mark ?" LN " dup type dup /marktype eq" LN " {" LN " % exit" LN " pop pop exit" LN " }" LN " {" LN " % ... object ... type ...." LN " % insert if a nametype" LN " /nametype eq" LN " {" LN " % insert the name at _pntr and increment pointer" LN " _tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll" LN " put" LN " }" LN " {" LN " % reset _pntr if it's a number" LN " /_pntr exch ddef" LN " }" LN " ifelse" LN " }" LN " ifelse" LN " }" LN " loop" LN "" LN " % return the modified encoding" LN " _tempEncode" LN "}" LN "def" LN "/TE % Set std platform encoding % (encoding pairs) TE -" LN "{" LN " StandardEncoding 256 array copy modifyEncoding" LN " /_nativeEncoding exch def" LN "} def" LN "% re-define font" LN "% expected arguments" LN "% for 'normal fonts :" LN "% [ /_Helvetica-Bold/Helvetica-Bold direction fontScript defaultEncoding TZ" LN "%" LN "% for cartographic, pictographic, and expert fonts :" LN "% [ ... number value stream ... /_Helvetica-Bold/Helvetica-Bold" LN "% direction fontScript defaultEncoding TZ" LN "/TZ" LN "{" LN " % platform dependent coding flag" LN " /_useNativeEncoding exch def" LN " % pop fontScript & direction" LN " pop pop" LN "" LN " % create a new dictionary with length" LN " % equal to original dictionary length + 2" LN " % copy all the key/value pairs except FID" LN " findfont dup length 2 add dict" LN "" LN " begin" LN "" LN " % copy all the values but the FID" LN " % into the new dictionary" LN " mark exch" LN " {" LN " 1 index /FID ne { def } if cleartomark mark" LN " }" LN " forall" LN " % discard last mark" LN " pop" LN "" LN " % define FontName" LN " /FontName exch def" LN "" LN " % if no re-encoding stream is present" LN " % then if the base encoding vector of the font" LN " % is the same as StandardEncoding" LN " % and the use platform encoding flag is true" LN " % then install AI platform encoding" LN " % else leave the base encoding in effect" LN " counttomark 0 eq" LN " {" LN " Encoding StandardEncoding eq 1 _useNativeEncoding eq and" LN " {" LN " /Encoding _nativeEncoding def" LN " }" LN " if" LN " % clean up" LN " cleartomark" LN " }" LN " {" LN " % custom encoding to be done" LN " % start off with a copy of the font's standard encoding" LN " /Encoding load 256 array copy" LN " modifyEncoding /Encoding exch def" LN " }" LN " ifelse" LN " FontName currentdict" LN " end" LN "" LN " % register the new font" LN " definefont pop" LN "}" LN "def" LN "% text painting operators" LN "/tr % string tr ax ay string" LN "{" LN "_ax _ay 3 2 roll" LN "} def" LN "/trj % string trj cx cy fillchar ax ay string" LN "{" LN "_cx _cy _sp _ax _ay 6 5 roll" LN "} def" LN "/a0" LN "{" LN "/Tx % text % textString Tx -" LN " {" LN " dup" LN " currentpoint 3 2 roll" LN " tr _psf" LN " newpath moveto" LN " tr _ctm _pss" LN " } ddef" LN "/Tj % justified text % textString Tj -" LN " {" LN " dup" LN " currentpoint 3 2 roll" LN " trj _pjsf" LN " newpath moveto" LN " trj _ctm _pjss" LN " } ddef" LN "" LN "} def" LN "/a1" LN "{" LN "W B" LN "} def" LN "/e0" LN "{" LN "/Tx % text % textString Tx -" LN " {" LN " tr _psf" LN " } ddef" LN "/Tj % justified text % textString Tj -" LN " {" LN " trj _pjsf" LN " } ddef" LN "} def" LN "/e1" LN "{" LN "W F" LN "} def" LN "/i0" LN "{" LN "/Tx % text % textString Tx -" LN " {" LN " tr sp" LN " } ddef" LN "/Tj % justified text % textString Tj -" LN " {" LN " trj jsp" LN " } ddef" LN "} def" LN "/o0" LN "{" LN "/Tx % text % textString Tx -" LN " {" LN " tr sw rmoveto" LN " } ddef" LN "/Tj % justified text % textString Tj -" LN " {" LN " trj swj rmoveto" LN " } ddef" LN "} def" LN "/r0" LN "{" LN "/Tx % text % textString Tx -" LN " {" LN " tr _ctm _pss" LN " } ddef" LN "/Tj % justified text % textString Tj -" LN " {" LN " trj _ctm _pjss" LN " } ddef" LN "} def" LN "/r1" LN "{" LN "W S" LN "} def" LN "% font operators" LN "% Binding" LN "/To % begin text % bindType To -" LN "{" LN " pop _ctm currentmatrix pop" LN "} def" LN "/TO % end text % TO -" LN "{" LN " Te _ctm setmatrix newpath" LN "} def" LN "% Text paths" LN "/Tp % begin text path % a b c d tx ty startPt Tp -" LN "{" LN " pop _tm astore pop _ctm setmatrix" LN " 2 dict begin /W {} def /h {} def" LN "} def" LN "/TP % end text path % TP -" LN "{" LN " end" LN " iTm 0 0 moveto" LN "} def" LN "% Render mode & matrix operators" LN "/Tr % begin render % render Tr -" LN "{" LN " Te currentpoint newpath moveto" LN " dup 8 eq {pop 0} {dup 9 eq {pop 1} if} ifelse" LN " dup /_render exch ddef" LN " _renderStart exch get load exec" LN "} def" LN "/iTm % internal set text matrix % - iTm - (uses _tm as implicit argument)" LN "{" LN "_ctm setmatrix _tm concat 0 _rise translate _hs 1 scale" LN "} def" LN "/Tm % set text matrix % a b c d tx ty Tm -" LN "{" LN "_tm astore pop iTm 0 0 moveto" LN "} def" LN "/Td % translate text matrix % tx ty Td -" LN "{" LN "_mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto" LN "} def" LN "/Te % end render % - Te -" LN "{" LN " _render -1 eq {} {_renderEnd _render get dup null ne {load exec} {pop} ifelse} ifelse" LN " /_render -1 ddef" LN "} def" LN "% Attributes" LN "/Ta % set alignment % alignment Ta -" LN "{" LN "pop" LN "} def" LN "/Tf % set font name and size % fontname size Tf -" LN "{" LN "dup 1000 div /_fScl exch ddef" LN "exch findfont exch scalefont setfont" LN "} def" LN "/Tl % set leading % leading paragraphLeading Tl -" LN "{" LN "pop" LN "0 exch _leading astore pop" LN "} def" LN "/Tt % set user tracking % userTracking Tt -" LN "{" LN "pop" LN "} def" LN "/TW % set word spacing % minSpace optSpace maxSpace TW -" LN "{" LN "3 npop" LN "} def" LN "/Tw % set computed word spacing % wordSpace Tw" LN "{" LN "/_cx exch ddef" LN "} def" LN "/TC % set character spacing % minSpace optSpace maxSpace TC -" LN "{" LN "3 npop" LN "} def" LN "/Tc % set computed char spacing % charSpace Tc -" LN "{" LN "/_ax exch ddef" LN "} def" LN "/Ts % set super/subscripting (rise) % rise Ts -" LN "{" LN "/_rise exch ddef" LN "currentpoint" LN "iTm" LN "moveto" LN "} def" LN "/Ti % set indentation % firstStartIndent otherStartIndent stopIndent Ti -" LN "{" LN "3 npop" LN "} def" LN "/Tz % set horizontal scaling % scalePercent Tz -" LN "{" LN "100 div /_hs exch ddef" LN "iTm" LN "} def" LN "/TA % set pairwise kerning % autoKern TA -" LN " % autoKern = 0 -> no pair kerning" LN " % = 1 -> automatic pair kerning" LN "{" LN "pop" LN "} def" LN "/Tq % set hanging quotes % hangingQuotes Tq -" LN " % hangingQuotes = 0 -> no hanging quotes" LN " % = 1 -> hanging quotes" LN "{" LN "pop" LN "} def" LN "% Text Bodies" LN "/TX {pop} def" LN "%/Tx % non-justified text % textString Tx -" LN "%/Tj % justified text % textString Tj -" LN "/Tk % kern % autoKern kernValue Tk -" LN " % autoKern = 0 -> manual kern, = 1 -> auto kern" LN " % kernValue = kern value in em/1000 space" LN "{" LN "exch pop _fScl mul neg 0 rmoveto" LN "} def" LN "/TK % non-printing kern % autoKern kernValue TK -" LN "{" LN "2 npop" LN "} def" LN "/T* % carriage return & line feed % - T* -" LN "{" LN "_leading aload pop neg Td" LN "} def" LN "/T*- % carriage return & negative line feed % - T*- -" LN "{" LN "_leading aload pop Td" LN "} def" LN "/T- % print a discretionary hyphen % - T- -" LN "{" LN "_hyphen Tx" LN "} def" LN "/T+ % discretionary hyphen hyphen % - T+ -" LN "{} def" LN "/TR % reset pattern matrix % a b c d tx ty TR -" LN "{" LN "_ctm currentmatrix pop" LN "_tm astore pop" LN "iTm 0 0 moveto" LN "} def" LN "/TS % special chars % textString justified TS -" LN "{" LN "0 eq {Tx} {Tj} ifelse" LN "} def" LN "currentdict readonly pop end" LN "setpacking" LN "%%EndResource" END_LN } void adobe_part2( FILE *psfile ) { BEGIN_LN LN "%%BeginResource: procset Adobe_IllustratorA_AI3 1.0 0" LN "%%Title: (Adobe Illustrator (R) Version 3.0 Abbreviated Prolog)" LN "%%Version: 1.0" LN "%%CreationDate: (7/22/89) ()" LN "%%Copyright: ((C) 1987-1990 Adobe Systems Incorporated All Rights Reserved)" LN "currentpacking true setpacking" LN "userdict /Adobe_IllustratorA_AI3 61 dict dup begin put" LN "% initialization" LN "/initialize % - initialize -" LN "{" LN "userdict /Adobe_IllustratorA_AI3_vars 46 dict dup begin put" LN "% paint operands" LN "/_lp /none def" LN "/_pf {} def" LN "/_ps {} def" LN "/_psf {} def" LN "/_pss {} def" LN "/_pjsf {} def" LN "/_pjss {} def" LN "/_pola 0 def" LN "/_doClip 0 def" LN "% paint operators" LN "/cf currentflat def % - cf flatness" LN "% typography operands" LN "/_tm matrix def" LN "/_renderStart [/e0 /r0 /a0 /o0 /i0 /i0 /i0 /i0] def" LN "/_renderEnd [null null null null /e1 /r1 /a1 /clip] def" LN "/_render -1 def" LN "/_rise 0 def" LN "/_ax 0 def % x character spacing (_ax, _ay, _cx, _cy follows awidthshow naming convention)" LN "/_ay 0 def % y character spacing" LN "/_cx 0 def % x word spacing" LN "/_cy 0 def % y word spacing" LN "/_leading [0 0] def" LN "/_ctm matrix def" LN "/_mtx matrix def" LN "/_sp 16#020 def" LN "/_hyphen (-) def" LN "/_fScl 0 def" LN "/_cnt 0 def" LN "/_hs 1 def" LN "/_nativeEncoding 0 def" LN "/_useNativeEncoding 0 def" LN "/_tempEncode 0 def" LN "/_pntr 0 def" LN "% typography operators" LN "/Tx {} def" LN "/Tj {} def" LN "% compound path operators" LN "/CRender {} def" LN "% printing" LN "/_AI3_savepage {} def" LN "% color operands" LN "/_gf null def" LN "/_cf 4 array def" LN "/_if null def" LN "/_of false def" LN "/_fc {} def" LN "/_gs null def" LN "/_cs 4 array def" LN "/_is null def" LN "/_os false def" LN "/_sc {} def" LN "/_i null def" LN "Adobe_IllustratorA_AI3 begin" LN "Adobe_IllustratorA_AI3" LN " {" LN " dup xcheck" LN " {" LN " bind" LN " } if" LN " pop pop" LN " } forall" LN "end" LN "end" LN "Adobe_IllustratorA_AI3 begin" LN "Adobe_IllustratorA_AI3_vars begin" LN "newpath" LN "} def" LN "/terminate % - terminate -" LN "{" LN "end" LN "end" LN "} def" LN "% definition operators" LN "/_ % - _ null" LN "null def" LN "/ddef % key value ddef -" LN "{" LN "Adobe_IllustratorA_AI3_vars 3 1 roll put" LN "} def" LN "/xput % key value literal xput -" LN "{" LN "dup load dup length exch maxlength eq" LN " {" LN " dup dup load dup" LN " length 2 mul dict copy def" LN " } if" LN "load begin def end" LN "} def" LN "/npop % integer npop -" LN "{" LN " {" LN " pop" LN " } repeat" LN "} def" LN "% marking operators" LN "/sw % ax ay string sw x y" LN "{" LN "dup length exch stringwidth" LN "exch 5 -1 roll 3 index 1 sub mul add" LN "4 1 roll 3 1 roll 1 sub mul add" LN "} def" LN "/swj % cx cy fillchar ax ay string swj x y" LN "{" LN "dup 4 1 roll" LN "dup length exch stringwidth" LN "exch 5 -1 roll 3 index 1 sub mul add" LN "4 1 roll 3 1 roll 1 sub mul add" LN "6 2 roll /_cnt 0 ddef" LN "{1 index eq {/_cnt _cnt 1 add ddef} if} forall pop" LN "exch _cnt mul exch _cnt mul 2 index add 4 1 roll 2 index add 4 1 roll pop pop" LN "} def" LN "/ss % ax ay string matrix ss -" LN "{" LN "4 1 roll" LN " { % matrix ax ay char 0 0 {proc} -" LN " 2 npop" LN " (0) exch 2 copy 0 exch put pop" LN " gsave" LN " false charpath currentpoint" LN " 4 index setmatrix" LN " stroke" LN " grestore" LN " moveto" LN " 2 copy rmoveto" LN " } exch cshow" LN "3 npop" LN "} def" LN "/jss % cx cy fillchar ax ay string matrix jss -" LN "{" LN "4 1 roll" LN " { % cx cy fillchar matrix ax ay char 0 0 {proc} -" LN " 2 npop" LN " (0) exch 2 copy 0 exch put" LN " gsave" LN " _sp eq" LN " {" LN " exch 6 index 6 index 6 index 5 -1 roll widthshow" LN " currentpoint" LN " }" LN " {" LN " false charpath currentpoint" LN " 4 index setmatrix stroke" LN " }ifelse" LN " grestore" LN " moveto" LN " 2 copy rmoveto" LN " } exch cshow" LN "6 npop" LN "} def" LN "% path operators" LN "/sp % ax ay string sp -" LN "{" LN " {" LN " 2 npop (0) exch" LN " 2 copy 0 exch put pop" LN " false charpath" LN " 2 copy rmoveto" LN " } exch cshow" LN "2 npop" LN "} def" LN "/jsp % cx cy fillchar ax ay string jsp -" LN "{" LN " { % cx cy fillchar ax ay char 0 0 {proc} -" LN " 2 npop" LN " (0) exch 2 copy 0 exch put" LN " _sp eq" LN " {" LN " exch 5 index 5 index 5 index 5 -1 roll widthshow" LN " }" LN " {" LN " false charpath" LN " }ifelse" LN " 2 copy rmoveto" LN " } exch cshow" LN "5 npop" LN "} def" LN "% path construction operators" LN "/pl % x y pl x y" LN "{" LN "transform" LN "0.25 sub round 0.25 add exch" LN "0.25 sub round 0.25 add exch" LN "itransform" LN "} def" LN "/setstrokeadjust where" LN " {" LN " pop true setstrokeadjust" LN " /c % x1 y1 x2 y2 x3 y3 c -" LN " {" LN " curveto" LN " } def" LN " /C" LN " /c load def" LN " /v % x2 y2 x3 y3 v -" LN " {" LN " currentpoint 6 2 roll curveto" LN " } def" LN " /V" LN " /v load def" LN " /y % x1 y1 x2 y2 y -" LN " {" LN " 2 copy curveto" LN " } def" LN " /Y" LN " /y load def" LN " /l % x y l -" LN " {" LN " lineto" LN " } def" LN " /L" LN " /l load def" LN " /m % x y m -" LN " {" LN " moveto" LN " } def" LN " }" LN " {%else" LN " /c" LN " {" LN " pl curveto" LN " } def" LN " /C" LN " /c load def" LN " /v" LN " {" LN " currentpoint 6 2 roll pl curveto" LN " } def" LN " /V" LN " /v load def" LN " /y" LN " {" LN " pl 2 copy curveto" LN " } def" LN " /Y" LN " /y load def" LN " /l" LN " {" LN " pl lineto" LN " } def" LN " /L" LN " /l load def" LN " /m" LN " {" LN " pl moveto" LN " } def" LN " }ifelse" LN "% graphic state operators" LN "/d % array phase d -" LN "{" LN "setdash" LN "} def" LN "/cf {} def % - cf flatness" LN "/i % flatness i -" LN "{" LN "dup 0 eq" LN " {" LN " pop cf" LN " } if" LN "setflat" LN "} def" LN "/j % linejoin j -" LN "{" LN "setlinejoin" LN "} def" LN "/J % linecap J -" LN "{" LN "setlinecap" LN "} def" LN "/M % miterlimit M -" LN "{" LN "setmiterlimit" LN "} def" LN "/w % linewidth w -" LN "{" LN "setlinewidth" LN "} def" LN "% path painting operators" LN "/H % - H -" LN "{} def" LN "/h % - h -" LN "{" LN "closepath" LN "} def" LN "/N % - N -" LN "{" LN "_pola 0 eq" LN " {" LN " _doClip 1 eq {clip /_doClip 0 ddef} if" LN " newpath" LN " }" LN " {" LN " /CRender {N} ddef" LN " }ifelse" LN "} def" LN "/n % - n -" LN "{N} def" LN "/F % - F -" LN "{" LN "_pola 0 eq" LN " {" LN " _doClip 1 eq" LN " {" LN " gsave _pf grestore clip newpath /_lp /none ddef _fc" LN " /_doClip 0 ddef" LN " }" LN " {" LN " _pf" LN " }ifelse" LN " }" LN " {" LN " /CRender {F} ddef" LN " }ifelse" LN "} def" LN "/f % - f -" LN "{" LN "closepath" LN "F" LN "} def" LN "/S % - S -" LN "{" LN "_pola 0 eq" LN " {" LN " _doClip 1 eq" LN " {" LN " gsave _ps grestore clip newpath /_lp /none ddef _sc" LN " /_doClip 0 ddef" LN " }" LN " {" LN " _ps" LN " }ifelse" LN " }" LN " {" LN " /CRender {S} ddef" LN " }ifelse" LN "} def" LN "/s % - s -" LN "{" LN "closepath" LN "S" LN "} def" LN "/B % - B -" LN "{" LN "_pola 0 eq" LN " {" LN " _doClip 1 eq % F clears _doClip" LN " gsave F grestore" LN " {" LN " gsave S grestore clip newpath /_lp /none ddef _sc" LN " /_doClip 0 ddef" LN " }" LN " {" LN " S" LN " }ifelse" LN " }" LN " {" LN " /CRender {B} ddef" LN " }ifelse" LN "} def" LN "/b % - b -" LN "{" LN "closepath" LN "B" LN "} def" LN "/W % - W -" LN "{" LN "/_doClip 1 ddef" LN "} def" LN "/* % - [string] * -" LN "{" LN "count 0 ne" LN " {" LN " dup type (stringtype) eq {pop} if" LN " } if" LN "_pola 0 eq {newpath} if" LN "} def" LN "% group operators" LN "/u % - u -" LN "{} def" LN "/U % - U -" LN "{} def" LN "/q % - q -" LN "{" LN "_pola 0 eq {gsave} if" LN "} def" LN "/Q % - Q -" LN "{" LN "_pola 0 eq {grestore} if" LN "} def" LN "/*u % - *u -" LN "{" LN "_pola 1 add /_pola exch ddef" LN "} def" LN "/*U % - *U -" LN "{" LN "_pola 1 sub /_pola exch ddef" LN "_pola 0 eq {CRender} if" LN "} def" LN "/D % polarized D -" LN "{pop} def" LN "/*w % - *w -" LN "{} def" LN "/*W % - *W -" LN "{} def" LN "% place operators" LN "/` % matrix llx lly urx ury string ` -" LN "{" LN "/_i save ddef" LN "6 1 roll 4 npop" LN "concat" LN "userdict begin" LN "/showpage {} def" LN "false setoverprint" LN "pop" LN "} def" LN "/~ % - ~ -" LN "{" LN "end" LN "_i restore" LN "} def" LN "% color operators" LN "/O % flag O -" LN "{" LN "0 ne" LN "/_of exch ddef" LN "/_lp /none ddef" LN "} def" LN "/R % flag R -" LN "{" LN "0 ne" LN "/_os exch ddef" LN "/_lp /none ddef" LN "} def" LN "/g % gray g -" LN "{" LN "/_gf exch ddef" LN "/_fc" LN "{" LN "_lp /fill ne" LN " {" LN " _of setoverprint" LN " _gf setgray" LN " /_lp /fill ddef" LN " } if" LN "} ddef" LN "/_pf" LN "{" LN "_fc" LN "fill" LN "} ddef" LN "/_psf" LN "{" LN "_fc" LN "ashow" LN "} ddef" LN "/_pjsf" LN "{" LN "_fc" LN "awidthshow" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "/G % gray G -" LN "{" LN "/_gs exch ddef" LN "/_sc" LN "{" LN "_lp /stroke ne" LN " {" LN " _os setoverprint" LN " _gs setgray" LN " /_lp /stroke ddef" LN " } if" LN "} ddef" LN "/_ps" LN "{" LN "_sc" LN "stroke" LN "} ddef" LN "/_pss" LN "{" LN "_sc" LN "ss" LN "} ddef" LN "/_pjss" LN "{" LN "_sc" LN "jss" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "/k % cyan magenta yellow black k -" LN "{" LN "_cf astore pop" LN "/_fc" LN "{" LN "_lp /fill ne" LN " {" LN " _of setoverprint" LN " _cf aload pop setcmykcolor" LN " /_lp /fill ddef" LN " } if" LN "} ddef" LN "/_pf" LN "{" LN "_fc" LN "fill" LN "} ddef" LN "/_psf" LN "{" LN "_fc" LN "ashow" LN "} ddef" LN "/_pjsf" LN "{" LN "_fc" LN "awidthshow" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "/K % cyan magenta yellow black K -" LN "{" LN "_cs astore pop" LN "/_sc" LN "{" LN "_lp /stroke ne" LN " {" LN " _os setoverprint" LN " _cs aload pop setcmykcolor" LN " /_lp /stroke ddef" LN " } if" LN "} ddef" LN "/_ps" LN "{" LN "_sc" LN "stroke" LN "} ddef" LN "/_pss" LN "{" LN "_sc" LN "ss" LN "} ddef" LN "/_pjss" LN "{" LN "_sc" LN "jss" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "/x % cyan magenta yellow black name gray x -" LN "{" LN "/_gf exch ddef" LN "findcmykcustomcolor" LN "/_if exch ddef" LN "/_fc" LN "{" LN "_lp /fill ne" LN " {" LN " _of setoverprint" LN " _if _gf 1 exch sub setcustomcolor" LN " /_lp /fill ddef" LN " } if" LN "} ddef" LN "/_pf" LN "{" LN "_fc" LN "fill" LN "} ddef" LN "/_psf" LN "{" LN "_fc" LN "ashow" LN "} ddef" LN "/_pjsf" LN "{" LN "_fc" LN "awidthshow" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "/X % cyan magenta yellow black name gray X -" LN "{" LN "/_gs exch ddef" LN "findcmykcustomcolor" LN "/_is exch ddef" LN "/_sc" LN "{" LN "_lp /stroke ne" LN " {" LN " _os setoverprint" LN " _is _gs 1 exch sub setcustomcolor" LN " /_lp /stroke ddef" LN " } if" LN "} ddef" LN "/_ps" LN "{" LN "_sc" LN "stroke" LN "} ddef" LN "/_pss" LN "{" LN "_sc" LN "ss" LN "} ddef" LN "/_pjss" LN "{" LN "_sc" LN "jss" LN "} ddef" LN "/_lp /none ddef" LN "} def" LN "% locked object operator" LN "/A % value A -" LN "{" LN "pop" LN "} def" LN "currentdict readonly pop end" LN "setpacking" LN "% annotate page operator" LN "/annotatepage" LN "{" LN "} def" LN "%%EndResource" LN "%AI3_BeginRider" LN "" LN "%----" LN "% The following statement can be used to set the default flatness for your print job. All" LN "% objects that have a Paint Style with flatness set to 0 will use the flatness specified" LN "% here. If this statement remains commented out, objects painted with flatness" LN "% set to 0 will use the device default." LN "" LN "%@2 setflat" LN "%----" LN "" LN "%----" LN "% The following statements can be used to set the default screen frequency and angle" LN "% for your print job. If these statements remain commented out, then all objects will" LN "% use the device default screen frequency and angle. Note that color printers have" LN "% multiple screen frequencies and angles. See the PostScript Language Reference Manual -" LN "% Second Edition for more information on using halftone screen operators for color printers." LN "" LN "%-- set screen frequency (halftone cells per inch)" LN "%@currentscreen 3 -1 roll pop" LN "%@30 % <- screen frequency" LN "%@3 1 roll setscreen" LN "" LN "%-- set screen angle (degrees)" LN "%@currentscreen 3 -2 roll pop" LN "%@30 % <- screen angle" LN "%@3 2 roll setscreen" LN "%----" LN "" LN "%----" LN "% The following statements can be used to define your own halftone cell spot function" LN "% for your print job. If these statements remain commented out, all objects will" LN "% use the device default halftone cell spot function. Note that a procedure stub" LN "% for defining your own spot function is provided, but you need to provide an implementation" LN "% if you intend to modify the spot function. You should not define spot functions unless" LN "% you're an experienced PostScript language programmer." LN "" LN "%-- set halftone cell spot function" LN "%@currentscreen pop" LN "%@{} % <- halftone cell spot function must be inserted inside curly braces" LN "%@setscreen" LN "%----" LN "" LN "%----" LN "% A simple procedure to print a string at the bottom of a page." LN "% Can be called by annotatepage (see below) if you wish." LN "%" LN "%@/PrintX % string PrintX -" LN "%@{" LN "%@ count 0 gt" LN "%@ {" LN "%@ dup type /stringtype eq" LN "%@ {" LN "%@ /Helvetica findfont 9 scalefont setfont" LN "%@ 36 36 moveto" LN "%@ show" LN "%@ } if" LN "%@ } if" LN "%@} bind def" LN "" LN "%----" LN "% The following procedure is called by the Adobe Illustrator prolog during the print job immediately" LN "% before the showpage operator is executed. You may use this procedure to perform operations like" LN "% placing a logo or other information on each page." LN "" LN "%@/annotatepage" LN "%@{" LN "%@gsave initgraphics" LN "% Insert your PostScript language code between the %=== lines below" LN "%=====================================" LN "%@(From the desk of ) PrintX" LN "%=====================================" LN "%@grestore" LN "%@} def" LN "%----" LN "" LN "" LN "%----" LN "% The following statements define an error handler that prints out diagnostics" LN "% on the output media if the print job fails due to a PostScript error." LN "%" LN "" LN "% Standard Error Handler" LN "" LN "/$brkpage 64 dict def $brkpage begin" LN "/prnt" LN " {dup type/stringtype ne{=string cvs}if dup length 6 mul/tx exch def/ty 10 def" LN " currentpoint/toy exch def/tox exch def 1 setgray newpath" LN " tox toy 2 sub moveto 0 ty rlineto tx 0 rlineto 0 ty neg rlineto" LN " closepath fill tox toy moveto 0 setgray show}bind def" LN "/nl{currentpoint exch pop lmargin exch moveto 0 -10 rmoveto}def" LN "/=={/cp 0 def typeprint nl}def" LN "/typeprint{dup type exec}readonly def" LN "/lmargin 72 def" LN "/rmargin 72 def" LN "/tprint" LN " {dup length cp add rmargin gt{nl/cp 0 def}if" LN " dup length cp add/cp exch def prnt}readonly def" LN "/cvsprint{=string cvs tprint( )tprint}readonly def" LN "/integertype{cvsprint}readonly def" LN "/realtype{cvsprint}readonly def" LN "/booleantype{cvsprint}readonly def" LN "/operatortype{(--)tprint =string cvs tprint(-- )tprint}readonly def" LN "/marktype{pop(-mark- )tprint}readonly def" LN "/dicttype{pop(-dictionary- )tprint}readonly def" LN "/nulltype{pop(-null- )tprint}readonly def" LN "/filetype{pop(-filestream- )tprint}readonly def" LN "/savetype{pop(-savelevel- )tprint}readonly def" LN "/fonttype{pop(-fontid- )tprint}readonly def" LN "/nametype{dup xcheck not{(/)tprint}if cvsprint}readonly def" LN "/stringtype" LN " {dup rcheck{(\\()tprint tprint(\\))tprint}{pop(-string- )tprint}ifelse" LN " }readonly def" LN "/arraytype" LN " {dup rcheck{dup xcheck" LN " {({)tprint{typeprint}forall(})tprint}" LN " {([)tprint{typeprint}forall(])tprint}ifelse}{pop(-array- )tprint}ifelse" LN " }readonly def" LN "/packedarraytype" LN " {dup rcheck{dup xcheck" LN " {({)tprint{typeprint}forall(})tprint}" LN " {([)tprint{typeprint}forall(])tprint}ifelse}{pop(-packedarray- )tprint}ifelse" LN " }readonly def" LN "/courier/Courier findfont 10 scalefont def" LN "end %$brkpage" LN "errordict/handleerror" LN " {systemdict begin $error begin $brkpage begin newerror" LN " {/newerror false store" LN " vmstatus pop pop 0 ne{grestoreall}if initgraphics courier setfont" LN " lmargin 720 moveto(ERROR: )prnt errorname prnt" LN " nl(OFFENDING COMMAND: )prnt/command load prnt" LN " $error/ostack" LN " known{nl nl(STACK:)prnt nl nl $error/ostack get aload length{==}repeat}if" LN " systemdict/showpage get exec(%%[ Error: )print" LN " errorname =print(; OffendingCommand: )print/command" LN " load =print( ]%%)= flush}if end end end}" LN "dup 0 systemdict put dup 4 $brkpage put bind readonly put" LN "%----" LN "" LN "%AI3_EndRider" END_LN } #endif /* RESOURCES_FROM_FILE */