argv@island.uu.net (Dan Heller) (04/11/89)
Submitted-by: David Harrison <davidh@ic.berkeley.edu> Posting-number: Volume 3, Issue 74 Archive-name: xgraph/part05 #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -d ./xgraph-11` then mkdir ./xgraph-11 echo "mkdir ./xgraph-11" fi if `test ! -s ./xgraph-11/dot.11` then echo "writing ./xgraph-11/dot.11" cat > ./xgraph-11/dot.11 << '\End\Of\Shar\' #define dot_width 8 #define dot_height 8 static char dot_bits[] = { 0x00, 0x3c, 0x7e, 0x7e, 0x7e, 0x7e, 0x3c, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/dot.11" fi if `test ! -s ./xgraph-11/hard_devices.c` then echo "writing ./xgraph-11/hard_devices.c" cat > ./xgraph-11/hard_devices.c << '\End\Of\Shar\' /* * Hardcopy Devices * * This file contains the basic output device table. The hardcopy * dialog is automatically constructed from this table. */ #include "copyright.h" #include "hard_devices.h" extern int hpglInit(); extern int psInit(); struct hard_dev hard_devices[] = { { "HPGL", hpglInit, "lpr -P%s", "xgraph.hpgl", "paper", 27.5, "1", 14.0, "1", 12.0 }, { "Postscript", psInit, "lpr -P%s", "xgraph.ps", "lps40", 19.0, "Times-Bold", 18.0, "Times-Roman", 12.0 } }; int hard_count = sizeof(hard_devices)/sizeof(struct hard_dev); \End\Of\Shar\ else echo "will not over write ./xgraph-11/hard_devices.c" fi if `test ! -s ./xgraph-11/hard_devices.h` then echo "writing ./xgraph-11/hard_devices.h" cat > ./xgraph-11/hard_devices.h << '\End\Of\Shar\' /* * Hardcopy Device Header * * This file declares the types required for the hardcopy table * found in hard_devices.c. */ #define MFNAME 25 typedef struct hard_dev { char *dev_name; /* Device name */ int (*dev_init)(); /* Initialization function */ char *dev_spec; /* Default pipe program */ char dev_file[MFNAME]; /* Default file name */ char dev_printer[MFNAME]; /* Default printer name */ double dev_max_dim; /* Default maximum dimension (cm) */ char dev_title_font[MFNAME];/* Default name of title font */ double dev_title_size; /* Default size of title font (pnts) */ char dev_axis_font[MFNAME]; /* Default name of axis font */ double dev_axis_size; /* Default size of axis font (pnts) */ }; extern int hard_count; extern struct hard_dev hard_devices[]; \End\Of\Shar\ else echo "will not over write ./xgraph-11/hard_devices.h" fi if `test ! -s ./xgraph-11/hpgl.c` then echo "writing ./xgraph-11/hpgl.c" cat > ./xgraph-11/hpgl.c << '\End\Of\Shar\' #define MAPX(state,x) ( (x) + P1X + state->clipminX ) #define MAPY(state,y) ( MAXY - (y) + P1Y - state->clipminY) #include "copyright.h" #include "xgout.h" #include "plotter.h" #include <stdio.h> #include <math.h> #define MAX(a,b) ( ((a)>(b)) ? (a) : (b) ) #define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) char *malloc(); extern void exit(); extern void free(); static void hpglText(); static void hpglSeg(); static void hpglDot(); static void hpglEnd(); static xgOut hpglInfo = { D_COLOR, /* device characteristics */ MAXX, /* width */ MAXY, /* height */ 200, /* border padding */ 0, /* extra space around axis labels */ 250, /* tick length - approx 1/4 inch */ 50, /* spacing above legend lables */ 0, /* axis font width */ 0, /* axis font height */ 0, /* title font width */ 0, /* title font height */ 1000000,/* maximum number of segments */ hpglText, /* text output function */ hpglSeg, /* segment drawing function */ hpglDot, /* dot/marker drawing function */ hpglEnd, /* end of plot function */ NULL, /* userInfo */ }; typedef struct { double axis_w; double axis_h; double title_w; double title_h; FILE *plotterFile; int clipminX; int clipminY; int clipmaxX; int clipmaxY; } mydata; int hpglInit(stream,width,height,title_family, title_size, axis_family, axis_size, outInfo,errmsg) FILE *stream; /* output stream */ int width; /* desired width of space in microns */ int height; /* desired height in microns */ char *title_family; /* name of font for titles */ double title_size; /* size of font for titles */ char *axis_family; /* name of font for axes */ double axis_size; /* size of font for axes */ xgOut *outInfo; /* my structure */ char errmsg[ERRBUFSIZE]; /* a place to complain to */ { char *cmd; mydata *myInfo; myInfo = (mydata*)malloc(sizeof(mydata)); if(myInfo == NULL) return(NULL); *outInfo = hpglInfo; outInfo->area_w = MIN(MAXX,width/25); outInfo->area_h = MIN(MAXY,height/25); /* magic formulas: input sizes are in points = 1/72 inch */ /* my sizes are in cm */ /* plotter units are in units of .025mm ~= 1/1016 inch */ /* have to warn of height 1.5 times larger or get bitten by plotter's internal padding */ /* widths are (arbitrarily) selected to be 2/3 of the height */ /* (cancels with width factor) */ myInfo->axis_w = axis_size * .666 * 2.54/72.; myInfo->axis_h = axis_size * 2.54/72.; myInfo->title_w = title_size * .666 * 2.54/72.; myInfo->title_h = title_size * 2.54/72.; outInfo->axis_pad = axis_size*1016.*1.5/72.; outInfo->axis_width = axis_size*1016.*1.5/72.; outInfo->axis_height = axis_size*1016.*.666/72.; outInfo->title_width = title_size*1016.*1.5/72.; outInfo->title_height = title_size*1016.*.666/72.; outInfo->user_state = (char *)myInfo; myInfo->plotterFile = stream; myInfo->clipminX = 0; myInfo->clipminY = 0; myInfo->clipmaxX = MAXX; myInfo->clipmaxY = MAXY; fprintf(myInfo->plotterFile,"PG;IN;\n"); fprintf(myInfo->plotterFile,"DI1,0;\n"); fprintf(myInfo->plotterFile,"IW%d,%d,%d,%d;\n",MAPX(myInfo,0), MAPY(myInfo,myInfo->clipmaxY-myInfo->clipminY), MAPX(myInfo,myInfo->clipmaxX-myInfo->clipminX), MAPY(myInfo,0)); return(1); } static void hpglClip(userState,ulx,uly,lrx,lry) mydata *userState; /* my state information */ int ulx,uly,lrx,lry; /* corners of plotting area */ { userState->clipminX = ulx; userState->clipminY = uly; userState->clipmaxX = lrx; userState->clipmaxY = lry; fprintf(userState->plotterFile,"IW%d,%d,%d,%d;\n",MAPX(userState,0), MAPY(userState,userState->clipmaxY-userState->clipminY), MAPX(userState,userState->clipmaxX-userState->clipminX), MAPY(userState,0)); return; } static void hpglText(userState,x,y,text,just,style) mydata *userState; /* my state information */ int x,y; /* coords of text origin */ char *text; /* what to put there */ int just; /* how to justify */ /* where the origin is relative to where the text should go * as a function of the various values of just T_UPPERLEFT T_TOP T_UPPERRIGHT T_LEFT T_CENTER T_RIGHT T_LOWERLEFT T_BOTTOM T_LOWERRIGHT */ int style; /* T_AXIS = axis font, T_TITLE = title font */ { fprintf(userState->plotterFile,"PU;SP%d;",TEXTCOLOR); fprintf(userState->plotterFile,"PA%d,%d;",MAPX(userState,x),MAPY(userState,y)); switch(style) { case T_AXIS: fprintf(userState->plotterFile,"SI%f,%f;",userState->axis_w,userState->axis_h); break; case T_TITLE: fprintf(userState->plotterFile,"SI%f,%f;",userState->title_w,userState->title_h); break; default: printf("bad text style %d in hpglText\n",style); exit(1); break; } switch(just) { case T_UPPERLEFT: fprintf(userState->plotterFile,"LO3;\n"); break; case T_TOP: fprintf(userState->plotterFile,"LO6;\n"); break; case T_UPPERRIGHT: fprintf(userState->plotterFile,"LO9;\n"); break; case T_LEFT: fprintf(userState->plotterFile,"LO2;\n"); break; case T_CENTER: fprintf(userState->plotterFile,"LO5;\n"); break; case T_RIGHT: fprintf(userState->plotterFile,"LO8;\n"); break; case T_LOWERLEFT: fprintf(userState->plotterFile,"LO1;\n"); break; case T_BOTTOM: fprintf(userState->plotterFile,"LO4;\n"); break; case T_LOWERRIGHT: fprintf(userState->plotterFile,"LO7;\n"); break; default: printf("bad justification type %d in hpglText\n",just); exit(1); break; } fprintf(userState->plotterFile,"LB%s\03;",text); } static int penselect[8] = { PEN1, PEN2, PEN3, PEN4, PEN5, PEN6, PEN7, PEN8}; static int lineselect[8] = { LINE1, LINE2, LINE3, LINE4, LINE5, LINE6, LINE7, LINE8}; static void hpglSeg(userState,ns,segs,width,style,lappr,color) mydata *userState; /* my state information (not used) */ int ns; /* number of segments */ XSegment *segs; /* X array of segments */ int width; /* width of lines in pixels */ int style; /* L_VAR = dotted, L_AXIS = grid, L_ZERO = axis*/ int lappr; /* line style */ int color; /* line color */ { int i; if (style == L_ZERO) { fprintf(userState->plotterFile,"SP%d;",PENAXIS); /* select correct pen */ fprintf(userState->plotterFile,"LT;"); /* solid line style */ } else if (style == L_AXIS) { fprintf(userState->plotterFile,"SP%d;",PENGRID); /* select correct pen */ fprintf(userState->plotterFile,"LT;"); /* solid line style */ } else if (style == L_VAR) { if( (color < 0) || (color >7) ) { printf("out of range line color %d in hpglLine\n",color); exit(1); } fprintf(userState->plotterFile,"SP%d;",penselect[color]); /* select correct pen */ if( (lappr < 0) || (lappr >7) ) { printf("out of range line style %d in hpglLine\n",lappr); exit(1); } if(lappr == 0) { fprintf(userState->plotterFile,"LT;");/*select solid line type*/ } else { fprintf(userState->plotterFile,"LT%d;",lineselect[lappr]);/*select line type*/ } } else { printf("unknown style %d in hpglLine\n",style); exit(1); } for(i=0;i<ns;i++) { if(!i || ( (segs[i].x1!=segs[i-1].x2) || (segs[i].y1!=segs[i-1].y2) ) ){ /* MOVE */ fprintf(userState->plotterFile,"PU;PA%d,%d;\n",MAPX(userState,segs[i].x1), MAPY(userState,segs[i].y1)); } /* DRAW */ if(width <= 1) { fprintf(userState->plotterFile,"PD;PA%d,%d;\n",MAPX(userState,segs[i].x2), MAPY(userState,segs[i].y2)); } else { /* ugly - wide lines -> rectangles */ double frac; int lx,ly; int urx,ury,ulx,uly,llx,lly,lrx,lry; frac = (width/2)/sqrt((double) ((segs[i].x1-segs[i].x2)* (segs[i].x1-segs[i].x2))+ ((segs[i].y1-segs[i].y2)* (segs[i].y1-segs[i].y2)) ); lx = frac * (segs[i].y2 - segs[i].y1); ly = -frac * (segs[i].x2 - segs[i].x1); urx = segs[i].x2 +lx; ury = segs[i].y2 +ly; ulx = segs[i].x2 -lx; uly = segs[i].y2 -ly; llx = segs[i].x1 -lx; lly = segs[i].y1 -ly; lrx = segs[i].x1 +lx; lry = segs[i].y1 +ly; fprintf(userState->plotterFile,"PU;PA%d,%d;",MAPX(userState,llx), MAPY(userState,lly)); fprintf(userState->plotterFile,"PM0;"); fprintf(userState->plotterFile,"PD,PA%d,%D;PA%d,%D;PA%d,%d;\n", MAPX(userState,lrx),MAPY(userState,lry), MAPX(userState,urx),MAPY(userState,ury), MAPX(userState,ulx),MAPY(userState,uly) ); fprintf(userState->plotterFile,"PM2;FP;EP;"); } } fprintf(userState->plotterFile,"PU;"); } static char *markselect[8] = { MARK1, MARK2, MARK3, MARK4, MARK5, MARK6, MARK7, MARK8}; static void hpglDot(userState,x,y,style,type,color) mydata *userState; /* my state information (not used) */ int x,y; /* coord of dot */ int style; /* type of dot */ int type; /* dot style variation */ int color; /* color of dot */ { /* move to given coord */ fprintf(userState->plotterFile,"PU;PA%d,%d;\n",MAPX(userState,x), MAPY(userState,y)); if( (color<0) || (color>7) ) { printf("unknown color %d in hpglDot\n",color); exit(1); } fprintf(userState->plotterFile,"SP%d;",penselect[color]); if(style == P_PIXEL) { fprintf(userState->plotterFile,"PD;PU;\n"); } else if (style == P_DOT) { fprintf(userState->plotterFile,"LT;PM0;CI40;PM2;FT;EP;\n"); } else if (style == P_MARK) { if( (type<0) || (type>7) ) { printf("unknown marker type %d in hpglDot\n",type); exit(1); } /*fprintf(userState->plotterFile,"LT;CA5;LO4;SI0.1;LB%s\03;\n",markselect[type]);*/ fprintf(userState->plotterFile,"LT;CS5;LO4;SI0.15;SM%s;PR0,0;SM;CS;\n",markselect[type]); } else { printf("unknown marker style %d in hpglDot\n",style); exit(1); } } static void hpglEnd(userState) mydata *userState; /* my state information (not used) */ { fprintf(userState->plotterFile,"SP;PG;IN;\n"); fflush(userState->plotterFile); return; } \End\Of\Shar\ else echo "will not over write ./xgraph-11/hpgl.c" fi if `test ! -s ./xgraph-11/mark1.11` then echo "writing ./xgraph-11/mark1.11" cat > ./xgraph-11/mark1.11 << '\End\Of\Shar\' #define mark1_width 8 #define mark1_height 8 #define mark1_x_hot 3 #define mark1_y_hot 3 static char mark1_bits[] = { 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark1.11" fi if `test ! -s ./xgraph-11/mark2.11` then echo "writing ./xgraph-11/mark2.11" cat > ./xgraph-11/mark2.11 << '\End\Of\Shar\' #define mark2_width 8 #define mark2_height 8 #define mark2_x_hot 3 #define mark2_y_hot 3 static char mark2_bits[] = { 0x00, 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark2.11" fi if `test ! -s ./xgraph-11/mark3.11` then echo "writing ./xgraph-11/mark3.11" cat > ./xgraph-11/mark3.11 << '\End\Of\Shar\' #define mark3_width 8 #define mark3_height 8 #define mark3_x_hot 3 #define mark3_y_hot 3 static char mark3_bits[] = { 0x00, 0x1c, 0x36, 0x22, 0x36, 0x1c, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark3.11" fi if `test ! -s ./xgraph-11/mark4.11` then echo "writing ./xgraph-11/mark4.11" cat > ./xgraph-11/mark4.11 << '\End\Of\Shar\' #define mark4_width 8 #define mark4_height 8 #define mark4_x_hot 3 #define mark4_y_hot 3 static char mark4_bits[] = { 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark4.11" fi if `test ! -s ./xgraph-11/mark5.11` then echo "writing ./xgraph-11/mark5.11" cat > ./xgraph-11/mark5.11 << '\End\Of\Shar\' #define mark5_width 8 #define mark5_height 8 #define mark5_x_hot 3 #define mark5_y_hot 3 static char mark5_bits[] = { 0x00, 0x08, 0x14, 0x22, 0x14, 0x08, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark5.11" fi if `test ! -s ./xgraph-11/mark6.11` then echo "writing ./xgraph-11/mark6.11" cat > ./xgraph-11/mark6.11 << '\End\Of\Shar\' #define mark6_width 8 #define mark6_height 8 #define mark6_x_hot 3 #define mark6_y_hot 3 static char mark6_bits[] = { 0x00, 0x1c, 0x14, 0x1c, 0x14, 0x1c, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark6.11" fi if `test ! -s ./xgraph-11/mark7.11` then echo "writing ./xgraph-11/mark7.11" cat > ./xgraph-11/mark7.11 << '\End\Of\Shar\' #define mark7_width 8 #define mark7_height 8 #define mark7_x_hot 3 #define mark7_y_hot 3 static char mark7_bits[] = { 0x00, 0x1c, 0x2a, 0x36, 0x2a, 0x1c, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark7.11" fi if `test ! -s ./xgraph-11/mark8.11` then echo "writing ./xgraph-11/mark8.11" cat > ./xgraph-11/mark8.11 << '\End\Of\Shar\' #define mark8_width 8 #define mark8_height 8 #define mark8_x_hot 3 #define mark8_y_hot 3 static char mark8_bits[] = { 0x00, 0x3e, 0x1c, 0x08, 0x1c, 0x3e, 0x00, 0x00}; \End\Of\Shar\ else echo "will not over write ./xgraph-11/mark8.11" fi if `test ! -s ./xgraph-11/new_ps.c` then echo "writing ./xgraph-11/new_ps.c" cat > ./xgraph-11/new_ps.c << '\End\Of\Shar\' /* * Postscript output for xgraph * * Rick Spickelmier * David Harrison */ #include "copyright.h" #include <stdio.h> #include "xgout.h" /* * Basic scaling parameters */ #define VDPI 1200.0 #define LDIM 11.0 #define SDIM 8.5 #define MICRONS_PER_INCH 2.54E+04 #define POINTS_PER_INCH 72.0 #define INCHES_PER_POINT 1.0/72.0 /* * Aesthetic parameters (inches) */ #define PS_BDR_PAD 0.075 #define PS_AXIS_PAD 0.1 #define PS_LEG_PAD 0.025 #define PS_TICK_LEN 0.125 #define BASE_DASH (1.0/48.0) #define BASE_WIDTH (1.0/8.0) #define PS_AXIS_WBASE 1 #define PS_ZERO_WBASE 4 #define PS_DATA_WBASE 7 #define PS_PIXEL 4 #define PS_DOT 12 #define PS_MARK 12 /* * Other constants */ #define FONT_WIDTH_EST 0.55 #define PS_MAX_SEGS 1000 #define PS_NO_TSTYLE -1 #define PS_NO_DSTYLE -1 #define PS_NO_WIDTH -1 #define PS_NO_LSTYLE -1 /* * Working macros */ #define OUT (void) fprintf #define PS(str) OUT(psFile, str) #define PSU(str) OUT(ui->psFile, str) #define IY(val) (ui->height_devs - val) #define MAX(a, b) ((a) > (b) ? (a) : (b)) /* * Globals */ static double PS_scale; /* devs/micron */ /* * Externals and forwards */ extern char *malloc(); static void psScale(), psFonts(), psMarks(), psText(), psSeg(), psDot(), psEnd(); /* * Local structures */ struct userInfo { FILE *psFile; int currentTextStyle; int currentDashStyle; int currentWidth; int currentLStyle; int baseWidth; int height_devs; char *title_family; double title_size; char *axis_family; double axis_size; }; int rd(dbl) double dbl; /* Short and sweet rounding function */ { if (dbl < 0.0) { return ((int) (dbl - 0.5)); } else { return ((int) (dbl + 0.5)); } } /*ARGSUSED*/ int psInit(psFile, width, height, tf, ts, af, as, outInfo, errmsg) FILE *psFile; /* Output file */ int width, height; /* In microns */ char *tf, *af; /* Title and axis font */ double ts, as; /* Title and axis size */ xgOut *outInfo; /* Returned device info */ char errmsg[ERRBUFSIZE]; /* Returned error message */ /* * The basic coordinate system is points (roughly 1/72 inch). * However, most laser printers can do much better than that. * We invent a coordinate system based on VDPI dots per inch. * This goes along the long side of the page. The long side * of the page is LDIM inches in length, the short side * SDIM inches in length. We we call this unit a `dev'. * We map `width' and `height' into devs. */ { struct userInfo *ui; double font_size; ui = (struct userInfo *) malloc(sizeof(struct userInfo)); ui->psFile = psFile; ui->currentTextStyle = PS_NO_TSTYLE; ui->currentDashStyle = PS_NO_DSTYLE; ui->currentWidth = PS_NO_WIDTH; ui->currentLStyle = PS_NO_LSTYLE; ui->title_family = tf; ui->title_size = ts; ui->axis_family = af; ui->axis_size = as; /* Roughly, one-eighth a point in devs */ ui->baseWidth = rd( VDPI / POINTS_PER_INCH * BASE_WIDTH ); PS_scale = VDPI / MICRONS_PER_INCH; outInfo->dev_flags = 0; outInfo->area_w = rd( ((double) width) * PS_scale ); outInfo->area_h = rd( ((double) height) * PS_scale ); ui->height_devs = outInfo->area_h; outInfo->bdr_pad = rd( PS_BDR_PAD * VDPI ); outInfo->axis_pad = rd( PS_AXIS_PAD * VDPI ); outInfo->legend_pad = rd( PS_LEG_PAD * VDPI ); outInfo->tick_len = rd( PS_TICK_LEN * VDPI ); /* Font estimates */ font_size = as * INCHES_PER_POINT * VDPI; outInfo->axis_height = rd( font_size ); outInfo->axis_width = rd( font_size * FONT_WIDTH_EST ); font_size = ts * INCHES_PER_POINT * VDPI; outInfo->title_height = rd( font_size ); outInfo->title_width = rd( font_size * FONT_WIDTH_EST ); outInfo->max_segs = PS_MAX_SEGS; outInfo->xg_text = psText; outInfo->xg_seg = psSeg; outInfo->xg_dot = psDot; outInfo->xg_end = psEnd; outInfo->user_state = (char *) ui; /* Header */ PS("%%!\n"); PS("%% Xgraph postscript output\n"); PS("%% Rick Spickelmier and David Harrison\n"); PS("%% University of California, Berkeley\n"); PS("%%\n"); /* Definitions */ psScale(psFile, width, height); psFonts(psFile); psMarks(psFile); PS("%%\n%% Main body begins here\n%%\n"); return 1; } static void psScale(psFile, width, height) FILE *psFile; /* Output stream */ int width; /* Output width */ int height; /* Output height */ /* * This routine figures out how transform the basic postscript * transformation into one suitable for direct use by * the drawing primitives. Two variables X-CENTER-PLOT * and Y-CENTER-PLOT determine whether the plot is centered * on the page. */ { double factor; double pnt_width, pnt_height; PS("%% Scaling information\n"); PS("%%\n"); PS("%% Change these if you would like to change the centering\n"); PS("%% of the plot in either dimension\n"); PS("/X-CENTER-PLOT 1 def\n"); PS("/Y-CENTER-PLOT 1 def\n"); PS("%%\n"); /* * Determine page size */ PS("%% Page size computation\n"); PS("clippath pathbbox\n"); PS("/page-height exch def\n"); PS("/page-width exch def\n"); PS("pop pop\n"); /* * First: rotation. If the width is greater than the short * dimension, do the rotation. */ pnt_width = ((double) width) / MICRONS_PER_INCH * POINTS_PER_INCH; pnt_height = ((double) height) / MICRONS_PER_INCH * POINTS_PER_INCH; PS("%% Determine whether rotation is required\n"); OUT(psFile, "%lg page-width gt\n", pnt_width); PS("{ %% Rotation required\n"); PS(" 90 rotate\n"); PS(" 0 page-width neg translate\n"); PS(" %% Handle centering\n"); PS(" Y-CENTER-PLOT 1 eq { %% Center in y\n"); OUT(psFile, " page-height %lg sub 2 div\n", pnt_width); PS(" } { %% Don't center in y\n"); PS(" 0\n"); PS(" } ifelse\n"); PS(" X-CENTER-PLOT 1 eq { %% Center in x\n"); OUT(psFile, " page-width %lg sub 2 div\n", pnt_height); PS(" } { %% Don't center in x\n"); PS(" 0\n"); PS(" } ifelse\n"); PS(" translate\n"); PS("} { %% No rotation - just handle centering\n"); PS(" X-CENTER-PLOT 1 eq { %% Center in x\n"); OUT(psFile, " page-width %lg sub 2 div\n", pnt_width); PS(" } { %% Don't center in x\n"); PS(" 0\n"); PS(" } ifelse\n"); PS(" Y-CENTER-PLOT 1 eq { %% Center in y\n"); OUT(psFile, " page-height %lg sub 2 div\n", pnt_height); PS(" } { %% Don't center in y\n"); PS(" 0\n"); PS(" } ifelse\n"); PS(" translate\n"); PS("} ifelse\n"); /* * Now: scaling. We have points. We want devs. */ factor = POINTS_PER_INCH / VDPI; PS("%% Set the scale\n"); OUT(psFile, "%lg %lg scale\n", factor, factor); } static void psFonts(psFile) FILE *psFile; /* Output stream */ /* * Downloads code for drawing title and axis labels */ { PS("%% Font Handling Functions\n"); PS("%%\n"); PS("%% Function giving y-offset to center of font\n"); PS("%% Assumes font is set and uses numbers to gauge center\n"); PS("%%\n"); PS("/choose-font %% stack: fontsize fontname => ---\n"); PS("{\n"); PS(" findfont \n"); PS(" exch scalefont \n"); PS(" setfont\n"); PS(" newpath\n"); PS(" 0 0 moveto (0) true charpath flattenpath pathbbox\n"); PS(" /top exch def pop\n"); PS(" /bottom exch def pop\n"); PS(" bottom top bottom top add 2 div\n"); PS(" /center-font-val exch def \n"); PS(" /upper-font-val exch def \n"); PS(" /lower-font-val exch def\n"); PS("} def\n"); PS("%%\n"); PS("%% Justfication offset routines\n"); PS("%%\n"); PS("/center-x-just %% stack: (string) x y => (string) newx y\n"); PS("{\n"); PS(" exch 2 index stringwidth pop 2 div sub exch\n"); PS("} def\n"); PS("%%\n"); PS("/left-x-just %% stack: (string) x y => (string) newx y\n"); PS("{ \n"); PS("} def\n"); PS("%%\n"); PS("/right-x-just %% stack: (string) x y => (string) newx y\n"); PS("{\n"); PS(" exch 2 index stringwidth pop sub exch\n"); PS("} def\n"); PS("%%\n"); PS("/center-y-just %% stack: (string) x y => (string) x newy\n"); PS("{\n"); PS(" center-font-val sub\n"); PS("} def\n"); PS("%%\n"); PS("/lower-y-just %% stack: (string) x y => (string) x newy\n"); PS("{\n"); PS(" lower-font-val sub\n"); PS("} def\n"); PS("%%\n"); PS("/upper-y-just %% stack: (string) x y => (string) x newy\n"); PS("{\n"); PS(" upper-font-val sub\n"); PS("} def\n"); PS("%%\n"); PS("%% Shows a string on the page subject to justification\n"); PS("%% \n"); PS("/just-string %% stack: (string) x y just => ---\n"); PS("{\n"); PS(" dup 0 eq { pop center-x-just center-y-just } if\n"); PS(" dup 1 eq { pop left-x-just center-y-just } if\n"); PS(" dup 2 eq { pop left-x-just upper-y-just } if\n"); PS(" dup 3 eq { pop center-x-just upper-y-just } if\n"); PS(" dup 4 eq { pop right-x-just upper-y-just } if\n"); PS(" dup 5 eq { pop right-x-just center-y-just } if\n"); PS(" dup 6 eq { pop right-x-just lower-y-just } if\n"); PS(" dup 7 eq { pop center-x-just lower-y-just } if\n"); PS(" dup 8 eq { pop left-x-just lower-y-just } if\n"); PS(" moveto show\n"); PS("} def\n"); PS("%%\n"); } static void psMarks(psFile) FILE *psFile; /* * Writes out marker definitions */ { PS("%% Marker definitions\n"); PS("/mark0 {/size exch def /y exch def /x exch def\n"); PS("newpath x size sub y size sub moveto\n"); PS("size size add 0 rlineto 0 size size add rlineto\n"); PS("0 size size add sub 0 rlineto closepath fill} def\n"); PS("/mark1 {/size exch def /y exch def /x exch def\n"); PS("newpath x size sub y size sub moveto\n"); PS("size size add 0 rlineto 0 size size add rlineto\n"); PS("0 size size add sub 0 rlineto closepath stroke} def\n"); PS("/mark2 {/size exch def /y exch def /x exch def\n"); PS("newpath x y moveto x y size 0 360 arc stroke} def\n"); PS("/mark3 {/size exch def /y exch def /x exch def\n"); PS("newpath x size sub y size sub moveto x size add y size add lineto\n"); PS("x size sub y size add moveto x size add y size sub lineto stroke} def\n"); PS("/mark4 {/size exch def /y exch def /x exch def\n"); PS("newpath x size sub y moveto x y size add lineto\n"); PS("x size add y lineto x y size sub lineto\n"); PS("closepath stroke} def\n"); PS("/mark5 {/size exch def /y exch def /x exch def\n"); PS("x y size mark1\n"); PS("newpath x size sub y moveto size size add 0 rlineto stroke} def\n"); PS("/mark6 {/size exch def /y exch def /x exch def\n"); PS("newpath x y moveto x y size 0 360 arc fill} def\n"); PS("/mark7 {/size exch def /y exch def /x exch def\n"); PS("newpath x y moveto x size sub y size sub lineto\n"); PS("x size add y size sub lineto closepath fill\n"); PS("newpath x y moveto x size add y size add lineto\n"); PS("x size sub y size add lineto closepath fill} def\n"); } static void psText(state, x, y, text, just, style) char *state; /* Really (struct userInfo *) */ int x, y; /* Text position (devs) */ char *text; /* Text itself */ int just; /* Justification */ int style; /* Style */ /* * Draws text at the given location with the given justification * and style. */ { struct userInfo *ui = (struct userInfo *) state; if (style != ui->currentTextStyle) { switch (style) { case T_AXIS: OUT(ui->psFile, "%lg /%s choose-font\n", ui->axis_size * INCHES_PER_POINT * VDPI, ui->axis_family); break; case T_TITLE: OUT(ui->psFile, "%lg /%s choose-font\n", ui->title_size * INCHES_PER_POINT * VDPI, ui->title_family); break; } ui->currentTextStyle = style; } OUT(ui->psFile, "(%s) %d %d %d just-string\n", text, x, IY(y), just); } /*ARGSUSED*/ static void psSeg(state, ns, seglist, width, style, lappr, color) char *state; /* Really (struct userInfo *) */ int ns; /* Number of segments */ XSegment *seglist; /* X array of segments */ int width; /* Width of lines (devcoords) */ int style; /* L_AXIS, L_ZERO, L_VAR */ int lappr; /* Zero to seven */ int color; /* Zero to seven */ /* * Draws a number of line segments. Grid lines are drawn using * light lines. Variable lines (L_VAR) are drawn wider. This * version ignores the color argument. */ { struct userInfo *ui = (struct userInfo *) state; int newwidth, i; if ((style != ui->currentLStyle) || (width != ui->currentWidth)) { switch (style) { case L_AXIS: newwidth = PS_AXIS_WBASE * ui->baseWidth; PSU("[] 0 setdash\n"); break; case L_ZERO: newwidth = PS_ZERO_WBASE * ui->baseWidth; PSU("[] 0 setdash\n"); break; case L_VAR: newwidth = PS_DATA_WBASE * ui->baseWidth; break; } ui->currentWidth = MAX(newwidth, width); ui->currentLStyle = style; OUT(ui->psFile, "%d setlinewidth\n", ui->currentWidth); } if ((lappr != ui->currentDashStyle) && (style == L_VAR)) { if (lappr == 0) { PSU("[] 0 setdash\n"); } else { OUT(ui->psFile, "[%lg] 0 setdash\n", ((double) lappr) * BASE_DASH * VDPI); } ui->currentDashStyle = lappr; } PSU("newpath\n"); OUT(ui->psFile, " %d %d moveto\n", seglist[0].x1, IY(seglist[0].y1)); OUT(ui->psFile, " %d %d lineto\n", seglist[0].x2, IY(seglist[0].y2)); for (i = 1; i < ns; i++) { if ((seglist[i].x1 != seglist[i-1].x2) || (seglist[i].y1 != seglist[i-1].y2)) { OUT(ui->psFile, " %d %d moveto\n", seglist[i].x1, IY(seglist[i].y1)); } OUT(ui->psFile, " %d %d lineto\n", seglist[i].x2, IY(seglist[i].y2)); } PSU("stroke\n"); } /*ARGSUSED*/ static void psDot(state, x, y, style, type, color) char *state; /* state information */ int x,y; /* coord of dot */ int style; /* type of dot */ int type; /* dot style variation */ int color; /* color of dot */ /* * Prints out a dot at the given location */ { struct userInfo *ui = (struct userInfo *) state; if (ui->currentDashStyle != PS_NO_DSTYLE) { OUT(ui->psFile, "[] 0 setdash "); ui->currentDashStyle = PS_NO_DSTYLE; } if (ui->currentWidth != PS_ZERO_WBASE * ui->baseWidth) { ui->currentWidth = PS_ZERO_WBASE * ui->baseWidth; OUT(ui->psFile, "%d setlinewidth ", ui->currentWidth); } switch (style) { case P_PIXEL: OUT(ui->psFile, "newpath %d %d moveto %d %d %d 0 360 arc fill\n", x, IY(y), x, IY(y), PS_PIXEL * ui->baseWidth); break; case P_DOT: OUT(ui->psFile, "newpath %d %d moveto %d %d %d 0 360 arc fill\n", x, IY(y), x, IY(y), PS_DOT * ui->baseWidth); break; case P_MARK: OUT(ui->psFile, "%d %d %d mark%d\n", x, IY(y), PS_MARK * ui->baseWidth, type); break; } return; } static void psEnd(userState) char *userState; /* state information */ { struct userInfo *ui = (struct userInfo *) userState; PSU("showpage\n"); } \End\Of\Shar\ else echo "will not over write ../xgraph-11/new_ps.c" fi if `test ! -s ./xgraph-11/plotter.h` then echo "writing ./xgraph-11/plotter.h" cat > ./xgraph-11/plotter.h << '\End\Of\Shar\' /* * HP plotter definition - these are dependent on the * SPECIFIC MODEL of HP plotter used, and should always * be modified when going to a new plotter. * * all dimensions are in plotter units. * * MINX and MINY are the smallest x and y values that * are inside the soft clip limits of the plotter * MAXX and MAXY are the largest x and y values that * are inside the soft clip limits of the plotter MINUS * MINX and MINY, so they give the dimension of the * soft clip area. * * PLOTTERTYPE is a character string which identifies the * plotter that should be used. control information will * be read for ~cad/lib/technology/$TECHNOLOGY/$PLOTTERTYPE.map * and output will go to /usr/ucb/lpr -Pplt$PLOTTERTYPE * */ #define PLOTTERTYPE "7550" #define P1X 80 #define P1Y 320 #define P2X 10080 #define P2Y 7520 #define MAXX 10000 #define MAXY 7200 #define PLOTTERNAME "paper" #define PENGRID 1 #define PENAXIS 2 #define TEXTCOLOR 1 #define PEN1 3 #define PEN2 4 #define PEN3 5 #define PEN4 6 #define PEN5 7 #define PEN6 8 #define PEN7 2 #define PEN8 1 #define LINE1 2 #define LINE2 4 #define LINE3 5 #define LINE4 6 #define LINE5 2 #define LINE6 4 #define LINE7 5 #define LINE8 6 #define MARK1 "L" #define MARK2 "K" #define MARK3 "M" #define MARK4 "O" #define MARK5 "G" #define MARK6 "F" #define MARK7 "E" #define MARK8 "A" \End\Of\Shar\ else echo "will not over write ./xgraph-11/plotter.h" fi if `test ! -s ./xgraph-11/plotter.try1.h` then echo "writing ./xgraph-11/plotter.try1.h" cat > ./xgraph-11/plotter.try1.h << '\End\Of\Shar\' /* * HP plotter definition - these are dependent on the * SPECIFIC MODEL of HP plotter used, and should always * be modified when going to a new plotter. * * all dimensions are in plotter units. * * MINX and MINY are the smallest x and y values that * are inside the soft clip limits of the plotter * MAXX and MAXY are the largest x and y values that * are inside the soft clip limits of the plotter MINUS * MINX and MINY, so they give the dimension of the * soft clip area. * * PLOTTERTYPE is a character string which identifies the * plotter that should be used. control information will * be read for ~cad/lib/technology/$TECHNOLOGY/$PLOTTERTYPE.map * and output will go to /usr/ucb/lpr -Pplt$PLOTTERTYPE * */ #define PLOTTERTYPE "7550" #define P1X 80 #define P1Y 320 #define P2X 10080 #define P2Y 7520 #define MAXX 10000 #define MAXY 7200 #define AFW 0.15 #define AFH 0.225 #define TFW 0.3 #define TFH 0.45 #define MAPX(x) ( (x) + P1X + clipminX ) #define MAPY(y) ( MAXY - (y) + P1Y - clipminY) #define PLOTTERNAME "paper" #define PENGRID 1 #define PENAXIS 2 #define TEXTCOLOR 1 #define PEN1 3 #define PEN2 4 #define PEN3 5 #define PEN4 6 #define PEN5 7 #define PEN6 8 #define PEN7 2 #define PEN8 1 #define LINE1 2 #define LINE2 4 #define LINE3 5 #define LINE4 6 #define LINE5 2 #define LINE6 4 #define LINE7 5 #define LINE8 6 #define MARK1 "L" #define MARK2 "K" #define MARK3 "M" #define MARK4 "O" #define MARK5 "G" #define MARK6 "F" #define MARK7 "E" #define MARK8 "A" \End\Of\Shar\ else echo "will not over write ./xgraph-11/plotter.try1.h" fi if `test ! -s ./xgraph-11/xgX.c` then echo "writing ./xgraph-11/xgX.c" cat > ./xgraph-11/xgX.c << '\End\Of\Shar\' /* * Generic Output Driver for X * X version 11 * * This is the primary output driver used by the new X graph * to display output to the X server. It has been factored * out of the original xgraph to allow mulitple hardcopy * output devices to share xgraph's capabilities. Note: * xgraph is still heavily X oriented. This is not intended * for porting to other window systems. */ #include "copyright.h" #include "xgout.h" #include "xgraph.h" #define PADDING 2 #define SPACE 10 #define TICKLENGTH 5 #define MAXSEGS 1000 typedef struct x_state { Window win; /* Primary window */ }; void text_X(); void seg_X(); void dot_X(); void set_X(new_win, out_info) Window new_win; /* Newly created window */ xgOut *out_info; /* Information to set */ /* * Sets some of the common parameters for the X output device. */ { struct x_state *new_state; out_info->dev_flags = ((depth > 3) ? D_COLOR : 0); out_info->area_w = out_info->area_h = 0; /* Set later */ out_info->bdr_pad = PADDING; out_info->axis_pad = SPACE; out_info->legend_pad = 0; out_info->tick_len = TICKLENGTH; #ifdef OLD out_info->axis_width = axisFont->max_bounds.rbearing - axisFont->max_bounds.lbearing; #endif out_info->axis_width = XTextWidth(axisFont, "8", 1); out_info->axis_height = axisFont->max_bounds.ascent + axisFont->max_bounds.descent; #ifdef OLD out_info->title_width = titleFont->max_bounds.rbearing - titleFont->max_bounds.lbearing; #endif out_info->title_width = XTextWidth(titleFont, "8", 1); out_info->title_height = titleFont->max_bounds.ascent + titleFont->max_bounds.descent; out_info->max_segs = MAXSEGS; out_info->xg_text = text_X; out_info->xg_seg = seg_X; out_info->xg_dot = dot_X; out_info->xg_end = (void (*)()) 0; new_state = (struct x_state *) malloc(sizeof(struct x_state)); new_state->win = new_win; out_info->user_state = (char *) new_state; } /*ARGSUSED*/ void init_X(user_state) char *user_state; /* * Initializes for an X drawing sequence. Does nothing under X11. */ { /* Body left empty on purpose */ } static GC textGC(t_win, t_font) Window t_win; /* Window for making GC */ XFontStruct *t_font; /* Text font */ /* * Sets the fields above in a global graphics context. If * the graphics context does not exist, it is created. */ { static GC text_gc = (GC) 0; XGCValues gcvals; unsigned long gcmask; gcvals.font = t_font->fid; gcmask = GCFont; if (text_gc == (GC) 0) { gcvals.foreground = normPixel; gcmask |= GCForeground; text_gc = XCreateGC(disp, t_win, gcmask, &gcvals); } else { XChangeGC(disp, text_gc, gcmask, &gcvals); } return text_gc; } static GC segGC(l_win, l_fg, l_style, l_width, l_chars, l_len) Window l_win; /* Window for making GC */ Pixel l_fg; /* Foreground color */ int l_style; /* Line style */ int l_width; /* Line width */ char *l_chars; /* Character spec */ int l_len; /* Length of spec */ /* * Sets the fields above in a global graphics context. If the * graphics context does not exist, it is created. */ { static GC segment_gc = (GC) 0; XGCValues gcvals; unsigned long gcmask; gcvals.foreground = l_fg; gcvals.line_style = l_style; gcvals.line_width = l_width; gcmask = GCForeground | GCLineStyle | GCLineWidth; if (segment_gc == (GC) 0) { segment_gc = XCreateGC(disp, l_win, gcmask, &gcvals); } else { XChangeGC(disp, segment_gc, gcmask, &gcvals); } if (l_len > 0) { XSetDashes(disp, segment_gc, 0, l_chars, l_len); } return segment_gc; } static GC dotGC(d_win, d_fg, d_clipmask, d_xorg, d_yorg) Window d_win; /* Window for making GC */ Pixel d_fg; /* Foreground color */ Pixmap d_clipmask; /* Clipmask */ int d_xorg, d_yorg; /* Clipmask origin */ /* * Sets the fields above in a global graphics context. If the * graphics context does not exist, it is created. */ { static GC dot_gc = (GC) 0; XGCValues gcvals; unsigned long gcmask; gcvals.foreground = d_fg; gcvals.clip_mask = d_clipmask; gcvals.clip_x_origin = d_xorg; gcvals.clip_y_origin = d_yorg; gcmask = GCForeground | GCClipMask | GCClipXOrigin | GCClipYOrigin; if (dot_gc == (GC) 0) { dot_gc = XCreateGC(disp, d_win, gcmask, &gcvals); } else { XChangeGC(disp, dot_gc, gcmask, &gcvals); } return dot_gc; } void text_X(user_state, x, y, text, just, style) char *user_state; /* Value set in xg_init */ int x, y; /* Text position (pixels) */ char *text; /* Null terminated text */ int just; /* Justification (above) */ int style; /* Text style (above) */ /* * This routine should draw text at the indicated position using * the indicated justification and style. The justification refers * to the location of the point in reference to the text. For example, * if just is T_LOWERLEFT, (x,y) should be located at the lower left * edge of the text string. */ { struct x_state *st = (struct x_state *) user_state; XCharStruct bb; int rx, ry, len, height, width, dir; int ascent, descent; len = strlen(text); XTextExtents((style == T_TITLE) ? titleFont : axisFont, text, len, &dir, &ascent, &descent, &bb); width = bb.rbearing - bb.lbearing; height = bb.ascent + bb.descent; switch (just) { case T_CENTER: rx = x - (width/2); ry = y - (height/2); break; case T_LEFT: rx = x; ry = y - (height/2); break; case T_UPPERLEFT: rx = x; ry = y; break; case T_TOP: rx = x - (width/2); ry = y; break; case T_UPPERRIGHT: rx = x - width; ry = y; break; case T_RIGHT: rx = x - width; ry = y - (height/2); break; case T_LOWERRIGHT: rx = x - width; ry = y - height; break; case T_BOTTOM: rx = x - (width/2); ry = y - height; break; case T_LOWERLEFT: rx = x; ry = y - height; break; } XDrawString(disp, st->win, textGC(st->win, ((style == T_TITLE) ? titleFont : axisFont)), rx, ry + bb.ascent, text, len); } void seg_X(user_state, ns, segs, width, style, lappr, color) char *user_state; /* Value set in xg_init */ int ns; /* Number of segments */ XSegment *segs; /* X array of segments */ int width; /* Width of lines */ int style; /* See above */ int lappr; /* Line appearence */ int color; /* Line color (if any) */ /* * This routine draws a number of line segments at the points * given in `seglist'. Note that contiguous segments need not share * endpoints but often do. All segments should be `width' devcoords wide * and drawn in style `style'. If `style' is L_VAR, the parameters * `color' and `lappr' should be used to draw the line. Both * parameters vary from 0 to 7. If the device is capable of * color, `color' varies faster than `style'. If the device * has no color, `style' will vary faster than `color' and * `color' can be safely ignored. However, if the * the device has more than 8 line appearences, the two can * be combined to specify 64 line style variations. * Xgraph promises not to send more than the `max_segs' in the * xgOut structure passed back from xg_init(). */ { struct x_state *st = (struct x_state *) user_state; GC gc; if (style == L_AXIS) { gc = segGC(st->win, normPixel, LineSolid, axisWidth, (char *) 0, 0); } else if (style == L_ZERO) { /* Set the color and line style */ gc = segGC(st->win, zeroPixel, LineSolid, zeroWidth, (char *) 0, 0); } else { /* Color and line style vary */ if (lappr == 0) { gc = segGC(st->win, AllAttrs[color].pixelValue, LineSolid, width, (char *) 0, 0); } else { gc = segGC(st->win, AllAttrs[color].pixelValue, LineOnOffDash, width, AllAttrs[lappr].lineStyle, AllAttrs[lappr].lineStyleLen); } } XDrawSegments(disp, st->win, gc, segs, ns); } #define LAST_CHECK void dot_X(user_state, x, y, style, type, color) char *user_state; /* Value set in xg_init */ int x, y; /* Location in pixel units */ int style; /* Dot style */ int type; /* Type of marker */ int color; /* Marker color (if any) */ /* * This routine should draw a marker at location `x,y'. If the * style is P_PIXEL, the dot should be a single pixel. If * the style is P_DOT, the dot should be a reasonably large * dot. If the style is P_MARK, it should be a distinguished * mark which is specified by `type' (0-7). If the output * device is capable of color, the marker should be drawn in * `color' (0-7) which corresponds with the color for xg_line. */ { struct x_state *st = (struct x_state *) user_state; switch (style) { case P_PIXEL: XDrawPoint(disp, st->win, dotGC(st->win, AllAttrs[color].pixelValue, (Pixmap) 0, 0, 0), x, y); break; case P_DOT: XFillRectangle(disp, st->win, dotGC(st->win, AllAttrs[color].pixelValue, dotMap, (int) (x - (dot_w >> 1)), (int) (y - (dot_h >> 1))), (int) (x - (dot_w >> 1)), (int) (y - (dot_h >> 1)), dot_w, dot_h); break; case P_MARK: XFillRectangle(disp, st->win, dotGC(st->win, AllAttrs[color].pixelValue, AllAttrs[type].markStyle, (int) (x - mark_cx), (int) (y - mark_cy)), (int) (x - mark_cx), (int) (y - mark_cy), mark_w, mark_h); break; } } \End\Of\Shar\ else echo "will not over write ./xgraph-11/xgX.c" fi if `test ! -s ./xgraph-11/xgout.h` then echo "writing ./xgraph-11/xgout.h" cat > ./xgraph-11/xgout.h << '\End\Of\Shar\' /* * Output Device Information * * This file contains definitions for output device interfaces * to the graphing program xgraph. */ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/cursorfont.h> #include "ux11/ux11.h" #define D_COLOR 0x01 /* Text justifications */ #define T_CENTER 0 #define T_LEFT 1 #define T_UPPERLEFT 2 #define T_TOP 3 #define T_UPPERRIGHT 4 #define T_RIGHT 5 #define T_LOWERRIGHT 6 #define T_BOTTOM 7 #define T_LOWERLEFT 8 /* Text styles */ #define T_AXIS 0 #define T_TITLE 1 /* Line Styles */ #define L_AXIS 0 #define L_ZERO 1 #define L_VAR 2 /* Marker Styles */ #define P_PIXEL 0 #define P_DOT 1 #define P_MARK 2 /* Output device information returned by initialization routine */ typedef struct xg_out { int dev_flags; /* Device characteristic flags */ int area_w, area_h; /* Width and height in pixels */ int bdr_pad; /* Padding from border */ int axis_pad; /* Extra space around axis labels */ int tick_len; /* Length of tick mark on axis */ int legend_pad; /* Top of legend text to legend line */ int axis_width; /* Width of big character of axis font */ int axis_height; /* Height of big character of axis font */ int title_width; /* Width of big character of title font */ int title_height; /* Height of big character of title font */ int max_segs; /* Maximum number of segments in group */ void (*xg_text)(); /* Draws text at a location */ void (*xg_seg)(); /* Draws a series of segments */ void (*xg_dot)(); /* Draws a dot or marker at a location */ void (*xg_end)(); /* Stops the drawing sequence */ char *user_state; /* User supplied data */ } xgOut; #define ERRBUFSIZE 2048 \End\Of\Shar\ else echo "will not over write ./xgraph-11/xgout.h" fi if `test ! -s ./xgraph-11/xgraph.1` then echo "writing ./xgraph-11/xgraph.1" cat > ./xgraph-11/xgraph.1 << '\End\Of\Shar\' .TH XGRAPH 1 "February 1, 1989" .SH NAME xgraph \- Draw a graph on an X11 Display .SH SYNOPSIS .B xgraph [ options ] [ =WxH+X+Y ] [ -display host:display.screen ] [ file ... ] .SH DESCRIPTION The .I xgraph program draws a graph on an X display given data read from either data files or from standard input if no files are specified. It can display up to 64 independent data sets using different colors and/or line styles for each set. It annotates the graph with a title, axis labels, grid lines or tick marks, grid labels, and a legend. There are options to control the appearance of most components of the graph. .PP The input format is similar to .I graph(1G) but differs slightly. The data consists of a number of .I "data sets." Data sets are separated by a blank line. A new data set is also assumed at the start of each input file. A data set consists of an ordered list of points of the form "X Y". Each point must appear on a separate line. The name of a data set can be specified by a line which begins with a double quote followed by the set name. An example input file with three data sets is shown below (note set three is not named): .sp 1 .nf 0.5 7.8 1.0 6.2 "set one 1.5 8.9 "set two -3.4 1.4e-3 -2.0 1.9e-2 -0.65 2.2e-4 2.2 12.8 2.4 -3.3 2.6 -32.2 2.8 -10.3 .fi .PP After .I xgraph has read the data, it will create a new window to graphically display the data. The interface used to specify the size and location of this window depends on the window manager currently in use. Refer to the reference manual of the window manager for details. .PP Once the window has been opened, all of the data sets will be displayed graphically (subject to the options explained below) with a legend in the upper right corner of the screen. To zoom in on a portion of the graph, depress a mouse button in the window and sweep out a region. .I xgraph will then open a new window looking at just that portion of the graph. .I xgraph also presents two control buttons in the upper left corner of each window: .I Close and .I Hardcopy. Windows are closed by depressing a mouse button while the mouse cursor is inside the .I Close button. Typing EOF (control-D) in a window also closes that window. Depressing a mouse button while the mouse cursor is in the .I Harcopy button causes a dialog to appear asking about hardcopy (printout) options. These options are described below: .IP "Output Device" Specifies the type of the output device (e.g. "HPGL", "Postscript", etc). An output device is chosen by depressing the mouse inside its name. The default values of other fields will change when you select a different output device. .IP "Disposition" Specifies whether the output should go directly to a device or to a file. Again, the default values of other fields will change when you select a different disposition. .IP "File or Device Name" If the disposition is "To Device", this field specifies the device name. A device name is the same as the name given for the -P command of lpr(1). If the disposition is "To File", this field specifies the name of the output file. .IP "Maximum Dimension" This specifies the maximum size of the plot on the hardcopy device in centimeters. .I xgraph takes in account the aspect ratio of the plot on the screen and will scale the plot so that the longer side of the plot is no more than the value of this parameter. If the device supports it, the plot may also be rotated on the page based on the value of the maximum dimension. .IP "Title Font Family" This field specifies the name of a font to use when drawing the graph title. Suitable defaults are initially chosen for any given hardcopy device. The value of this field is hardware specific -- refer to the device reference manual for details. .IP "Title Font Size" This field specifies the desired size of the title fonts in points (1/72 of an inch). If the device supports scalable fonts, the font will be scaled to this size. .IP "Axis Font Family and Axis Font Size" These fields are like .I "Title Font Family" and .I "Title Font Size" except they specify values for the font .I xgraph uses to draw axis labels, and legend descriptions. .IP "Control Buttons" After specifing the parameters for the plot, the "Ok" button causes .I xgraph to produce a hardcopy. Pressing the "Cancel" button will abort the hardcopy operation. .PP .I xgraph accepts a large number of options most of which can be specified either on the command line or in the user's ~/.Xdefaults file. A list of these options is given below. The command line option is specified first with its X default name (if any) in parenthesis afterward. The format of the option in the X defaults file is "program.option: value" where program is the program name (xgraph) and the option name is the one specified below. Note that the value of a flag in the X defaults file must be "1". .TP .B \-<digit> <name> These options specify the data set name for the corresponding data set. The digit should be in the range '0' to '63'. This name will be used in the legend. .TP .B \-b Force .I xgraph to output the graph in black and white (even if the display is color). This is useful for those using .I xwd(1) to produce hardcopies of the graph. .TP .B \-bar Specifies that vertical bars should be drawn from the data points to a base point which can be specified with -brb. Usually, the -nl flag is used with this option. The point itself is located at the center of the bar. .TP .B \-bb (BoundBox) Draw a bounding box around the data region. This is very useful if you prefer to see tick marks rather than grid lines (see -tk). .TP .B \-bd <color> (Border) This specifies the border color of the .I xgraph window. .TP .B \-bg <color> (Background) Background color of the .I xgraph window. .TP .B \-brb <base> This specifies the base for a bar graph. By default, the base is zero. .TP .B \-brw <width> This specifies the width of bars in a bar graph. The amount is specified in the user's units. By default, a bar one pixel wide is drawn. .TP .B \-bw <size> (BorderSize) Border width (in pixels) of the .I xgraph window. .TP .B \-fg <color> (Foreground) Foreground color. This color is used to draw all text and the normal grid lines in the window. .TP .B \-lf <fontname> (LabelFont) Label font. All axis labels and grid labels are drawn using this font. It must be a fixed-width font. .TP .B \-lnx Specifies a logarithmic X axis. Grid labels represent powers of ten. .TP .B \-lny Specifies a logarithmic Y axis. Grid labels represent powers of ten. .TP .B \-lw width Specifies the width of the data lines in pixels. The default is one. .TP .B \-lx <xl,xh> This option limits the range of the X axis to the specified interval. This (along with -ly) can be used to "zoom in" on a particularly interesting portion of a larger graph. .TP .B \-ly <yl,yh> This option limits the range of the Y axis to the specified interval. .TP .B \-m (Markers) Mark each data point with a distinctive marker. There are eight distinctive markers used by xgraph. These markers are assigned uniquely to each different line style on black and white machines and varies with each color on color machines. .TP .B \-M (StyleMarkers) Similar to -m but markers are assigned uniquely to each eight consecutive data sets (this corresponds to each different line style on color machines). .TP .B \-nl (NoLines) Turn off drawing lines. When used with -m, this can be used to produce scatter plots. When used with -bar, it can be used to produce standard bar graphs. .TP .B \-p (PixelMarkers, SmallPixels) Marks each data point with a small marker (pixel sized). This is usually used with the -nl option for scatter plots. .TP .B \-P (LargePixels) Similar to -p but marks each pixel with a large dot. .TP .B \-rv (ReverseVideo) Reverse video. On black and white displays, this will invert the foreground and background colors. It does nothing on color displays. .TP .B \-s (Spline) This option specifies the lines should be drawn as spline curves. Currently, this is implemented using the X spline option which fits only three points at a time. Thus, the effect is not what you might expect. .TP .B \-t <string> Title of the plot. This string is centered at the top of the graph. .TP .B \-tf <fontname> (TitleFont) Title font. This is the name of the font to use for the graph title. It defaults to 9x15. .TP .B \-tk (Ticks) This option causes .I xgraph to draw tick marks rather than full grid lines. The -bb option is also useful when viewing graphs with tick marks only. .TP .B \-x <unitname> This is the unit name for the X axis. Its default is "X". .TP .B \-y <unitname> This is the unit name for the Y axis. Its default is "Y". .TP .B \-zg <color> (ZeroColor) This is the color used to draw the zero grid line. .PP Some options can only be specified in the X defaults file. These options are described below: .TP .B <digit>.Color Specifies the color for a data set. Eight independent colors can be specified. Thus, the digit should be between '0' and '7'. If there are more than eight data sets, the colors will repeat but with a new line style (see below). .TP .B <digit>.Style Specifies the line style for a data set. A sixteen-bit integer specifies the sixteen-bit pattern used for the line style. Eight independent line styles can be specified. Thus, the digit should be between '0' and '7'. If there are more than eight data sets, these styles will be reused. On color workstations, one line style is used for each of eight colors. Thus, 64 unique data sets can be displayed. .TP .B GridSize Width, in pixels, of normal grid lines. .TP .B GridStyle Line style pattern of normal grid lines. .TP .B ZeroSize Width, in pixels, of the zero grid line. .TP .B ZeroStyle Line style pattern of the zero grid line. .SH AUTHOR David Harrison University of California \End\Of\Shar\ else echo "will not over write ./xgraph-11/xgraph.1" fi echo "Finished archive 5 of 6"