home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
d
/
dots151.zip
/
GRAPHSRC.ZIP
/
GPS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-15
|
22KB
|
687 lines
/*
gps - graphics interface routine for PostScript printers
history...
5 Jul 90 Version 1.45: Only closing output file once. Default
output filename is foo.ps, where foo is the root name
of the first data file.
4 Jul 90 Version 1.44: Getting parameters from configuration
file.
23 Jun 90 Version 1.42: Ported to Turbo C.
19 Jun 90 Version 1.41: Adding strokes if needed within a long
series of lineto commands.
28 Nov 89 Version 1.40: generating structure comments for
Nelson Beebe's DVIALW (.DVI -> Apple LaserWriter).
1 Nov 89 Version 1.35: widened characters by 20% for better
superscript placement. Something is still wrong,
especially with the last label on the X axis.
26 May 89 Version 1.34: minor format changes in prologue and
clear_graph.
12 May 89 Version 1.33: Using "show" for all text rather than
"s", so these labels don't have opaque backgrounds.
POSTOGRF adds its own definition of "s", including
routines for adding opaque backgrounds.
4 May 89 Version 1.32: Putting whitespace after "]" everywhere.
Writing version
number into output file. Margin
specification revised so that portrait or landscape
orientation requests aren't dropped.
2 May 89 Version 1.31: Adding a stroke before each label.
25 Apr 89 Version 1.3: Using PostScript "translate" command to
adjust margins rather than adding a constant
displacement to every position. Printing size of
plot area. Default margins and sizes now match the
MITRE document mat standards.
21 Apr 89 Version 1.2: shorter prologue, implementing grayscale
14 Apr 89 Version 1.12: Adding "st" commands periodically,
to avoid overrunning printer's stack.
28 Sep 88 Version 1.11: L or P at end of either dimension
input line specifies landscape or portrait orientation.
19 Jul 88 Version 1.10: Deleting output file before opening it.
9 May 88 Adapted from LIPS-10 driver
9 Jul 87 Creating output file if it doesn't already exist
21 May 87 Stronger warning msg about using default output port
13 May 87 Default margins, width, and height set for landscape
orientation.
1 May 87 Adapted from Hewlett Packard plotter routine
23 Jun 86 Adapted from Houstin Instruments plotter routine
27 Oct 87 Environment variable "plot_setup" can contain an
alternate setup string.
bugs...
bench needs to check for "erasing"
g3x needs to call set_height to set character size.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "g.h"
#include "config.h"
#define VERSION "1.45"
#include "gps.h" /* this defines "prelude", the introductory text */
#define TI(x,y) /* printf("%15d = %s\n", x, y) /**/
#define TR(x,y) /* printf("%15.4g = %s\n", x, y) /**/
#define UNIT (1./300.)
#define BUFSIZE 80
#define DEFAULT_FILE "COM1"
/* default margins, defined assuming portrait orientation */
#define LMARGIN 1.125
#define RMARGIN 1.125
#define TMARGIN 1.5
#define BMARGIN 1.5
/* imported variables */
extern char *default_script_file;
/* exported graphics variables */
char *machine = "PostScript";
char *interface_version = VERSION;
static char default_config_file[] = "GRAPHPS.CFG";
char *config_file = NULL;
int plotting_device = 1;
int erasing = 0;
int max_color = 1;
int current_color = 0;
double current_intensity = 1.;
/* these dimensions assume landscape orientation */
int pixels_wide = 300*11; /* width of screen in pixels */
int pixels_high = 30*85; /* height of screen in pixels */
double best_width = 1.; /* relative height/width for landscape */
double best_height = .720;
int pen_diameter = 3;
int char_rows = 30*85/65; /* text parameters */
int char_columns = 300*11/30; /* (recalculated by init_graphics) */
int char_height = 65;
int char_width = 30;
int x_offset = 0;
int y_offset = 0;
int char_v_adjusted = 1;
int char_h_adjusted = 1;
int has_cursor_keys = 0; /* no cursor keys,
so the rest of these are ignored... */
int up_arrow = 0x48; /* cursor key codes */
int down_arrow = 0x50;
int left_arrow = 0x4b;
int right_arrow = 0x4d;
int escaped_arrows = 1; /* cursor keys are preceded by 0 */
int escape_char = 0;
/* an 'A' on row r, column c has lower left corner on raster
r*char_height + y_offset
at pixel
c*char_width + x_offset */
struct PRIM_ATTR prim_attr=
{2, /* # colors */
16, /* # intensities */
0, /* nonzero if supported in hardware */
9, /* # linestyles in hardware */
1, /* # linestyles in software */
1, /* # linewidths */
0, /* nonzero if supported in hardware */
1, /* minimum linewidth */
14, /* maximum linewidth (.2 in) */
1, /* # pens in hardware */
0, /* # pens in software */
1, /* # fonts */
1, /* # character sizes */
0, /* nonzero if supported in hardware */
10, /* minimum character height (pixels) */
10, /* maximum character height (pixels) */
0, /* # markers in hardware */
0, /* # markers in software */
0 /* # pick IDs in hardware */
};
static draw();
static erase();
static text();
static character();
static font=0;
static int plotter_type;
FILE *plot_file=stdout;
static int style_code=1;
static int color_code=0;
static current_width=3;
static cx=0, cy=0; /* actual position of pen */
static something_printed=0; /* nonzero if something printed since last
PAGE command (graphics_clear()) */
#define WAIT something_printed=1
#define DASHES 8
#define MAX_STYLE 9
char styles[DASHES*MAX_STYLE]={ /* 0 - solid */
8,2,0,0,0,0,0,0, /* 1 - dashed */
3,2,0,0,0,0,0,0, /* 2 - short dashes */
1,3,0,0,0,0,0,0, /* 3 - dotted */
16,2,1,2,0,0,0,0, /* 4 - dash-dot */
16,2,1,2,1,2,0,0, /* 5 - dash-dot-dot */
16,2,1,2,1,2,1,2, /* 6 - dash-dot-dot-dot */
16,2,16,2,1,2,0,0, /* 7 - dash-dash-dot */
16,2,16,2,1,2,1,2, /* 8 - dash-dash-dot-dot */
15,10,0,0,0,0,0,0}; /* 9 - long dashes */
static set_style(style) int style;
{ char *t;
int i;
if(style<=0)
{style=0;
if(style_code==style) return;
WAIT;
fprintf(plot_file,"cpt st m\n[] 0 sd %% solid line\n");
}
else
{if(style>=prim_attr.hardware_linestyles)
style=prim_attr.hardware_linestyles-1;
if(style_code==style) return;
WAIT;
t=styles+DASHES*(style-1);
fprintf(plot_file, "cpt st m\n[");
for (i=0; i<DASHES && *t; i++)
fprintf(plot_file, "%1.0f ", 15.* (current_width/3-1+ *t++ ));
fprintf(plot_file, "] 0 sd\n");
}
style_code=style;
}
static set_width(width) int width;
{ width *= 3;
if(width<3) width=3;
else if(width>64) width=64;
if(width==current_width) return;
fprintf(plot_file,"cpt st m\n%d setlinewidth\n",(width*10)/3);
current_width=width;
}
/* set_color - set color to be used for subsequent primitives */
set_color(color) int color; {}
inquire_color() {return 1;}
/*
set_intensity - set intensity to be used for subsequent primitives
1 -> black (easiest to see)
0 -> white (most subtle)
*/
set_intensity(intensity) double intensity;
{ if(intensity < 0.) intensity = 0.;
else if(intensity > 1.) intensity = 1.;
if(current_intensity == intensity) return;
current_intensity = intensity;
fprintf(plot_file,"cpt st m %3.3f sg\n", 1. - current_intensity);
}
double inquire_intensity() {return current_intensity;}
/* draw - draw a straight line */
static int draw(x1, y1, x2, y2) int x1, y1, x2, y2;
{ int t, d1, d2;
static int segments=0;
y1= pixels_high-1-y1; y2= pixels_high-1-y2;
d1=maximum(abs(cx-x1), abs(cy-y1));
d2=maximum(abs(cx-x2), abs(cy-y2));
#ifdef DEBUG
printf("\nat (%d,%d) drawing (%d,%d)(%d away) to (%d,%d)(%d away)",
cx, cy, x1, y1, d1, x2, y2, d2);
#endif
if(d2<d1)
{t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; t=d1; d1=d2; d2=t;
#ifdef DEBUG
puts("swapping");
#endif
}
#ifdef DEBUG
putchar('\n');
#endif
WAIT;
segments++;
if(d1)
{
if(segments > 100)
{ /*
"stroke" to clear printer memory of
accumulated "lineto" and "moveto" commands
*/
fprintf(plot_file, "st \n");
segments = 0;
}
fprintf(plot_file,"%ld %ld m \n",(x1*10L)/3L,(y1*10L)/3L);
}
else
{if(segments > 100)
{ /*
"stroke" to clear printer memory of
accumulated "lineto" and "moveto" commands
*/
fprintf(plot_file, "cpt st m\n");
segments = 0;
}
}
fprintf(plot_file,"%ld %ld l \n",(x2*10L)/3L,(y2*10L)/3L);
cx=x2; cy=y2;
}
/* gotoxy - move pen to new position (used before text display) */
gotoxy(x,y) int x,y;
{ y= pixels_high-1-y;
if (x<0) x=0; else if (x>=pixels_wide) x=pixels_wide-1;
if (y<0) y=0; else if (y>=pixels_high) y=pixels_high-1;
if(x==cx && y==cy) return;
WAIT;
fprintf(plot_file,"%ld %ld m \n",(x*10L)/3L,(y*10L)/3L);
cx=x; cy=y;
}
static nil() {}
/* exported function pointers */
int (*draw_line)() = draw;
int (*erase_line)() = nil;
int (*draw_text)() = text;
int (*draw_char)() = character;
/* find a character in a string (case insensitive) */
static int strichr(s, c) char *s, c;
{
for (c=tolower(c); *s; s++)
if(tolower(*s) == c)
return 1;
return 0;
}
/* init - initialize the graphics system */
init_graphics()
{ int d1, d2, c, i, vel;
double left, top, right, bottom, w, h, hmax, wmax;
char buf[BUFSIZE], inbuf[BUFSIZE], *s, *t, **sp;
static int offset_ask = 1,
size_ask = 1,
orientation_ask = 1,
/* plotter_ask = 1, */
/* velocity_ask = 1, */
file_ask = 0;
static double offset[2] = {BMARGIN, LMARGIN};
static double size[2] = {11. - BMARGIN - TMARGIN, 8.5 - LMARGIN - RMARGIN};
static int portrait = 0, landscape = 0;
static char *port_name = NULL;
static PARAM parmv[] = {
{'o', REAL, &offset_ask, offset, 2},
{'l', REAL, &offset_ask, &offset[0]},
{'t', REAL, &offset_ask, &offset[1]},
{'s', REAL, &size_ask, size, 2},
{'w', REAL, &size_ask, &size[0]},
{'h', REAL, &size_ask, &size[1]},
{'p', BOOLEAN, &orientation_ask, &portrait, 0},
{'l', BOOLEAN, &orientation_ask, &landscape, 0},
{'f', STRING, &file_ask, &port_name, 1},
{'\0'}};
if(config_file == NULL) config_file = default_config_file;
config(config_file, NULL, parmv, buf, BUFSIZE);
if(port_name == NULL && version() >= 0x200)
port_name = getenv("PLOT_PORT");
if(port_name == NULL)
{port_name = strncpy(buf, default_script_file, BUFSIZE-4);
s = strchr(port_name, '.');
if(s != NULL) *s = 0;
strcat(port_name, ".ps");
}
else file_ask = 0;
if(file_ask)
{port_name = strncpy(buf, port_name, BUFSIZE);
printf("Enter output file (default %s): ",buf);
gets(inbuf);
if(inbuf[0]) strcpy(buf,inbuf);
}
else
printf("\noutput written to %s\n", port_name);
unlink(port_name); /* delete the file if it exists */
plot_file=fopen(port_name, "w"); /* this will open a file or device */
if(plot_file==NULL) {printf("can\'t open output file %s", port_name); exit(1);}
buf[0]=0;
if(orientation_ask)
{printf("Portrait or landscape orientation? ('p' or 'l', default %c): ",
portrait?'p':'l');
gets(buf);
portrait |= strichr(buf, 'p');
landscape = !portrait;
}
left=offset[0];
top=offset[1];
while(1)
{if(offset_ask)
{printf("\nEnter left and top margin in inches \n");
printf(" (default %5.3f and %5.3f): ",left,top);
gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&left,&top);
}
if(left<0. || left>10.75)
printf("left margin outside valid range 0-10.75\n");
else if(top<0. || top>10.75)
printf("top margin outside valid range 0-10.75\n");
else if((portrait && left > 8.25) || (landscape && top > 8.25) ||
(left > 8.25 && top > 8.25))
printf("no room left for plot!\n");
else break;
offset_ask = 1;
left=BMARGIN;
top=LMARGIN;
}
w = size[0];
h = size[1];
while(1)
{if(size_ask)
{
printf("\nEnter width and height of plot area in inches \n");
if(!portrait)
printf("maximum for landscape orientation, %5.3f by %5.3f\n",
10.75 - left, 8.15 - top);
if(!landscape)
printf("maximum for portrait orientation, %5.3f by %5.3f\n",
8.15 - left, 10.75 - top);
printf(" (default, %5.3f by %5.3f): ", w, h);
gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
}
if(landscape) hmax = 8.15 - top; else hmax = 10.75 - top;
if(portrait) wmax = 8.15 - left; else wmax = 10.75 - left;
/* round to nearest .01" */
hmax = floor(hmax*100. + .5)/100.;
wmax = floor(wmax*100. + .5)/100.;
h = floor(h*100. + .5)/100.;
w = floor(w*100. + .5)/100.;
if(w < .1 || w > wmax)
printf("width outside valid range 0.1 to %2.3f\n", wmax);
else if(h < .1 || h > hmax)
printf("height outside valid range 0.1 to %2.3f\n", hmax);
else if(w + left > 8.15 && h + top > 8.15)
printf("either width or height must be reduced\n");
else break;
/* find suitable defaults for next time */
if(!portrait && top < 8.5 - LMARGIN)/* assume landscape orientation */
{h = 8.5 - top - LMARGIN;
if(left < 11. - TMARGIN) w=11. - left - TMARGIN;
else w = 11 - left;
}
else if(!landscape && left < 8.5 - RMARGIN)
{ /* else assume portrait orientation */
w = 8.5 - RMARGIN - left;
if(top < 11. - BMARGIN) h = 11. - top - BMARGIN;
else h = 11. - top;
}
else if(!portrait && top<8.15) {h=8.15-top; w=10.75-left;}
else {h=10.75-top; w=8.15-left;} /* maximize area */
size_ask = 1;
}
if(w + left > 11.) w = 11. - left;
if(landscape)
{ /* landscape orientation */
if(h + top > 8.15) h = 8.15-top;
}
else
{ /* portrait orientation */
if(h + top > 11.) h = 11.-top;
}
pixels_wide = w/UNIT;
pixels_high = h/UNIT;
/*
Use 13 point font, which has height 13/72 = .181
in (including an allowance for spacing between
lines), assume height:width ratio of 2:1. (Due
to proportional spacing, actual character width
is variable, from about .085 inch for lower
case to about .103 for upper case.) This width is
increased by 20% because it seems to be
necessary to get proper superscript placement.
*/
char_height = 13./72/UNIT;
char_width = 13./72/2/UNIT*1.2;
char_columns = pixels_wide/char_width;
char_rows = pixels_high/char_height;
if(portrait) /* portrait orientation */
{best_width = (double)pixels_wide/pixels_high;
best_height = 1.;
}
else /* landscape orientation */
{best_width = 1.;
best_height = (double)pixels_high/pixels_wide;
}
TI(pixels_wide,"pixels_wide");
TI(pixels_high,"pixels_high");
TI(char_rows,"char_rows");
TI(char_width,"char_width");
TI(char_columns,"char_columns");
TR(best_width,"best_width");
TR(best_height,"best_height");
sp = prelude1;
while(*sp) fputs(*sp++, plot_file);
/*
PostScript's origin is at the bottom left corner of the 8.5x11 page.
"translate" and "rotate [CCW]" commands operate on the material
being drawn.
*/
if(portrait)
{fprintf(plot_file, "/setorigin { %3.3f inch %3.3f inch translate \n",
left, 11. - h - top); /* move to starting point */
bottom = 11. - h - top;
right = 8.5 - w - left;
}
else
{fprintf(plot_file,"/setorigin { %3.3f inch %3.3f inch translate \n",
top + h, left); /* move to starting point */
fprintf(plot_file, " 90 rotate \n"); /* landscape */
bottom = 8.5 - h - top;
right = 11. - w - left;
}
fprintf(plot_file, " 0 0 m } def \n\n");
fprintf( plot_file, portrait ? "%% portrait orientation\n\n"
: "%% landscape orientation\n\n");
fprintf( plot_file, "%% left margin: %4.3f in = %5.2f cm\n",
left, left*2.54 );
fprintf( plot_file, "%% plot width: %4.3f in = %5.2f cm = %5d pixels\n",
pixels_wide*UNIT, pixels_wide*UNIT*2.54, pixels_wide );
fprintf( plot_file, "%% right margin: %4.3f in = %5.2f cm\n\n",
right, right*2.54 );
fprintf( plot_file, "%% top margin: %4.3f in = %5.2f cm\n",
top, top*2.54 );
fprintf( plot_file, "%% plot height: %4.3f in = %5.2f cm = %5d pixels\n",
pixels_high*UNIT, pixels_high*UNIT*2.54, pixels_high );
fprintf( plot_file, "%% bottom margin: %4.3f in = %5.2f cm\n",
bottom, bottom*2.54 );
/**/
sp = prelude2;
while(*sp) fputs(*sp++, plot_file);
fprintf(plot_file, "%% initialization complete\n");
}
static int allwhite(s) char *s;
{ while(*s) if(!isspace(*s++)) return 0;
return 1;
}
static text(s) char *s;
{ int c;
if(allwhite(s)) return;
WAIT;
fprintf(plot_file, "cpt st m\nfont0 sf (");
while(c = *s++)
{if(strchr("\\()", c) != NULL)
fprintf(plot_file, "\\"); /* escape special characters */
fprintf(plot_file, "%c", c);
}
fprintf(plot_file, ") show \n");
cx=cy=-2000;
}
static character(c) char c;
{ char buf[2];
buf[0]=c; buf[1]=0;
text(buf);
}
version() /* return MS-DOS version number. Version 2.01 returned as 0x201 */
{
#ifdef __DESMET__
extern unsigned _rax;
_rax=0x3000;
_doint(0x21);
return ( (_rax&0xff)<<8 | (_rax&0xff00)>>8 );
#else
#include <dos.h>
return ( (_version&0xff)<<8 | (_version&0xff00)>>8 );
#endif
}
#ifdef __DESMET__
/* search environment for given string */
getenv(target) char *target;
{ char buf[256],*s,t[25],*env, *malloc();
int nt,offset;
s=t;
while(*target) *s++=toupper(*target++);
*s++= '='; *s=0;
nt = strlen(t);
offset=0;
_lmove(2,44,_showcs()-0x10,&env,_showds());
while(1)
{_lmove(256,offset,env,buf,_showds());
s=buf;
if(*s)
{/* printf("examining entry: %s \n",s); getchar(); */
if (strncmp(t,s,nt)==0)
{env = malloc(strlen(s+nt)+1);
if(env == NULL) return NULL;
return strcpy(env, s+nt);
}
}
else return NULL;
offset+=strlen(buf)+1;
}
}
#endif
/* finish - close down the graphics system */
finish_graphics()
{ if(plot_file != stdout)
{clear_graphics();
fclose(plot_file);
}
plot_file = stdout;
}
clear_graphics()
{ if(something_printed)
fprintf(plot_file,
"stroke \n%%EndGraph\n%%end(plot)\n showpage grestore\n%%%%Trailer\n");
/*
"%end(plot)" is a structure comment for the program DVIALW by Nelson
H. F. Beebe (Beebe@Science.Utah.Edu). DVIALW is a program to
convert a TeX DVI file into PostScript for the Apple LaserWriter.
This comment and the the "%begin(plot)" included in gps.h delimit the
portion of a GRAPHPS output file which is to be incorporated into a
TeX document.
*/
something_printed=0;
}
/* pointers to optional functions (NULL if not implemented) */
int (*new_linestyle)()=set_style; /* (*new_linestyle)(style) int style; */
int (*new_linewidth)()=set_width; /* (*new_linewidth)(width) int width; */
int (*new_charsize)()=0; /* (*new_charsize)(w,h) int w,h; */
int (*draw_marker)()=0; /* (*draw_marker)(n) int n; */
#ifdef MAIN
main()
{ char buf[100];
printf("Interface %s for the %s\n",interface_version,machine);
init_graphics();
printf("screen width %d pixels\nheight %d pixels\n",
pixels_wide,pixels_high);
printf("height:width ratio %f:%f\n",best_height,best_width);
printf("%d colors\n",max_color+1);
printf("primitive attributes...\n");
printf("color_count= %d \n",prim_attr.color_count);
printf("intensity_count= %d \n",prim_attr.intensity_count);
printf("intensities_in_hardware= %d \n",prim_attr.intensities_in_hardware);
printf("hardware_linestyles= %d \n",prim_attr.hardware_linestyles);
printf("software_linestyles= %d \n",prim_attr.software_linestyles);
printf("linewidth_count= %d \n",prim_attr.linewidth_count);
printf("linewidths_in_hardware= %d \n",prim_attr.linewidths_in_hardware);
printf("linewidth_minimum= %d \n",prim_attr.linewidth_minimum);
printf("linewidth_maximum= %d \n",prim_attr.linewidth_maximum);
printf("hardware_pens= %d \n",prim_attr.hardware_pens);
printf("software_pens= %d \n",prim_attr.software_pens);
printf("charfont_count= %d \n",prim_attr.charfont_count);
printf("charsize_count= %d \n",prim_attr.charsize_count);
printf("charsize_in_hardware= %d \n",prim_attr.charsize_in_hardware);
printf("charsize_minimum= %d \n",prim_attr.charsize_minimum);
printf("charsize_maximum= %d \n",prim_attr.charsize_maximum);
printf("hardware_markers= %d \n",prim_attr.hardware_markers);
printf("software_markers= %d \n",prim_attr.software_markers);
printf("pick_id_count= %d \n",prim_attr.pick_id_count);
(*draw_line)(2,4,200,-400);
(*draw_line)(20,40,100,-200);
(*erase_line)(2,4,200,-400);
(*draw_line)(10,30,100,300);
(*draw_line)(10,40,500,890);
(*draw_line)(10,40,500,32);
(*draw_line)(10,1000,78,8900);
gotoxy(10,-20);
(*draw_text)(" ello\nDolly ");
(*draw_char)('H');
finish_graphics();
}
#endif
maximum(a,b) int a,b;
{ if (a>b) return a;
return b;
}