From: ecsd@tfs.com (Eric C. S. Dynamic)
Subject: HP LJ-3 HP/GL-2 mode plotting code, 690+ lines (sorry)
Keywords: plot code
Organization: ECSD
Date: Sat, 10 Oct 1992 06:05:55 GMT

The program below takes as input, a .POS file (my own standard format)
and produces an HP/GL-2 plot file, sent to the printer or to a file.
The target device is an HP LJ-3. Page Protect should be On, Letter to
use this (I have 5MB ram in my LJ.) Also, if you send output to a file,
you plot by "copy /b filename prn" and DOS may complain about printer
timeouts; just reply 'R' (retry). The full set of planets and asteroids
I use almost always causes timeouts (the device does rendering as it
receives the commands, which makes the computer wait.)

The .POS file contains lines "xx sss nnnn" where xx is the abbreviation for
a body, sss the abbreviation for a sign, and nnnn is minutes-seconds.
It may also contain lines "*name" and "@other information". This program
prints the contents of these lines as a title in the upper left of the page.

The program has the following flaws: (1) it prints ascii names for symbols,
rather than symbols themselves; I need to develop a font for the plot mode.
(2) it overprints things too closely conjunct. I haven't developed a tiling
algorithm to fix this yet.

The orbs for the aspects can be adjusted (same for any pair of planets,
sorry) - in array 'asptbl' below, values are in minutes of arc.

The program generates a European style wheel, with aspect lines in the center.
The program is not well documented, so if you have any questions, ASK ME.
The below program is complete in itself - written for Microsoft C 5.1.
The copyright is to protect my investment of time - that someone will not
sell something which uses this code without my also profitting. If you want to
incorporate portions of this into something for sale, let me know, my 'terms'
are very reasonable. If you develop this further, or redevelop it, I would
appreciate receiving a copy - under the same obligations.

Below is partial contents of the .POS file for my chart. My house cusps are
here, for those who wanted them, and they know who they are.

*Eric C. S. Dynamic
su cap 2731
mo ari 0019
me aqu 1327
ve pis 0117
nn sag 1509
as pis 1751
02 tau 0316
03 gem 0158
ic gem 2346
05 can 1431
06 leo 0921

/*---------------------------------------------------------------------------*/
/* ch3.c - Plot a chart file on HP LJ III printer (MS C 5.1)
/*---------------------------------------------------------------------------*/
/* Eric C. S. Dynamic: PROPRIETARY program source code
/* (C) Copyright 1991, 1992, Eric C. S. Dynamic - all rights reserved
/* This material may be copied and distributed provided the copyright
/* information and this notice remain intact. This material may be used
/* freely for experimental purposes but may not be incorporated into a
/* product to be sold or licensed without the express written permission of
/* Eric C. S. Dynamic. Address inquiries to:
/* P.O.Box 278, Berkeley, CA 94701-0278 USA.
/*---------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/*---------------------------------------------------------------------------*/
#if 0
unsigned char font[256*16] =
	{
	#include <fontdef.h>
	};
#endif
/*---------------------------------------------------------------------------*/
/* Planets, Signs, Aspects
/*---------------------------------------------------------------------------*/

struct plrec
	{
	char psname[3], plname[9];
	int qasp;
	int known,arc,ax,ay;
	};

