home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
PRINTING
/
SHOWGL10.ZIP
/
HPGL2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-29
|
14KB
|
549 lines
#pragma linesize(132) /* listing linewidth = 132 */
/* this file contains the following functions:
begin_plot ()
define_path ()
label_origin ()
line_pattern ()
page_adv ()
set_csize ()
calc_csize ()
set_slant ()
extra_space ()
char_plot ()
label_graph ()
symbol_mark ()
label_term ()
label_dir ()
*/
#include <stdio.h>
#include <math.h>
#include "hpgl.h"
#include "graph.h"
extern struct csizes cs;
extern struct cplot cp;
extern int x_mirror, y_mirror;
extern double p1x, p2x, p1y, p2y;
extern unsigned endlabel;
static char copyright[] = "Copyright 1991, Robert C. Becker, Lantern Systems";
static unsigned char label_bfr[LABEL_BFR];
static double es_x, es_y;
/*--------------------------------------*/
void label_origin (FILE * infile)
{
double x;
int l;
if (!get_val (infile, &x) )
{
cp.lorg = LORG_DEFAULT;
return;
}
l = (int) x;
if (l > 19 || l < 1 || l == 10) /* no lorg (10) */
{
print_string ("LO: value out of range\n");
return; /* no changes */
}
cp.lorg = l; /* new label origin */
return;
}
/*--------------------------------------*/
void line_pattern (FILE * infile)
{
double x, y;
int l;
if ( !get_val (infile, &x) )
{ /* default line type */
line_type (0, 0);
return;
}
else
{
if (x < 0) /* line type w/pattern # */
{
print_noinstr ("Adaptive line type");
return;
}
l = (int) (MAX (0.0, MIN (6.0, x)) ) + 2;
/* translate HPGL patterns to library patterns */
if (!get_val (infile, &y))
{
line_type (l, 0);
return;
}
else /* line type w/pattern # and repeat length */
{
line_type (l, MAX (0.0, MIN ( y, 127.9999)));
return;
}
}
return;
}
/*--------------------------------------*/
void set_csize (FILE * infile, int type)
{ /* type: 0 -> absolute, 1 -> relative */
/* set height (y) and width (x) of char (in cm) */
double x, y;
if (type)
{ /* relative size */
cs.rcsize_x = x = 0.75; /* width: 0.75% (p2x - p1x) */
cs.rcsize_y = y = 1.50; /* height: 1.5% (p2y - p1y) */
}
else
{ /* absolute size */
x = 0.19; /* default width (cm) */
y = 0.27;
}
if (get_val (infile, &x) ) /* got width value: need height */
{
if ( !get_val (infile, &y)) /* missing height */
{
if (type)
print_string ("SR: missing height parameter\n");
else
print_string ("SI: missing height parameter\n");
return;
}
}
x = MAX (-128.00, (MIN (127.9999, x)));
y = MAX (-128.00, (MIN (127.9999, y)));
calc_csize (x, y, type); /* set char size */
return;
}
/*--------------------------------------*/
void calc_csize (double x, double y, int type)
{
double ar;
cs.cscale_mode = 0; /* default to abs. char size scaling */
if (type) /* relative char size: convert to cm */
{
cs.cscale_mode = 1; /* turn on relative char size scaling */
cs.rcsize_x = x;
cs.rcsize_y = y; /* save relative csizes for changes in IP */
x = x * fabs (p2x - p1x) * 0.00254 / 100.0;
y = y * fabs (p2y - p1y) * 0.00254 / 100.0;
} /* P1, P2 are in mils. 0.00254 cm/mil */
x = cs.csize_x = (10.0) * ((x_mirror) ? -x : x); /* convert from cm to mm's for csize () */
y = cs.csize_y = (10.0) * ((y_mirror) ? -y : y); /* correct for reflection/inversion of P2 - P1 */
/* cs.csize_x, cs.csize_y save char size for SL function */
ar = x / fabs (y); /* aspect ratio */
/* need fabs() to isolate AR from possibly negative y-size, but retain sign of x */
if (!type) cs.csize_y = (y *= 0.725);
/* factor of 0.725 corrects default graphix lib font size to
HPGL plotter font size for absolute font sizes (this is a patch) */
csize (y, ar, cs.slant); /* height (in cm), aspect ratio, slant (deg) */
return;
}
/*--------------------------------------*/
void set_slant ( FILE *infile )
{
double ar, x;
DB (printf ("SL\n");)
x = 0.0;
get_val (infile, &x); /* if no value present, x is unchanged */
x = MAX (-128.00, (MIN (127.9999, x)));
cs.slant = RAD_2_DEG * atan (x); /* sl is in degrees */
DB (printf ("SL: angle = %lf\n", cs.slant);)
ar = cs.csize_x / fabs (cs.csize_y); /* aspect ratio */
/* need fabs() to isolate AR from possibly negative y-size, but retain sign of x */
csize (cs.csize_y, ar, cs.slant); /* height (in cm), aspect ratio, slant (deg) */
return;
}
/*--------------------------------------*/
void extra_space ( double x, double y)
{
es_x = x; /* save extra space for char_plot */
es_y = y;
char_xspace (100.0 * x, 100.0 * y); /* char_xspace takes % values */
return;
}
/*--------------------------------------*/
void char_plot (FILE *infile)
{
double x, y, x_1, y_1;
double lsin, lcos, xdir, ydir;
if (get_val (infile, &x)) /* get # spaces */
{ /* got x-value: try for y-value */
if (!get_val (infile, &y)) y = 0.0; /* get # linefeeds (if any) */
}
else /* got no x-value: default to 1 linefeed */
{
move (cp.x, cp.y);
labelf ("\n");
where (&cp.x, &cp.y);
return;
}
/* move x spaces "horizontally" and y lines "vertically" */
/* directions depend on current label direction & mirroring */
DB (printf ("CP: x = %lf, y = %lf, cp.dv = %d\n", x, y, cp.dv);)
DB (printf ("CP1: cp.x = %lf, cp.y = %lf\n", cp.x, cp.y);)
move (cp.x, cp.y);
setgu (); /* this looks like a kludge, but it gets */
where (&x_1, &y_1); /* around problems of not knowing character */
/* sizes in both plotter and user units */
lcos = cos ( (cp.ldir + cp.dvdir) / RAD_2_DEG );
lsin = sin ( (cp.ldir + cp.dvdir) / RAD_2_DEG ); /* label directions */
xdir = (x_mirror) ? -1.0 : 1.0;
ydir = (y_mirror) ? -1.0 : 1.0; /* correct for P1/P2 mirroring */
switch (cp.dv) /* calculate x, y move from # x, y spaces */
{
case 0: /* horizontal */
x = x * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
y = y * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
break;
case 1: /* -90 degrees: 'x' chars of y-size, 'y' chars of x-size */
x = x * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
y = y * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
break;
case 2: /* 180 degrees */
x = x * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
y = y * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
break;
case 3: /* 90 degrees: 'x' chars of y-size, 'y' chars of x-size */
x = x * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
y = y * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
break;
default: break;
}
/* now rotate char offset to label direction */
x_1 += x * lcos - y * lsin;
y_1 += y * lcos + x * lsin;
move (x_1, y_1); /* new position */
setuu ();
where (&cp.x, &cp.y);
DB (printf ("CP2: cp.x = %lf, cp.y = %lf\n", cp.x, cp.y);)
return;
}
/*--------------------------------------*/
void label_graph (FILE * infile)
{
double xpos, ypos, x_offset, y_offset;
unsigned char c2;
int i;
DB (printf ("LB\n");)
setgu (); /* switch to GDU's */
where ( &xpos, &ypos ); /* get current position in GDU's */
x_offset = y_offset = 0.0;
if (cp.lorg < 10) /* anchor label to edges of label */
{
switch (cp.lorg) /* these offsets derived by experimentation */
{
case 1:
y_offset = -0.386 * cs.csize_y;
x_offset = -0.10 * cs.csize_x;
break;
case 2:
x_offset = -0.10 * cs.csize_x;
break;
case 3:
y_offset = 0.303 * cs.csize_y;
x_offset = -0.10 * cs.csize_x;
break;
case 4:
y_offset = -0.386 * cs.csize_y;
break;
case 5: break; /* centered in (x,y) */
case 6:
y_offset = 0.303 * cs.csize_y;
break;
case 7:
x_offset = 0.09 * cs.csize_x;
y_offset = -0.386 * cs.csize_y;
break;
case 8:
x_offset = 0.09 * cs.csize_x;
break;
case 9:
y_offset = 0.303 * cs.csize_y;
x_offset = 0.09 * cs.csize_x;
break;
default: break;
}
move (xpos + x_offset, ypos + y_offset); /* correct for normally offset label origins */
lorg (cp.lorg);
}
else /* normal label origins: offset from edges of labels */
{
lorg (cp.lorg - 10);
}
setuu (); /* back to user units */
i = 0;
while ( 1 )
{
label_bfr[i] = c2 = getc (infile);
if (i >= LABEL_BFR - 1 || c2 == '\n')
{
label_bfr[++i] = '\0'; /* terminate label string */
labelf ("%s", label_bfr); /* label the plot */
if (c2 == '\n')
{
setgu ();
imove (-x_offset, -y_offset); /* remove for label origin offset */
setuu ();
where (&cp.x, &cp.y); /* get label position: new <cr> position for CP fn. */
setgu ();
imove (x_offset, y_offset); /* restore for label origin offset */
setuu ();
}
i = 0;
continue;
}
if (c2 == endlabel || c2 == (char) EOF)
{
label_bfr[i] = '\0'; /* terminate label string */
labelf ("%s", label_bfr); /* label the plot */
setgu ();
imove (-x_offset, -y_offset); /* remove for label origin offset */
setuu ();
break;
}
label_bfr[i++] = c2;
}
DB (printf ("end: LB\n");)
plotted_on (1); /* we drew something on this plot */
return;
}
/*--------------------------------------*/
void define_path (FILE * infile)
{
double path, line;
int l, p;
if (!get_val (infile, &path)) /* no parameters-> defaults */
{
cp.dv = 0; /* store label direction for CP fn. */
cp.dvdir = 0.0; /* clear stacking direction */
cdir (0); /* char direction along label direction */
ldir (cp.ldir); /* horizontal label directions */
return;
}
if (path < 0.0 || path > 3.0)
return; /* illegal values: do nothing */
p = (int) path;
if ( get_val (infile, &line))
{ /* have a linefeed type param */
print_string ("DV: linefeed parameter not implimented\n");
if (line != 0.0 || line != 1.0)
l = 0; /* force default for illegal value */
else
l = (int) line;
}
switch (p)
{
case 0: /* normal directions */
cdir (0.0);
cp.dvdir = 0.0; /* normal stacking direction */
cp.dv = 0; /* store direction code for CP fn. */
break;
case 1: /* down with vertical stacking */
cdir (90.0);
cp.dvdir = -90.0; /* downward label stacking */
cp.dv = 1; /* store label direction for CP fn. */
break;
case 2: /* left, with reversed lettering */
cdir (180.0);
cp.dvdir = 180.0; /* left label stacking */
cp.dv = 2; /* store label direction for CP fn. */
break;
case 3: /* up with vertical stacking, reversed */
cdir (-90.0);
cp.dvdir = 90.0; /* upward label stacking */
cp.dv = 3; /* store label direction for CP fn. */
break;
default: break;
}
ldir (cp.ldir + cp.dvdir); /* rotate DV angle by label direction */
return;
}
/*--------------------------------------*/
void symbol_mark (unsigned char symbol)
{
lorg (5);
labelf ("%c", symbol);
if (cp.lorg < 10)
lorg (cp.lorg);
else
lorg (cp.lorg - 10);
return;
}
/*--------------------------------------*/
void label_term (FILE * infile)
{
unsigned l;
double x;
l = (unsigned) getc (infile);
/* test for illegal values */
if ( l < 1 || l > 127 || l == 5 || l == 27) return;
endlabel = l;
return;
}
/*--------------------------------------*/
void label_dir (FILE * infile, int type)
{ /* set relative character direction */
double rise, run;
if ( !get_val (infile, &run)) /* get run value */
{ /* No value: ldir defaults to 0.0 */
cp.ldir = 0.0; /* save for CP fn. */
ldir (cp.dvdir); /* label in direction of text stacking */
return;
}
if ( !get_val (infile, &rise)) /* get rise value */
{
return; /* no rise coordinate: error: do nothing */
}
if (!type) /* absolute label direction */
{ /* set absolute angle, & save for CP fn. */
cp.ldir = RAD_2_DEG * atan2 (rise, run);
ldir ( cp.ldir + cp.dvdir );
return;
}
if (rise < -128.0 || rise > 127.9999 || run < -128.0 || run > 127.9999) return; /* fault */
rise = rise * (p2y - p1y) / 100.0;
run = run * (p2x - p1x) / 100.0; /* relative angle determined by delta P1:P2
/* set relative angle & save for CP fn. */
cp.ldir = RAD_2_DEG * atan2 (rise, run);
ldir ( cp.ldir + cp.dvdir );
return;
}
/*--------------------------------------*/
void begin_plot (FILE * infile)
{
double x;
unsigned l;
unsigned char c;
if ( plotted_on (0) )
{
twait (infile, PG_DELAY); /* if we have a plot already up, delay screen clear */
gclear ();
}
initialize (infile); /* initialize plotter */
if (!get_val (infile, &x)) return; /* no arguments */
do /* process arguments */
{
l = (int) x;
switch (l)
{
case 1: /* newstring (in quotes) */
c = getc (infile); /* find 1st '"' char */
while (c && c != (unsigned char) EOF && c != '"') c = getc (infile);
c = getc (infile); /* dump everything through next '"' char */
while (c && c != (unsigned char) EOF && c != '"') c = getc (infile);
break;
case 2: /* number of copies: NOP */
if (!get_val (infile, &x)) /* mus supply a value, anyway */
{
print_string ("BP: missing argument to number of copies\n");
return;
}
break;
case 3: /* file disposition code: NOP */
if (!get_val (infile, &x)) /* must supply a disposition code, anyway */
{
print_string ("BP: missing file disposition code\n");
return;
}
break;
case 4: /* render last plot if unfinished */
if (!get_val (infile, &x))
{
print_string ("BP: incomplete 'unfinished plot' rendering code\n");
break;
}
default:
print_string ("BP: invalid kind parameter\n");
return; /* stop processing BP at invalid kind */
break;
}
}
while (get_val (infile, &x));
return;
}
/*--------------------------------------*/
void page_adv (FILE * infile)
{
double x;
get_val (infile, &x); /* get possibly one value */
setgu ();
move (0.0, 0.0); /* move to lower left corner of hard clip */
setuu ();
twait (infile, PG_DELAY); /* delay PG_DELAY seconds */
gclear ();
plotted_on (0); /* new page */
return;
}
/*--------------------------------------*/