struct plrec P[] =
#define XSU 00  /* Sun */
	{{"Su","Sun", 1, 0,0,0,0 }
#define XMO 01  /* Moon */
	,{"Mo","Moon", 1, 0,0,0,0 }
#define XME 02  /* Mercury */
	,{"Me","Mercury", 1, 0,0,0,0 }
#define XVE 03  /* Venus */
	,{"Ve","Venus", 1, 0,0,0,0 }
#define XMA 04  /* Mars */
	,{"Ma","Mars", 1, 0,0,0,0 }
#define XJU 05  /* Jupiter */
	,{"Ju","Jupiter", 1, 0,0,0,0 }
#define XSA 06  /* Saturn */
	,{"Sa","Saturn", 1, 0,0,0,0 }
#define XUR 07  /* Uranus */
	,{"Ur","Uranus", 1, 0,0,0,0 }
#define XNE 08  /* Neptune */
	,{"Ne","Neptune", 1, 0,0,0,0 }
#define XPL 09  /* Pluto */
	,{"Pl","Pluto", 1, 0,0,0,0 }
#define XNN 10  /* North Node */
	,{"NN","N.Node", 1, 0,0,0,0 }
#define XSN 11  /* South Node */
	,{"SN","S.Node", 1, 0,0,0,0 }
#define XCE 12  /* Ceres */
	,{"Ce","Ceres", 0, 0,0,0,0 }
#define XPA 13  /* Pallas Athena */
	,{"Pa","Pallas", 0, 0,0,0,0 }
#define XJO 14  /* Juno */
	,{"Jo","Juno", 0, 0,0,0,0 }
#define XVS 15  /* Vesta */
	,{"Vs","Vesta", 0, 0,0,0,0 }
#define XPY 16  /* Psyche */
	,{"Py","Psyche", 0, 0,0,0,0 }
#define XER 17  /* Eros */
	,{"Er","Eros", 0, 0,0,0,0 }
#define XSP 18  /* Sappho */
	,{"Sp","Sappho", 0, 0,0,0,0 }
#define XAM 19  /* Amor */
	,{"Am","Amor", 0, 0,0,0,0 }
#define XTO 20  /* Toro */
	,{"To","Toro", 0, 0,0,0,0 }
#define XLL 21  /* Lilith */
	,{"Ll","Lilith", 0, 0,0,0,0 }
#define XDI 22  /* Diana */
	,{"Di","Diana", 0, 0,0,0,0 }
#define XHD 23  /* Hidalgo */
	,{"Hd","Hidalgo", 0, 0,0,0,0 }
#define XIK 24  /* Icarus */
	,{"Ik","Icarus", 0, 0,0,0,0 }
#define XPD 25  /* Pandora */
	,{"Pd","Pandora", 0, 0,0,0,0 }
#define XUA 26  /* Urania */
	,{"Ua","Urania", 0, 0,0,0,0 }
#define XCH 27  /* Chiron */
	,{"Ch","Chiron", 0, 0,0,0,0 }
#define XPF 28  /* Part of Fortune */
	,{"PF","Fortune", 1, 0,0,0,0 }
#define XPS 29  /* Part of Spirit */
	,{"PS","Spirit", 1, 0,0,0,0 }
#define X01 30  /* Ascendant */
	,{"As","Asc", 1, 0,0,0,0 }
#define X02 31  /* 2nd house cusp */
	,{"02","02", 0, 0,0,0,0 }
#define X03 32  /* 3rd house cusp */
	,{"03","03", 0, 0,0,0,0 }
#define X04 33  /* Imum Coeli (Nadir, 4th house cusp) */
	,{"IC","IC", 0, 0,0,0,0 }
#define X05 34  /* 5th house cusp */
	,{"05","05", 0, 0,0,0,0 }
#define X06 35  /* 6th house cusp */
	,{"06","06", 0, 0,0,0,0 }
#define X07 36  /* Descendant */
	,{"Ds","Dsc", 0, 0,0,0,0 }
#define X08 37  /* 8th house cusp */
	,{"08","08", 0, 0,0,0,0 }
#define X09 38  /* 9th house cusp */
	,{"09","09", 0, 0,0,0,0 }
#define X10 39  /* Medium (?) Coeli (Midheaven, 10th house cusp) */
	,{"MC","MC", 1, 0,0,0,0 }
#define X11 40  /* 11th house cusp */
	,{"11","11", 0, 0,0,0,0 }
#define X12 41  /* 12th house cusp */
	,{"12","12", 0, 0,0,0,0 }
	};
#define MAXP ( sizeof(P) / sizeof(struct plrec) )

/* Alternate names */
#define XAS X01
#define XIC X04
#define XDS X07
#define XMC X10

/* Table of opposites */
int oppn[]=
	{X01,X07
	,X02,X08
	,X03,X09
	,X04,X10
	,X05,X11
	,X06,X12
	,XNN,XSN
	};
#define NOPP (sizeof(oppn)/sizeof(int))

char sname[12][4]=
	{"Ari","Tau","Gem","Can","Leo","Vir"
	,"Lib","Sco","Sag","Cap","Aqu","Pis"};

/* Aspects */

struct adrec { char name[4]; int pen,loc,lo,hi; } asptbl[] =
	{
		{"01", 0,     0,     0,  480  },
		{"1C", 1,  1800,  1680, 1920  },
		{"19", 3,  2400,  2340, 2460  },
		{"18", 2,  2700,  2610, 2790  },
		{"17", 7,  3086,  3026, 3146  },
		{"16", 8,  3600,  3390, 3810  },
		{"15", 5,  4320,  4260, 4380  },
		{"29",-1,  4800,  4740, 4860  },
		{"14", 0,  5400,  5040, 5760  },
		{"27", 7,  6171,  6111, 6231  },
		{"13", 8,  7200,  6840, 7560  },
		{"38", 2,  8100,  8010, 8190  },
		{"25", 5,  8640,  8580, 8700  },
		{"5C", 1,  9000,  8730, 9270  },
		{"37", 7,  9257,  9197, 9317  },
		{"49",-1,  9600,  9540, 9660  },
		{"12", 0, 10800, 10320, 10800 },
	};
#define MAXA ( sizeof(asptbl) / sizeof(struct adrec) )

/*---------------------------------------------------------------------------*/

#define ESC "\x1b"
#define ETX "\x03"

/*---------------------------------------------------------------------------*/

#define PI 3.141592653589793
#define D2R (PI/180.0)
#define R2D (180.0/PI)

/* Circular functions, minutes */
#define cir(x)    ( (int) ( ( (long)(x) + 43200L    ) % 21600 ) )
#define cadd(x,y) ( (int) ( ( (long)(x) + (long)(y) ) % 21600 ) )
#define csub(x,y) ( (int) ( ( (long)(x) - (long)(y) ) % 21600 ) )

/*---------------------------------------------------------------------------*/

#define XMAX   (2400)
#define YMAX   (3300)

#define XORG   (XMAX/2)
#define YORG   (YMAX/2)
#define RADIUS (XMAX/2 - 50)

/*---------------------------------------------------------------------------*/

FILE *fp;

#define BUFMAX 256
char buf[BUFMAX],file[BUFMAX];

#define USRMAX 12
char username[81];
char userdata[USRMAX][81];
int userlines;

double w1 = 1.00 * (double) RADIUS;
double w2 = 0.90 * (double) RADIUS;
double w3 = 0.85 * (double) RADIUS;
double w4 = 0.75 * (double) RADIUS;

int morigin;
double origin;

int hvhouses;

/*---------------------------------------------------------------------------*/
#pragma page()
/*---------------------------------------------------------------------------*/

int quadrant(double angle)
{
if( angle <= 180.0 )
	if( angle <= 90.0 ) return(0);
	else return(1);
else
	if( angle <= 270.0 ) return(2);
	else return(3);
}

double XDotsPerChar, YDotsPerChar;

void settextparms( int pitch, int points )
{

XDotsPerChar = 300.0 / (double)pitch;
YDotsPerChar = 300.0 * (double)points / 72.0;

sprintf(file,
	"SD3,%d,4,%d,6,9999;" /* cpi, points, stick-font one dot thick */
	,pitch,points
	);
fprintf(fp,file);

return;
}

#define CENTERED 0
#define FLUSH    1

void radialtext( double angle, double r1, double r2, char *text, int flush )
{
double x,cx,sx,dx,dy,run,rise,radius;
int q;

angle = fmod( angle + 360.0, 360.0 );

x = D2R * angle; cx = cos(x); sx = sin(x);

/* Determine character direction for label */
q = quadrant(angle);
run = fabs(cx);
if( (q == 0) || (q == 2) ) rise = fabs(sx); /* "Up" to East */
else rise = -fabs(sx);                      /* "Up" to West */

/* Determine radius of start of text */
x = XDotsPerChar * (double)strlen(text);
if( flush == FLUSH )
	if( (q == 0) || (q == 3) ) radius = r2 + XDotsPerChar;
	else radius = r2 + x + ( 2.0 / 3.0 ) * XDotsPerChar;
else
	{
	x = ( r1 - r2 - x ) / 2.0;
	if( (q == 0) || (q == 3) ) radius = r2 + x;
	else radius = r1 - x;
	}

/*
Set direction,
move cursor so that radius line bisects middle of character cell,
plot text
*/
x = YDotsPerChar / 4.0;
switch(q)
	{
	case 0: case 3: dx = x;  dy = -x; break;
	case 1: case 2: dx = -x; dy = x; break;
	}
sprintf(file,"DI%6.3f,%6.3f;PU%d,%d;LB%s" ETX
	,run ,rise
	,XORG + (int)( radius * cx + dx * sx )
	,YORG - (int)( radius * sx + dy * cx )
	,text
	);
fprintf(fp,file);

return;
}

/*---------------------------------------------------------------------------*/
#pragma page()
/*---------------------------------------------------------------------------*/

void main( int argc, char *argv[] )
{
double angle, x, cx, sx;
int i,j,k,l,m, rc;

int seen;
char pn[3],sn[4];
char ifn[100],ofn[100];
struct adrec *ap;

*username = *ifn = *ofn = '\0';
for( i = 0; i < MAXP; i++ ) P[i].known = 0;

/*===========================================================================*/
#pragma page()
/*===========================================================================*/
/* Process user options
/*===========================================================================*/

rc = 0;
if( argc < 2 ) rc = 1;
else
	for( i = 1; i < argc; i++ )
		{
		if( !strncmp("-f",argv[i],2) )
			{
			if( argv[i][2] ) { strcpy( ofn, argv[i]+2 ); continue; }
			if( ++i < argc ) { strcpy( ofn, argv[i] ); continue; }
			printf("Missing filename after '-f'.\n");
			rc = 1;
			break;
			}
		if( argv[i][0] == '-' )
			{
			printf("Unknown option supplied: %s\n",argv[i]);
			rc = 1;
			break;
			}
		if( *ifn )
			{
			printf("Ambiguous arguments...\n");
			rc = 1;
			break;
			}
		strcpy(ifn,argv[i]);
		}

if(rc)
		{
		fprintf(stdout,"Usage: ch3 filename [-f outfile]\n");
		exit(1);
		}

/*===========================================================================*/
#pragma page()
/*===========================================================================*/
/* Input the chart
/*===========================================================================*/

fp = fopen(ifn,"r");
if( fp == NULL )
	{
	fprintf(stdout,"Cannot open input file \"%s\".\n",ifn);
	exit(1);
	}

/* Input planet positions */
for( userlines = seen = 0; ; )
	{
	if( fgets(buf,BUFMAX,fp) == NULL ) break;
	rc = 0;
	switch( *buf )
		{
		case '\0':
			break;
		case '*':
			*(buf+strlen(buf)-1) = '\0';
			strcpy( username, buf+1 );
			break;
		case '@':
			if( userlines >= USRMAX ) break;
			*(buf+strlen(buf)-1) = '\0';
			strcpy( userdata[userlines++], buf+1 );
			break;
		default:
			if( sscanf(buf,"%2s %3s %2d%2d",pn,sn,&i,&j) != 4 )
				{ rc = 1; break; }
			l = 60 * i + j;
			k = -1;
			for( k = -1, i = 0; i < MAXP; i++ )
				if( !strcmpi( pn, P[i].psname ) ) { k = i; break;}
			if( k < 0 ) { rc = 1; break; }
			for( j = -1, i = 0; i < 12; i++ )
				if( !strcmpi( sn, *(sname+i) ) ) { j = i; break; }
			if( j < 0 ) break;
			P[k].arc = 1800 * j + l;
			P[k].known = 1;
			seen++;
			break;
		}
	if(rc) printf("Error in input data. Tough darts!\n");
	}
fclose(fp);
if( !rc && !seen )
	{
	printf("No planetary data, nothing to plot.\n");
	rc = 1;
	}
if(rc) exit(1);

/*===========================================================================*/
#pragma page()
/*===========================================================================*/
/* Calculations prior to plotting
/*===========================================================================*/

/* Install values for polar opposites */
for( i = 0; i < NOPP; i += 2 )
	{
	j = oppn[i]; k = oppn[i+1];
	if( P[j].known && !P[k].known )
		{ P[k].arc = cir(cadd(P[j].arc,10800)); P[k].known = 1; }
	else if(!P[j].known && P[k].known)
		{ P[j].arc = cir(cadd(P[k].arc,10800)); P[j].known = 1; }
	}

/* Calculate parts if possible */
if( P[XSU].known && P[XMO].known && P[XAS].known )
	{
	i = P[XSU].arc - P[XMO].arc;
	P[XPF].arc = cir(csub(P[XAS].arc,i)); P[XPF].known = 1;
	P[XPS].arc = cir(cadd(P[XAS].arc,i)); P[XPS].known = 1;
	}

/* Establish rotation parameters vs. ascendant */
if( !P[XAS].known ) /* Don't know the ascendant, start Aries in the East */
	{ morigin = 10800; origin = 180.0; }
else /* Put the ascendant in the East, and find start of Aries */
	{
	morigin = cir( csub( 10800, P[XAS].arc ) );
	origin = (double)morigin / 60.0;
	}

/* If houses not known and Sun is known, use equal-house system */
if( !P[XAS].known && P[XSU].known )
	{
	j = P[XSU].arc;
	for( i = X01; i <= X12; i++, j = cir(cadd(j,1800)) )
		{ P[i].arc = j; P[i].known = 1; }
	}

/* If houses still not known, collapse the chart to eliminate houses */
if( P[XAS].known ) hvhouses = 1;
else { hvhouses = 0; w4 = w2 - ( w1 - w2 ); w3 = w2; }

/* Establish inner-circle coordinates of each body or point */
for( i = 0; i < MAXP; i++ ) if( P[i].known )
	{
	angle = D2R * ( origin + (double)P[i].arc / 60.0 );
	P[i].ax = (int)( XORG + w4 * cos(angle) );
	P[i].ay = (int)( YORG - w4 * sin(angle) );
	}

/*===========================================================================*/
#pragma page()
/*===========================================================================*/
/* Plot the chart
/*===========================================================================*/

/* Open the output unit */
if( !*ofn ) fp = stdprn;
else if( (fp = fopen(ofn,"wb")) == NULL )
	{ printf("Cannot open output file '%s'\n",ofn); exit(1); }

/* Initialize, put in plotting mode. Make GL coordinates same as PCL. */
sprintf(file,
	ESC "E"              /* Reset printer                            */
	ESC "&l2A"           /* Page size letter                         */
	ESC "&l0O"           /* Portrait                                 */
	ESC "&l0E"           /* Top margin 0                             */
	ESC "*r0F"           /* Graphics orientation logical, not phys.  */
	ESC "*t300R"         /* Set graphics density to 300 dpi          */
	ESC "*p0x0Y"         /* Move to (0,0)                            */
	ESC "*c5760x7920Y"   /* Set picture frame to 8" x 11"            */
	ESC "*c0T"           /* Anchor picture frame at PCL cursor       */
	ESC "%%1B"           /* Enter HP/GL-2 mode, pen at PCL cursor    */
	"IN;"                /* GL Initialize                            */
	"SP1;"               /* Select black pen                         */
	"PW0;"               /* Pen widths - one dot                     */
	"SC0,2400,3300,0,1;" /* Scale & flip Y to match PCL addressing   */
	);
fprintf(fp,"%s",file);

/* Set line fill parameters */
sprintf(file,
	"UL1,10,1,0,1;"  /* dash, 1 dot */
	"UL2,10,1,0,1,0,1;"  /* dash, 2 dots */
	"UL3,10,1,0,1,0,1,0,1;"  /* dash, 3 dots */
	"UL4,10,1,0,1,0,1,0,1,0,1;"  /* dash, 4 dots */
	"UL5,10,1,0,1,0,1,0,1,0,1,0,1;"  /* dash, 5 dots */
	"UL6,10,1,0,1,0,1,0,1,0,1,0,1,0,1;"  /* dash, 6 dots */
	"UL7,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1;"  /* dash, 7 dots */
	"UL8,10,1;"  /* dashes */
	);
fprintf(fp,file);

/*---------------------------------------------------------------------------*/
/* Print user info
/*---------------------------------------------------------------------------*/

sprintf(file,"PU0,0;CP;CP;LB");
fprintf(fp,file);
if( *username ) fprintf(fp,"%s\n\r", username );
for( i = 0; i < userlines; i++ )
	{
	sprintf(file,"%s\n\r", userdata[i] );
	fprintf(fp,file);
	}
sprintf(file,ETX);
fprintf(fp,file);

/*---------------------------------------------------------------------------*/
/* Draw concentric circles
/*---------------------------------------------------------------------------*/

if( P[XAS].known ) /* Chart with houses */
	sprintf(file,"PU%d,%d;CI%d,2;CI%d,2;CI%d,2;CI%d,2;"
		,XORG,YORG,(int)w1,(int)w2,(int)w3,(int)w4
		);
else /* Chart without houses */
	sprintf(file,"PU%d,%d;CI%d,2;CI%d,2;CI%d,2;"
		,XORG,YORG,(int)w1,(int)w2,(int)w4
		);
fprintf(fp,file);

/* Set subsequent char output to small text */
settextparms(30,4); /* 30cpi, 4 point */

/*---------------------------------------------------------------------------*/
/* Draw sign boundaries
/*---------------------------------------------------------------------------*/

for( angle = origin, i = 0; i < 12; i++, angle += 30.0 )
	{
	/* Draw sign boundary */
	x = D2R * angle; cx = cos(x); sx = sin(x);
	sprintf(file,"PU%d,%d;PD%d,%d;"
		,XORG + (int)(w1*cx) , YORG - (int)(w1*sx)
		,XORG + (int)(w2*cx) , YORG - (int)(w2*sx)
		);
	fprintf(fp,file);
	}

/*---------------------------------------------------------------------------*/
/* Draw sign symbols
/*---------------------------------------------------------------------------*/

for( angle = origin + 15.0, i = 0; i < 12; i++, angle += 30.0 )
	radialtext( angle, w1, w2, sname[i], CENTERED );

/*---------------------------------------------------------------------------*/
/* Draw house numbers
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Draw house boundaries and coordinates
/*---------------------------------------------------------------------------*/

if( hvhouses ) for( k = X01; k <= X12; k++ )
	{
	angle = origin + (double)P[k].arc / 60.0;
	x = D2R * angle; cx = cos(x); sx = sin(x);
	/* Draw boundary line */
	sprintf(file,"PU%d,%d;PD%d,%d;"
		,XORG + (int)(w2*cx) , YORG - (int)(w2*sx)
		,XORG + (int)(w3*cx) , YORG - (int)(w3*sx)
		);
	fprintf(fp,file);
	sprintf(buf,"%02d%02d", (P[k].arc / 60) % 30, P[k].arc % 60 );
	radialtext( angle, w1, w2, buf, FLUSH );
	}

/*---------------------------------------------------------------------------*/
/* Draw planet symbols and coordinates
/*---------------------------------------------------------------------------*/

for( k = XSU; k < MAXP; k++ ) if( P[k].known )
	{
	if( (k >= X01) && !P[k].qasp ) continue;
	angle = origin + (double)P[k].arc / 60.0;
	if( k < X01 )
		{
		sprintf(buf,"%02d%02d", (P[k].arc / 60) % 30, P[k].arc % 60 );
		radialtext( angle, w2, w3, buf, CENTERED );
		}
	radialtext( angle, w3, w4, P[k].plname, FLUSH );
	}

/*---------------------------------------------------------------------------*/
/* Calculate aspects and draw aspect lines
/*---------------------------------------------------------------------------*/
for( i = 0; i < NOPP; i += 2 )
	{
	j = oppn[i]; k = oppn[i+1];
	if( P[j].known && !P[k].known )
		{ P[k].arc = cir(cadd(P[j].arc,10800)); P[k].known = 1; }
	else if(!P[j].known && P[k].known)
		{ P[j].arc = cir(cadd(P[k].arc,10800)); P[j].known = 1; }
	}

for( i = 0; i < MAXP - 1; i++ ) if( P[i].known && P[i].qasp )
	{
	for( m = -1, k = 0; k < NOPP; k++ )
		if( i == oppn[k] )
			{
			if( k % 2 ) m = k + 1; else m = k - 1;
			break;
			}
	for( l = P[i].arc, j = i + 1; j < MAXP; j++ )
	if( P[j].known && P[j].qasp && j != m )
		{
		k = l - P[j].arc;
		if( k < 0 ) k = -k;
		if( k > 10800 ) k = 21600 - k;
		for( ap = asptbl; ap < asptbl + MAXA; ap++ )
			if( (ap->lo <= k) && (k <= ap->hi) )
				{
				if( ap->pen < 0 ) break;
				if( ap->pen )
					{
					sprintf(file,"LT-%d;",ap->pen);
					fprintf(fp,file);
					}
				sprintf(file,"PU%d,%d;PD%d,%d;LT;"
					,P[i].ax,P[i].ay,P[j].ax,P[j].ay
					);
				fprintf(fp,file);
				break;
				}
		}
	}

/*---------------------------------------------------------------------------*/
/* Draw aspect symbols
/*---------------------------------------------------------------------------*/

/*===========================================================================*/
/* All fucking done.
/*===========================================================================*/

sprintf(file,"%s",(ESC "%%0A")); /* Exit HP/GL-2 mode */
fprintf(fp,file);
sprintf(file,ESC "E");         /* Reset printer, ejects current page buffer */
fprintf(fp,file);

fflush(fp);
fclose(fp);

return;
}

/*---------------------------------------------------------------------------*/
/* End - ch3.c
/*---------------------------------------------------------------------------*/