damc@natmlab.dms.oz.AU (Don McCormick) (12/07/88)
Posting-number: Volume 5, Issue 67 Submitted-by: Don McCormick <damc@natmlab.dms.oz.AU> Archive-name: hpgl2ps-v2 I am posting this improved version of hpgl2ps. The filter will work on the HPGL output from the CAD packages, AUTOCAD and VERSACAD. Don McCormick #--------------------------- Cut here ------------------------------------------ # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # README dxy2ps.man hpgl2ps.man Makefile changesizes.c circle.c defcoords.c defn.h dxy2ps.c dxycom.c end_draw.c getval.c hpgl2ps.c hpglcom.c linesize.c linetype.c manualfeed.c plotdot.c plotinit.c plotps.c ps_macros.c rectangle.c textps.c viewport.c window.c test1.dxy test1.hpgl echo x - README cat > "README" << '//E*O*F README//' There are two filters in this package that are based on the Roland plotter command set. 1. DXY: A simple command set that is used with all DXY plotters 2. RD-GL: This command set is a superset of the HP (Hewlett Packard) graphics language however it is compatable with the 7475A command set. In fact this version of the hpgl2ps filter has been rewritten using the 7475A command hand book. Not all the commands of DXY or RD-GL (HPGL) are implemented (approx 95% are) and those commands that are not are skipped and a warning given. It is very easy to add to this filter if a particular unimplemented command is desired. If you wish to implement a command go to the relevant portion in the command switch "dxycom.c" or "hpglcom.c" and call an appropriate user written procedure. (You will need a good knowledge of writing PostScript programs). Also don't forget to put the procedure name in the Makefile. The filters call the procedure "getopt" that is used to interpret command line options and arguments and is normally available on 4.3 bsd and Sys V Unix. For those sites running 4.1 or 4.2 it may be available as a local library and must be written into the Makefile. IF YOU DONT HAVE GETOPT YOU WILL HAVE REWRITE THE CODE THAT INTERPRETS COMMAND LINE OPTIONS AND ARGUMENTS. A procedure called "rint" is called in "dxycom.c" and "linetype.c" if you dont have this call in your maths library then the following C code will have to be written. Call the following rint.c (put "rint.o" in the Makefile). /*-----------Start rint.c------------------*/ int rint(f) double f; {return (int)(f + ((f>0) ? 0.5 : -0.5));} /*------------ End rint.c------------------*/ NOTE 1: The PostScript macros are written into a C procedure to allow each filter to be a single stand alone program. These macros can easily be incorporated into other filter programs. NOTE 2: I have written some test procedures for the testing of each filter they are "test1.hpgl" for hpgl2ps and "test1.dxy" for dxy2ps. Don McCormick. //E*O*F README// echo x - dxy2ps.man cat > "dxy2ps.man" << '//E*O*F dxy2ps.man//' .TH DXY2PS (1L) "25 September 1987" .SH NAME dxy2ps - A Roland DXY plot command filter to PostScript .SH SYNOPSIS \fBdxy2ps\fR [\fB-amr\fR] [\fB-l \fIline sizes\fR] [\fB-s \fIscale\fR] [\fB-x \fIoffset\fR] [\fB-y \fIoffset\fR] [\fIplotfile\fR] .SH DESCRIPTION This filter is used to convert the Roland DXY and the Roland Graphics Language (RD-GL) (which is a superset of the Hewlet Packard Graphics Language (HP-GL)) commands to PostScript. .PP The RD-GL commands are only operated on if each command is prefixed with a "^", therfore if your plotfile only contains HP-GL or RD-GL commands use the filter \fBhpgl2ps\fR. .PP The default conditions for \fBdxy2ps\fR are: .TP .B 1. The plot translation is from ISO A3 (420mm x 297mm) to ISO A4 (297mm x 210mm) on the LaserWriter. .TP .B 2. Line thicknesses are in millimeters and are for lines (pens) 1 to 9: ( 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.25, 1.5 ) .TP .B Note: If the plotfile is not specified then standard input is assumed. .SH ARGUMENTS .TP .B -a Draw on an A4 ISO (297mm x 210mm) sheet of paper. This will give an aproximate 1:1 translation to the LaserWriter. .TP \fB-l \fIline sizes\fR This option allows the default line sizes to be replaced with different sizes starting from line (pen) one through nine. The new sizes (real or integer) are entered in a comma seperated string (\fIline size\fR) and are in millimeters. Only the sizes entered in the string will be changed with respect to lines (pens) one to nine while nonentered line (pen) sizes will retain the default sizes. .sp In the following example only the first three sizes will be changed. .sp eg: dxy2ps -l 0.4,0.3,1 file | lpr -Plaser1 .TP .B -m Enable the manual feed on the LaserWriter (cutoff time 3 minutes). .TP .B -r Rotate plot(s) through 90 degrees. (The plot is made smaller) .TP \fB-s\fI scale\fR Scale the plot from 0.1 to 3 times its original size. .TP \fB-x\fI offset\fR Place an X offset (in mm) in the plot. .TP \fB-y\fI offset\fR Place an Y offset (in mm) in the plot. .PP \fBNote:\fR Offsets are with respect to the 0, 0 (origin) of the HP-GL / RD-GL plotting commands, thus if the minimum plotting coordinates are below either the X and/or Y zero axis then a positive offset is applied. Similarly if the minimum plot coordinates are above the X and/or Y zero axis then a negative offset is applied. .SH FILES /usr/local/bin/dxy2ps .br /usr/local/bin/hpgl2ps .SH AUTHOR Don McCormick .br CSIRO .br Division of Applied Physics .br PO 218, Lindfield, N.S.W., 2070 .br Australia .SH BUGS Some of the graphics commands are unimplemented and a warning will be displayed. If this command is vital then it must be written into the code. .PP No interactive command is suported. .PP If any bugs are found notify damc@natmlab or damc@nifty or root. //E*O*F dxy2ps.man// echo x - hpgl2ps.man cat > "hpgl2ps.man" << '//E*O*F hpgl2ps.man//' .TH HPGL2PS (1L) "25 September 1987" .SH NAME hpgl2ps - A HP (Hewlett Packard) plot command filter to PostScript .SH SYNOPSIS \fBhpgl2ps\fR [\fB-amr\fR] [\fB-l \fIline sizes\fR] [\fB-s \fIscale\fR] [\fB-x \fIoffset\fR] [\fB-y \fIoffset\fR] [\fIplotfile\fR] .SH DESCRIPTION This filter is used to convert the Hewlett Packard Graphic Language (HP-GL) 9873C plotter commands to PostScript. The HP-GL commands are a subset of the Roland plotter command set (RD-GL). .PP The default conditions for \fBhpgl2ps\fR are: .TP .B 1. The plot translation is from ISO A3 (420mm x 297mm) to ISO A4 (297mm x 210mm) on the LaserWriter. .TP .B 2. Line thicknesses are in millimeters and are for lines (pens) 1 to 9: ( 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0, 1.25, 1.5 ) .TP .B Note: If the plotfile is not specified then standard input is assumed. .SH ARGUMENTS .TP .B -a Draw on an A4 ISO (297mm x 210mm) sheet of paper. This will give an aproximate 1:1 translation to the LaserWriter. .TP \fB-l \fIline sizes\fR This option allows the default line sizes to be replaced with different sizes starting from line (pen) one through nine. The new sizes (real or integer) are entered in a comma seperated string (\fIline size\fR) and are in millimeters. Only the sizes entered in the string will be changed with respect to lines (pens) one to nine while nonentered line (pen) sizes will retain the default sizes. .sp In the following example only the first three sizes will be changed. .sp eg: hpgl2ps -l 0.4,0.3,1 file | lpr -Plaser1 .TP .B -m Enable the manual feed on the LaserWriter (cutoff time 3 minutes). .TP .B -r Rotate plot(s) through 90 degrees. (The plot is made smaller) .TP \fB-s\fI scale\fR Scale the plot from 0.1 to 3 times its original size. .TP \fB-x\fI offset\fR Place an X offset (in mm) in the plot. .TP \fB-y\fI offset\fR Place an Y offset (in mm) in the plot. .PP \fBNote:\fR Offsets are with respect to the 0, 0 (origin) of the HP-GL / RD-GL plotting commands, thus if the minimum plotting coordinates are below either the X and/or Y zero axis then a positive offset is applied. Similarly if the minimum plot coordinates are above the X and/or Y zero axis then a negative offset is applied. .SH FILES /usr/local/bin/hpgl2ps .SH AUTHOR Don McCormick .br CSIRO .br Division of Applied Physics .br PO 218, Lindfield, N.S.W., 2070 .br Australia .SH BUGS Some of the graphics commands are unimplemented and a warning will be displayed. If this command is vital then it must be written into the code. .PP No interactive command is suported. .PP If any bugs are found notify damc@natmlab or damc@nifty or root. //E*O*F hpgl2ps.man// echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' # 1.0 dxy2ps and hpgl2ps (Copyright) D McCormick # Commercial reproduction prohibited. # FILTER1= dxy2ps FILTER2= hpgl2ps INSDIR= /usr/local/bin INCLUDE= defn.h LOCALLIB= libroland.a AR= ar ARFLAGS= ru LOADLIBES= -lm CFLAGS= -g OBJ1= dxy2ps.o OBJ2= hpgl2ps.o OBJC= changesizes.o circle.o defcoords.o dxycom.o\ end_draw.o getval.o hpglcom.o linesize.o\ linetype.o manualfeed.o plotdot.o plotinit.o\ plotps.o ps_macros.o rectangle.o textps.o\ viewport.o window.o all: $(FILTER1) $(FILTER2) $(FILTER1): $(LOCALLIB) $(OBJ1) $(CC) $(CFLAGS) -o $@ $(OBJ1) $(LOCALLIB) $(LOADLIBES) $(FILTER2): $(LOCALLIB) $(OBJ2) $(CC) $(CFLAGS) -o $@ $(OBJ2) $(LOCALLIB) $(LOADLIBES) $(LOCALLIB): $(OBJC) $(AR) $(ARFLAGS) $@ $(OBJC) ranlib $(LOCALLIB) $(OBJC): $(INCLUDE) $(OBJ1): $(INCLUDE) $(OBJ2): $(INCLUDE) install: $(FILTER1) $(FILTER2) install -s $(FILTER1) $(INSDIR) install -s $(FILTER2) $(INSDIR) clean: -rm -f *.o a.out core libroland.a //E*O*F Makefile// echo x - changesizes.c cat > "changesizes.c" << '//E*O*F changesizes.c//' /* * This utility will take a string of real numbers seperated by commas and * put them in an array. * * Don McCormick */ #include "defn.h" #define ERROR1 "Only 9 line sizes allowed" #define ERROR2 "Too many decimal points in number" #define ERROR3 "line size specification incorrect" #define ERROR4 "Max no of characters for each line size is 5" changesizes(sizebuf) char sizebuf[50]; { int i; int j = 0; int k = 0; int DECIMAL = 0; float number; char numbuf[5]; for (i = 0; i < 50; i++) { if (sizebuf[i] == ',' || sizebuf[i] == NULL) { if ((number = atof(numbuf)) >= 0.01 && number <= 10) pen_size[j] = number; /* Put number in array */ else fprintf(stderr, "Warning: line size too large ignored \n"); if (sizebuf[i] == NULL) return; if (j++ > 8) { fprintf(stderr, "Error: %s\n", ERROR1); exit(1); } for (k = 0; k < 5; k++) numbuf[k] = NULL; /* Clear number buffer */ k = 0; DECIMAL = 0; /* One decimal per number */ while (sizebuf[i + 1] == ',' && sizebuf[i + 1] != NULL) i++; /* Get rid of extra commas */ } else { if ((sizebuf[i] >= '0' && sizebuf[i] <= '9') || sizebuf[i] == '.') { if (sizebuf[i] == '.') { if (DECIMAL == 1) { fprintf(stderr, "Error: %s\n", ERROR2); exit(1); } DECIMAL = 1; } numbuf[k] = sizebuf[i]; } else { fprintf(stderr, "Error: %s\n", ERROR3); exit(1); } if (k++ > 5) { fprintf(stderr, "Error: %s\n", ERROR4); exit(1); } } } } //E*O*F changesizes.c// echo x - circle.c cat > "circle.c" << '//E*O*F circle.c//' #include "defn.h" circle(type) int type; { float radius; float start_angle = 0; float end_angle = 360; float chord_angle = 0; float Xc, Yc; float percent; float distance; float length; float angle; end_draw(); switch (type) { case RDGLCIRCLE: if (SIGNED_NUMERIC) radius = getval() * XSCALE; if (SIGNED_NUMERIC) chord_angle = getval(); Xc = absX; Yc = absY; break; case CIRCLE: if (SIGNED_NUMERIC) absX = Xc = getval() * XSCALE + XOFFSET; if (SIGNED_NUMERIC) absY = Yc = getval() * YSCALE + YOFFSET; if (SIGNED_NUMERIC) radius = getval() * XSCALE; if (SIGNED_NUMERIC) start_angle = getval(); if (SIGNED_NUMERIC) end_angle = getval(); if (SIGNED_NUMERIC) chord_angle = getval(); break; case RCIRCLE: if (SIGNED_NUMERIC) radius = getval() * XSCALE; if (SIGNED_NUMERIC) start_angle = getval(); if (SIGNED_NUMERIC) end_angle = getval(); if (SIGNED_NUMERIC) chord_angle = getval(); angle = deg2rad * (90.0 - start_angle); Xc = absX - radius * cos(angle); angle = deg2rad * (90.0 - start_angle); Yc = absY + radius * sin(angle); break; case CCIRCLE: if (SIGNED_NUMERIC) absX = getval() * XSCALE + XOFFSET; if (SIGNED_NUMERIC) absY = getval() * YSCALE + YOFFSET; break; case ACIRCLE: Xc = absX; Yc = absY; if (SIGNED_NUMERIC) radius = getval() * XSCALE; if (SIGNED_NUMERIC) start_angle = getval(); if (SIGNED_NUMERIC) end_angle = getval(); if (SIGNED_NUMERIC) chord_angle = getval(); break; case SCIRCLE: if (SIGNED_NUMERIC) percent = getval(); if (SIGNED_NUMERIC) distance = getval(); if (SIGNED_NUMERIC) length = getval(); fprintf(stderr, "Warning: segment and indication lines not available yet\n"); break; } printf("%g %g %g %g %g %g Ellipse\n", Xc, Yc, radius, radius, start_angle, end_angle); } //E*O*F circle.c// echo x - defcoords.c cat > "defcoords.c" << '//E*O*F defcoords.c//' /* * Define Scaling plotting points. * P1 (P1x, P1y), P2 (P2x, P2y) * * Define User Unit mapping points. * U1 (U1x, U1y), U2 (U2x, U2y) * * Plotter PaperSize can be: * "A3" ISO (297mm by 420mm) * "A4" ISO (210mm by 297mm) * "A" ANSI (8.5" by 11") * "B" ANSI (11" by 17") * * Maximum Plotting Range ( HPGL Plotter units) maxXrange, maxYrange * * "A4" ISO 0-11040 by 0-7721 (274.6mm by 192.1mm) * "A3" ISO 0-16158 by 0-11040 (401.9mm by 274.6mm) * "A" ANSI 0-10365 by 0-7962 (10.15" by 7.8") * "B" ANSI 0-16640 by 0-10365 (16.3" by 10.15") * * Note: will be scaled to fit on A4 LaserWriter paper. * * Mode can be: "HPGL" or "DXY" * * Don McCormick */ #include "defn.h" defcoords() { if (strcmp(Mode, "HPGL") == 0) { if (strcmp(PaperSize, "A3") == 0) /* HP-GL ISO A3 420mm * 297mm */ { maxXrange = 16158; maxYrange = 11040; P2x = U2x = 15370; P2y = U2y = 10602; P1x = U1x = 170; P1y = U1y = 602; } else /* HP-GL ISO A4 297mm * 210mm */ { maxXrange = 11040; maxYrange = 7721; P2x = U2x = 10603; P2y = U2y = 7721; P1x = U1x = 603; P1y = U1y = 521; } } else { if (strcmp(PaperSize, "A3") == 0) /* DXY ISO A3 420mm * 297mm */ { maxXrange = P2x = U2x = 3800; maxYrange = P2y = U2y = 2700; } else /* DXY ISO A4 297mm * 210mm */ { maxXrange = P2x = U2x = 2700; maxYrange = P2y = U2x = 1920; } P1x = P1y = U1x = U1y = 0.0; } } //E*O*F defcoords.c// echo x - defn.h cat > "defn.h" << '//E*O*F defn.h//' /* * * The following definations allow for the efficient * translation of DXY and RD-GL codes to PostScript code * */ #include <stdio.h> #include <math.h> #include <ctype.h> #include <string.h> #define TRUE 1 #define FALSE 0 #define CR '\015' #define LF '\012' #define SPACE '\040' #define SIGNED_NUMERIC (ungetc(( ch = getc(stream)),stream) != EOF ) &&\ (((ch>='0') && (ch<='9')) || (ch=='-') || (ch=='+')\ || (ch==' ') || (ch==',') || (ch == '.')) #define CIRCLE 21 /* DXY Circle */ #define RCIRCLE 22 /* DXY Relative Circle */ #define CCIRCLE 23 /* DXY Centered Circle */ #define ACIRCLE 24 /* DXY Arc plus Circle */ #define SCIRCLE 25 /* DXY Segment Circle */ #define RDGLARCABS 26 /* RD-GL Arc Absolute */ #define RDGLARCREL 27 /* RD-GL Arc Relative */ #define RDGLCIRCLE 28 /* RD-GL Circle */ #define TEXT 31 #define MARK 32 #define LINETYPE 41 #define LINESCALE 42 #define LINE_TYPE_SCALE 43 /* * Maximum PostScript Page Coordinates (in mm) */ #define PAGEHEIGHT 297; #define PAGEWIDTH 210; #define PAGEMARGIN 8; /* Margin around paper */ /* * Files to open if any */ FILE *stream; FILE *fopen(); /* * Plotting Parameters that will contain the necessary PostScript * commands to plot (see dxy2ps.c for the initialisation) and * ps_macros.c for the plotting macros). */ char *MOVE; char *RMOVE; char *DRAW; char *RDRAW; /* * Definition of "ch" used in SIGNED_NUMERIC */ char ch; /* * Define the function getval() which returns a real number. */ float getval(); /* * Scaling parameters used for translation from DXY and RD-GL * coordinate sytem to the PostScript coordinate system which * has been defined in millimeters. (See above) * * The procedure viewport.c allows the program to initialise * plotting scaling points and the user scaling points as well * as allowing the commands "IP" and "SC" to change them. */ float SCALE; /* User selected plot scale */ float XSCALE; /* */ float YSCALE; /* */ float XOFFSET; /* */ float YOFFSET; /* */ float maxXrange, maxYrange; /* Max plotting range in plotter units */ float P1x, P1y; /* Scaling point P1 area coords */ float P2x, P2y; /* Scaling point P2 area coords */ float U1x, U1y; /* User U1 area coords */ float U2x, U2y; /* User U2 area coords */ /* * End of line terminator (RD-GL / HP-GL) */ char EOL; /* * PostScript Coordinate parameters */ float lastXmove; float lastYmove; float absX; float absY; float xval; float yval; float xoffset, yoffset; /* * Extra parameters */ float char_angle; float char_height; float char_width; float char_space; float char_slant; char *font; char symbol; int dcount; /* * Degree radian conversion parameter ie: deg_rad = asin(1) / 90.0; * ( Defined in dxy2ps.c or rdgl2ps.c ) */ float deg2rad; /* * Line / pen size parameter (max 9 sizes) */ float pen_size[9]; /* * Paper size (ie A3 or A4) and Mode (HPGL or DXY) */ char *PaperSize; char *Mode; /* * Flags */ int LANDSCAPE; int DRAW_FLAG; int PLOTABS; int PENDOWN; int SETDOT; /* HP-GL commands only */ int SYMBOL; /* HP-GL commands only */ int DEBUG; int SCALING; /* True when SC command is detected */ //E*O*F defn.h// echo x - dxy2ps.c cat > "dxy2ps.c" << '//E*O*F dxy2ps.c//' #include "defn.h" #define USAGE "Usage: dxy2ps [-amr] [-l line sizes] [-s scale] [-x offset] [-y offset] [file]\n" main(argc, argv) int argc; char *argv[]; { extern int optind; extern char *optarg; int op; int opt; int MANUAL_FEED = 0; /* DEFAULT: No manual feed */ PaperSize = "A3"; Mode = "DXY"; defcoords(); /* Set up plotter coordinates */ plotinit(); /* Get other initialisations */ while ((opt = getopt(argc, argv, "al:ms:x:y:r")) != EOF) { switch (opt) { case 'a': /* DXY ISO A4 297mm * 210mm */ PaperSize = "A4"; defcoords(); break; case 'l': changesizes(optarg); break; case 'm': MANUAL_FEED = 1; break; case 'r': LANDSCAPE = FALSE; break; case 's': SCALE = atof(optarg); if (SCALE < 0.1) SCALE = 0.1; else if (SCALE > 3) SCALE = 3; break; case 'x': xoffset = atof(optarg); break; case 'y': yoffset = atof(optarg); break; default: fprintf(stderr, "%s\n", USAGE); exit(1); } } if (optind == argc) stream = stdin; else if ((stream = fopen(argv[optind], "r")) == NULL) { fprintf(stderr, "ERROR: cannot open \"%s\"\n", argv[optind]); exit(1); } ps_macros(); /* Output PostScript Macros */ viewport(1); /* Scale the viewport for the plot */ printf("/%s %g Font\n", font, char_height); if (MANUAL_FEED) manualfeed(1); while ((op = getc(stream)) != EOF) if ((isalpha(op) > 0) || op == '^') dxycom(op); end_draw(); printf("showpage\n"); if (MANUAL_FEED) manualfeed(0); } //E*O*F dxy2ps.c// echo x - dxycom.c cat > "dxycom.c" << '//E*O*F dxycom.c//' #include "defn.h" dxycom(dxyop) char dxyop; { int intval; int hpglop; switch (dxyop) { case 'H': /* HOME */ case 'h': break; case 'D': /* DRAW */ case 'd': plotps(DRAW); break; case 'M': /* MOVE */ case 'm': plotps(MOVE); break; case 'I': /* RELATIVE DRAW */ case 'i': plotps(RDRAW); break; case 'R': /* RELATIVE MOVE */ case 'r': plotps(RMOVE); break; case 'L': /* LINE TYPE */ case 'l': linetype(LINETYPE); break; case 'B': /* LINE SCALE */ case 'b': linetype(LINESCALE); break; case 'X': /* AXIS */ case 'x': { int p, q, r; p = rint(getval()); q = rint(getval()); r = rint(getval()); fprintf(stderr, "Warning %c not implemented yet\n", dxyop); } break; case 'P': /* PRINT */ case 'p': textps(TEXT); break; case 'S': /* ALPHA SCALE */ case 's': { int n; if (SIGNED_NUMERIC) n = rint(getval()); else n = 3; char_height = (n + 1) * 0.8 * SCALE; char_width = (n + 1) * 0.4 * SCALE; char_space = (n + 1) * 0.2 * SCALE; } printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant); break; case 'Q': /* ALPHA ROTATE */ case 'q': intval = rint(getval()); switch (intval) { case 0: char_angle = 0.0; break; case 1: char_angle = 90.0; break; case 2: char_angle = 180.0; break; case 3: char_angle = 270.0; break; } break; case 'N': /* MARK */ case 'n': textps(MARK); break; case 'J': /* PEN CHANGE */ case 'j': linesize(); break; case 'C': /* CIRCLE */ case 'c': circle(CIRCLE); break; case 'E': /* RELATIVE CIRCLE */ case 'e': circle(RCIRCLE); break; case 'A': /* CIRCLE CENTER */ case 'a': circle(CCIRCLE); break; case 'G': /* ARC + CIRCLE */ case 'g': circle(ACIRCLE); break; case 'K': /* SEGMENT AND INDICATION LINES FOR CIRCLES */ case 'k': circle(SCIRCLE); break; case 'T': /* HATCHING */ case 't': rectangle(); break; case '^': /* CALL HP-GL / RD-GL COMMANDS */ end_draw(); if ((hpglop = getc(stream)) != EOF) hpglcom(hpglop); break; default: fprintf(stderr, "Warning: %c Unknown DXY command\n", dxyop); break; } } //E*O*F dxycom.c// echo x - end_draw.c cat > "end_draw.c" << '//E*O*F end_draw.c//' #include "defn.h" end_draw() { if (DRAW_FLAG) { if (lastXmove == absX && lastYmove == absY) printf("closepath\n"); printf("stroke\n"); DRAW_FLAG = 0; } dcount = 0; } //E*O*F end_draw.c// echo x - getval.c cat > "getval.c" << '//E*O*F getval.c//' /* * Returns a real number */ #include "defn.h" #define ERROR "Two or more decimal places in a number" float getval() { char valbuf[10]; float value; int DECIMAL = 0; int i; /* Null the value buffer "valbuf" */ for (i = 0; i < 10; i++) valbuf[i] = NULL; i = 0; ch = getc(stream); /* * Get Rid of seperators */ while ((ch == ' ') || (ch == ',')) ch = getc(stream); while ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-' || ch == '+') { if (ch == '.') { if (DECIMAL) { fprintf(stderr,"Error: %s\n", ERROR); exit(1); } DECIMAL = 1; } valbuf[i++] = ch; ch = getc(stream); } ungetc(ch, stream); /* Put non numeric char back */ value = atof (valbuf); return (value); } //E*O*F getval.c// echo x - hpgl2ps.c cat > "hpgl2ps.c" << '//E*O*F hpgl2ps.c//' #include "defn.h" #define USAGE "Usage: hpgl2ps [-amr] [-l line sizes] [-s scale] [-x offset] [-y offset] [file]\n" main(argc, argv) int argc ; char *argv[] ; { extern int optind ; extern char *optarg ; int op ; int opt ; int MANUAL_FEED = 0 ; /* DEFAULT: No manual feed */ DEBUG = FALSE ; SCALING = FALSE ; PaperSize = "A3" ; Mode = "HPGL" ; defcoords() ; plotinit() ; /* Get other initialiasations */ while ((opt = getopt(argc, argv, "Dal:ms:x:y:r")) != EOF) { switch (opt) { case 'D': DEBUG = TRUE ; break ; case 'a': /* HP-GL ISO A4 297mm * 210mm */ PaperSize = "A4" ; defcoords() ; break ; case 'l': changesizes(optarg) ; break ; case 'm': MANUAL_FEED = 1 ; break ; case 'r': LANDSCAPE = FALSE ; break ; case 's': SCALE = atof(optarg) ; if (SCALE < 0.1) SCALE = 0.1 ; else if (SCALE > 3) SCALE = 3 ; break ; case 'x': xoffset = atof(optarg) ; break ; case 'y': yoffset = atof(optarg) ; break ; default: fprintf(stderr, "%s\n", USAGE) ; exit(1) ; } } if (optind == argc) stream = stdin ; else if ((stream = fopen(argv[optind], "r")) == NULL) { fprintf(stderr, "ERROR: cannot open \"%s\"\n", argv[optind]) ; exit(1) ; } ps_macros() ; /* Output PostScript Macros */ viewport(1) ; /* Scale the viewport for the plot */ if (MANUAL_FEED) manualfeed(1) ; while ((op = getc(stream)) != EOF) if (isalpha(op) > 0) hpglcom(op) ; end_draw() ; printf("showpage\n") ; if (MANUAL_FEED) manualfeed(0) ; } //E*O*F hpgl2ps.c// echo x - hpglcom.c cat > "hpglcom.c" << '//E*O*F hpglcom.c//' /* * This procedure translates RD-GL (Roland DG Graphic Language) into the * equivalent PostScript language. * * The RD-GL is a superset equivalent to HP-GL * * Don McCormick */ #include "defn.h" /* The folowing defaults should be 0.5% and 1.0% for the respective character * width and height, however this is too small when scaled to Postcript * charcter sizes. */ float DEFWIDTH = 0.0075 ; /* 0.75 % of P2x - P1x for default char width */ float DEFHEIGHT = 0.015 ; /* 1.5 % of P2y - P1y for default char height */ /* * Note the 1.4 multiplier allows for an approx conversion * between the plotter char size and what would be expected * on the Laser printer. */ float PSmult = 1.4 ; hpglcom(op1) char op1 ; { char op2 ; int arg ; PSmult *= SCALE ; switch (op1) { case 'A': case 'a': op2 = getc(stream) ; switch (op2) { case 'A': /* (AA) Arc Absolute */ case 'a': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: Arc absolute not implemented yet\n") ; break ; case 'P': /* (AP) Automatic Pen Lift (not implemented) */ case 'p': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; break ; case 'R': /* (AR) Arc Relative */ case 'r': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: Arc relative not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n\n", op1, op2) ; } break ; case 'C': case 'c': op2 = getc(stream) ; switch (op2) { case 'A': /* (CA) Alternate Character Set (Not Used) */ case 'a': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: Alt character set not implemented yet\n") ; break ; case 'I': /* (CI) Circle */ case 'i': circle(RDGLCIRCLE) ; break ; case 'P': /* (CP) Character Plot */ case 'p': { float xspace, yspace ; xspace = getval() * XSCALE * (char_width + char_space) ; yspace = getval() * YSCALE * (char_width + char_space) ; end_draw() ; printf(" %g mm %g mm %s\n", xspace, yspace, RMOVE) ; } break ; case 'S': /* (CS) Standard Character Set */ case 's': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'D': case 'd': op2 = getc(stream) ; switch (op2) { case 'C': /* (DC) Digitize Clear (Not Used) */ case 'c': break ; case 'F': /* (DF) Default */ case 'f': SETDOT = FALSE ; PENDOWN = FALSE ; SYMBOL = 0 ; EOL = '\003' ; char_angle = 0 ; char_slant = 0 ; char_width = DEFWIDTH * (P2x - P1x) * XSCALE * PSmult ; char_height = DEFHEIGHT * (P2y - P1y) * YSCALE * PSmult ; char_space = char_width * (1/.67 - 1) ; printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant) ; break ; case 'I': /* (DI) Absolute Direction */ case 'i': { float run, rise ; if (SIGNED_NUMERIC) { run = getval() * XSCALE ; rise = getval() * YSCALE ; char_angle = atan2(rise, run) / deg2rad ; } else char_angle = 0 ; } break ; case 'P': /* (DP) Digitize Point (Not Used) */ case 'p': break ; case 'R': /* (DR) Relative Direction */ case 'r': { float run, rise ; if (SIGNED_NUMERIC) { run = getval() * XSCALE ; rise = getval() * YSCALE ; char_angle += atan2(rise, run) / deg2rad ; } else char_angle = 0 ; } break ; case 'T': /* (DT) Define Label Terminator */ case 't': if ((arg = getc(stream)) != EOF) EOL = arg ; /* End of label terminator */ break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'E': case 'e': op2 = getc(stream) ; switch (op2) { case 'A': /* (EA) Edge Rectangle Absolute */ case 'a': break ; case 'R': /* (ER) Edge Rectangle Relative */ case 'r': break ; case 'W': /* (EW) Edge Wedge */ case 'w': break ; default: fprintf(stderr, "Warning: %c%c Unknown RD-GL Command\n", op1, op2) ; } break ; case 'F': case 'f': op2 = getc(stream) ; switch (op2) { case 'T': /* (FT) Fill Type */ case 't': fprintf(stderr, "Warning: Fill type not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'I': case 'i': op2 = getc(stream) ; switch (op2) { case 'M': /* (IM) Input Mask (Not Used) */ case 'm': break ; case 'N': /* (IN) Initialize */ case 'n': defcoords() ; SETDOT = FALSE ; PENDOWN = FALSE ; SYMBOL = 0 ; EOL = '\003' ; char_angle = 0 ; char_slant = 0 ; char_width = DEFWIDTH * (P2x - P1x) * XSCALE * PSmult ; char_height = DEFHEIGHT * (P2y - P1y) * YSCALE * PSmult ; char_space = char_width * (1/0.67 - 1) ; printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant) ; break ; case 'P': /* (IP) Input P1 and P2 */ case 'p': if (SIGNED_NUMERIC) { P1x = getval() ; if (SIGNED_NUMERIC) P1y = getval() ; else { fprintf(stderr,"Error expecting P1y from IP instruction\n") ; defcoords() ; /* Set default coordinates */ break ; } } else { defcoords() ; /* Set default coordinates */ break ; } if (SIGNED_NUMERIC) { P2x= getval() ; if (SIGNED_NUMERIC) P2y = getval() ; else { fprintf(stderr,"Error expecting P2y from IP instruction\n") ; defcoords() ; /* Set default coordinates */ break ; } } else { P2x += P1x ; /* P2 tracks P1 */ P2y += P1y ; /* P2 tracks P1 */ } viewport(0) ; break ; case 'W': /* (IW) Input Window */ case 'w': window() ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'L': case 'l': op2 = getc(stream) ; switch (op2) { case 'B': /* (LB) Label */ case 'b': textps(TEXT) ; break ; case 'T': /* (LT) Line Type */ case 't': linetype(LINE_TYPE_SCALE) ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'O': case 'o': op2 = getc(stream) ; switch (op2) { case 'A': /* (OA) Output Actual Position */ case 'a': break ; case 'C': /* (OC) Output Commanded Position */ case 'c': break ; case 'D': /* (OD) Output Digitise */ case 'd': break ; case 'E': /* (OD) Output Error */ case 'e': break ; case 'P': /* (OP) Output P1 and P2 */ case 'p': break ; case 'S': /* (OS) Output Status */ case 's': break ; case 'W': /* (OW) Output Window */ case 'w': break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'P': case 'p': op2 = getc(stream) ; switch (op2) { case 'A': /* (PA) Plot Absolute */ case 'a': PLOTABS = TRUE ; if (SIGNED_NUMERIC) if (SETDOT || SYMBOL) plotdot(MOVE) ; else if (PENDOWN) plotps(DRAW) ; else plotps(MOVE) ; break ; case 'D': /* (PD) Pen Down */ case 'd': PENDOWN = TRUE ; if (SIGNED_NUMERIC) if (SETDOT || SYMBOL) plotdot(MOVE) ; else if (PLOTABS) plotps(DRAW) ; else plotps(RDRAW) ; break ; case 'R': /* (PR) Plot Relative */ case 'r': PLOTABS = FALSE ; if (SIGNED_NUMERIC) if (SETDOT || SYMBOL) plotdot(RMOVE) ; else if (PENDOWN) plotps(RDRAW) ; else plotps(RMOVE) ; break ; case 'T': /* (PT) Pen Thickness */ case 't': { float linewidth ; linewidth = getval() * SCALE ; /* In mm */ printf("%g mm setlinewidth\n", linewidth) ; } break ; case 'U': /* (PU) Pen Up */ case 'u': PENDOWN = FALSE ; if (SIGNED_NUMERIC) if (SETDOT) plotdot(MOVE) ; else if (PLOTABS) plotps(MOVE) ; else plotps(RMOVE) ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'R': case 'r': op2 = getc(stream) ; switch (op2) { case 'A': /* (RA) Shade Rectange Absolute */ case 'a': break ; case 'R': /* (RR) Shade Rectangle Relative */ case 'r': break ; default: fprintf(stderr, "Warning: %c%c Unknown RD-GL Command\n", op1, op2) ; } break ; case 'S': case 's': op2 = getc(stream) ; switch (op2) { case 'A': /* (SA) Select Alternate Set (Not Used) */ case 'a': break ; case 'C': /* (SC) Scale */ case 'c': if (SIGNED_NUMERIC) U1x = getval() ; else /* Turn Scaling off */ { SCALING = FALSE ; break ; } if (SIGNED_NUMERIC) U2x = getval() ; else { fprintf(stderr,"Error expecting U2x from SC instruction\n") ; SCALING = FALSE ; defcoords() ; /* Set up default conditions */ break ; } if (SIGNED_NUMERIC) U1y = getval() ; else { fprintf(stderr,"Error expecting U1y from SC instruction\n") ; SCALING = FALSE ; defcoords() ; /* Set up default conditions */ break ; } if (SIGNED_NUMERIC) { U2y = getval() ; SCALING = TRUE ; } else { fprintf(stderr,"Error expecting U2y from SC instruction\n") ; SCALING = FALSE ; defcoords() ; /* Set up default conditions */ break ; } viewport(0) ; break ; case 'I': /* (SI) Absolute Character Size */ case 'i': if (SIGNED_NUMERIC) { char_width = getval() * 10 * PSmult ; /* In mm */ char_height = getval() * 10 * PSmult ; /* In mm */ char_width *= 11040 / maxXrange ; /* Scale to A4 paper */ char_height *= 7721 / maxYrange ; /* Scale to A4 paper */ } else { if (((arg = getc(stream)) == ' ;') || isalpha(arg) != 0) { ungetc(arg, stream) ; if (strcmp(PaperSize, "A4") == 0) { char_width = 1.87 * PSmult ; char_height = 2.69 * PSmult ; char_width *= 11040 / maxXrange ; char_height *= 7721 / maxYrange ; } else { char_width = 2.85 * PSmult ; char_height = 3.75 * PSmult ; char_width *= 11040 / maxXrange ; /* Scale to A4 paper */ char_height *= 7721 / maxYrange ; /* Scale to A4 paper */ } } } char_space = char_width * (1/.67 - 1) ; printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant) ; break ; case 'L': /* (SL) Character Slant */ case 'l': if (SIGNED_NUMERIC) char_slant = char_height * getval() ; else char_slant = 0 ; char_space = char_width * (1/.67 - 1) ; printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant) ; break ; case 'M': /* (SM) Symbol Mode */ case 'm': if ((arg = getc(stream)) != EOF && arg != ' ;' && isgraph(arg) > 0) { symbol = arg ; SYMBOL = 1 ; } else SYMBOL = 0 ; break ; case 'P': /* (SP) Pen Select */ case 'p': linesize() ; break ; case 'R': /* (SR) Relative Character Size */ case 'r': { float pwidth, pheight ; if (SIGNED_NUMERIC) { pwidth = getval() ; /* Percent */ pheight = getval() ; /* Percent */ } else { pwidth = DEFWIDTH * 100 ; pheight = DEFHEIGHT * 100 ; } char_width = (P2x - P1x) * XSCALE * pwidth / 100.0 * PSmult ; char_height = (P2y - P1y) * YSCALE * pheight / 100.0 * PSmult ; char_space = char_width * (1/.67 - 1) ; char_width *= 11040 / maxXrange ; /* Scale to A4 paper */ char_height *= 7721 / maxYrange ; /* Scale to A4 paper */ } printf("/%s %g %g %g DefFont\n", font, char_width, char_height, char_slant) ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'T': case 't': op2 = getc(stream) ; switch (op2) { case 'L': /* (TL) Tick Length */ case 'l': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: Tick length not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'U': case 'u': op2 = getc(stream) ; switch (op2) { case 'C': /* (UC) User Defined Character */ case 'c': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: User defined character not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'V': case 'v': op2 = getc(stream) ; switch (op2) { case 'S': /* (VS) Velocity Select */ case 's': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'W': case 'w': op2 = getc(stream) ; switch (op2) { case 'G': /* (WS) Shade Wedge */ case 'g': break ; default: fprintf(stderr, "Warning: %c%c Unknown RD-GL Command\n", op1, op2) ; } break ; case 'X': case 'x': op2 = getc(stream) ; switch (op2) { case 'T': /* (XT) X Tick */ case 't': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: X tick not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; case 'Y': case 'y': op2 = getc(stream) ; switch (op2) { case 'T': /* (YT) Y Tick */ case 't': while (((arg = getc(stream)) != EOF) && isalpha(arg) == 0) ; ungetc(arg, stream) ; fprintf(stderr, "Warning: Y tick not implemented yet\n") ; break ; default: fprintf(stderr, "Warning: %c%c Unknown HP-GL Command\n", op1, op2) ; } break ; default: fprintf(stderr, "Warning: %c Unknown HP-GL First Op Command\n", op1) ; break ; } } //E*O*F hpglcom.c// echo x - linesize.c cat > "linesize.c" << '//E*O*F linesize.c//' #include "defn.h" linesize() { int ipen = 0; float linewidth; if (SIGNED_NUMERIC) ipen = getval() - 1; if (ipen < 0 || ipen > 8) ipen = 0; linewidth = pen_size[ipen] * SCALE; /* In mm */ printf("%g mm setlinewidth\n", linewidth); } //E*O*F linesize.c// echo x - linetype.c cat > "linetype.c" << '//E*O*F linetype.c//' /* * Sets the line type and the scaling of the line pattern * * Don McCormick CSIRO Division of Applied Physics National Measurements * Laboritory Bradfield Road Lindfield 2018 N.S.W. * * NOTE: default length for a line pattern is approx 6.5 mm on A4 size paper. */ #include "defn.h" float linescale; int linestyle; linetype(line) int line; { float down1, down2; float up1, up2; float diagonal; end_draw(); if (line == LINE_TYPE_SCALE) /* HP-GL only */ { if (SIGNED_NUMERIC) { if ((linestyle = rint(getval())) > 6) linestyle = 6; else if (linestyle < -6) linestyle = -6; } else { SETDOT = FALSE; printf("[] 0 setdash\n"); return; } diagonal = pow((P2x - P1x),2.0) + pow((P2y - P1y),2.0); diagonal = pow(diagonal,0.5); if (SIGNED_NUMERIC) linescale = getval() * 0.01 * diagonal * XSCALE * 0.2; else linescale = 0.015 * diagonal * XSCALE * 0.2; } else if (line == LINESCALE) /* DXY commands only */ { if (SIGNED_NUMERIC) linescale = getval() / 80 * SCALE; else return; } else if (line == LINETYPE) /* DXY commands only */ { if (SIGNED_NUMERIC) { if ((linestyle = rint(getval())) > 5) linestyle = 5; else if (linestyle < -5) linestyle = -5; } else return; } else { fprintf(stderr, "Error: Unknown line flag in linetype.c\n"); exit(1); } /* * select a line style/type and scale/pitch */ switch (linestyle) { case 6: down1 = 2.0; up1 = up2 = 1.5; down2 = 1.5; break; case 5: down1 = 3.0; up1 = up2 = 1.0; down2 = 1.5; break; case 4: down1 = 4.0; up1 = up2 = 0.75; down2 = 1.0; break; case 3: down1 = 5.0; up1 = up2 = 1.0; down2 = 0.5; break; case 2: down1 = 5.5; up1 = 1.0; up2 = down2 = 0.0; break; case 1: down1 = 5.0; up1 = 1.5; up2 = down2 = 0.0; break; case -1: down1 = 1.5; up1 = 3.5; down2 = 1.5; up2 = 0.0; break; case -2: down1 = 2.0; up1 = 2.5; down2 = 2.0; up2 = 0.0; break; case -3: down1 = 2.5; up1 = up2 = 1.75; down2 = 0.5; break; case -4: down1 = 2.5; up1 = up2 = 1.5; down2 = 1.5; break; case -5: down1 = down2 = 2.0; up1 = up2 = 1.25; break; case -6: down1 = down2 = 1.75; up1 = up2 = 1.5; break; } if (linestyle == 0) { SETDOT = TRUE; /* For HP-GL only */ printf("[] 0 setdash\n"); /* For DXY commands */ } else { SETDOT = FALSE; /* For HP-GL only */ if (linescale <= 0) linescale = SCALE; down1 *= linescale; up2 *= linescale; up1 *= linescale; down2 *= linescale; printf("[%g mm %g mm %g mm %g mm] 0 setdash\n", down1, up1, down2, up2); } } //E*O*F linetype.c// echo x - manualfeed.c cat > "manualfeed.c" << '//E*O*F manualfeed.c//' /* * A procedure to allow the user to use the manual feed on * the LaserWriter. * The default wait before timeout is 3 minutes however this * is easily changed. * * argument: 1. Enable manual feed. * 0. Disable manual feed. * * Don McCormick */ manualfeed(arg) int arg; { if (arg == 1) { printf("statusdict /manualfeed true put\n"); printf("statusdict /manualfeedtimeout 180 put\n"); /* 3 minute wait */ } else printf("statusdict /manualfeed false put\n"); printf("usertime 5000 add\n"); printf("{dup usertime lt {pop exit} if} loop\n"); } //E*O*F manualfeed.c// echo x - plotdot.c cat > "plotdot.c" << '//E*O*F plotdot.c//' /* * Plot a dot or symbol on the paper * * This doesnot quite emulate what HPGL is suposed to do. * * A symbol should be placed at the end of each vector, however this will * only occur in the penup or non draw mode and not for pendown or the draw * mode. The main problem is due to my limited knowledge of the PostScript * language, it is not quite a simple matter of combining lineplot and * text drawing commands. * * Don McCormick */ #include "defn.h" plotdot(type) char *type; { end_draw(); while (SIGNED_NUMERIC) { xval = getval(); yval = getval(); if (type == RMOVE) { absX += xval * XSCALE; absY += yval * YSCALE; } else if (type == MOVE) { absX = xval * XSCALE + XOFFSET; absY = yval * YSCALE + YOFFSET; } else { fprintf(stderr, "Error: expecting move command not %s\n", type); exit(1); } if (SYMBOL) printf("%g %g 5 %g (%c) Text\n", absX, absY, char_angle, symbol); else if (SETDOT) { printf("newpath\n"); printf(" %g %g %s %g %g %s\n", absX, absY, MOVE, absX, absY, DRAW); printf("stroke\n"); } } } //E*O*F plotdot.c// echo x - plotinit.c cat > "plotinit.c" << '//E*O*F plotinit.c//' #include "defn.h" plotinit() { /* * Initialisation of PostScript plot macros */ MOVE = "M"; RMOVE = "R"; DRAW = "D"; RDRAW = "I"; LANDSCAPE = TRUE; /* Display plot in Landscape mode */ PLOTABS = TRUE; /* Absolute plot coordinates */ PENDOWN = FALSE; /* Penup */ SETDOT = FALSE; /* HP-GL only for linetype = 0 */ SCALE = 1; /* Default Scale, ie 1:1 */ SYMBOL = 0; /* HP-GL only */ /* * Default line/pen sizes (in mm) */ pen_size[0] = 0.1; pen_size[1] = 0.2; pen_size[2] = 0.3; pen_size[3] = 0.4; pen_size[4] = 0.5; pen_size[5] = 0.7; pen_size[6] = 1.0; pen_size[7] = 1.25; pen_size[8] = 1.5; font = "Courier"; /* Default font (mono spaced) */ EOL = '\003'; /* End of line terminator default */ /* * Default character specifications for plotter A4 paper */ char_angle = 0; /* Degrees */ char_slant = 0; /* tan(angle) */ char_height = 2.7; /* mm */ char_space = 0.8; /* mm */ char_width = 1.9; /* mm */ /* * Page offsets set to zero */ xoffset = yoffset = 0; /* * Define degree to radian parameter */ deg2rad = asin(1.0) / 90.0; } //E*O*F plotinit.c// echo x - plotps.c cat > "plotps.c" << '//E*O*F plotps.c//' #include "defn.h" #define MAXDRAWPOINTS 1000 plotps(type) char *type; { if (type == MOVE || type == RMOVE) { while (SIGNED_NUMERIC) { if (type == MOVE) { end_draw(); absX = lastXmove = getval() * XSCALE + XOFFSET; absY = lastYmove = getval() * YSCALE + YOFFSET; } else if (type == RMOVE) { end_draw(); lastXmove = absX += getval() * XSCALE; lastYmove = absY += getval() * YSCALE; } } } else /* Must be a DRAW or RDRAW */ { while (SIGNED_NUMERIC) { if (dcount++ >= MAXDRAWPOINTS) { end_draw(); printf("newpath\n"); printf(" %g %g %s\n", absX, absY, MOVE); DRAW_FLAG = 1; fprintf(stderr, "Warning exceeded %d draw points\n", MAXDRAWPOINTS); } xval = getval(); /* Get HPGL X value */ yval = getval(); /* Get HPGL Y value */ if (!DRAW_FLAG) { printf("newpath\n"); printf(" %g %g %s\n", absX, absY, MOVE); DRAW_FLAG = 1; } if (type == RDRAW) { float rxval, ryval; rxval = xval * XSCALE; ryval = yval * YSCALE; absX += rxval; absY += ryval; printf(" %g %g %s\n", rxval, ryval, RDRAW); } else if (type == DRAW) { absX = xval * XSCALE + XOFFSET; absY = yval * YSCALE + YOFFSET; printf(" %g %g %s\n", absX, absY, DRAW); } else { fprintf(stderr, "Error: expecting draw command not %s\n", type); exit(1); } } } } //E*O*F plotps.c// echo x - ps_macros.c cat > "ps_macros.c" << '//E*O*F ps_macros.c//' ps_macros() { printf("%%! PS-Adobe-1.0: For Apple LaserWriter\n"); printf("%% default font is 10 pt. Helvetica\n"); printf("/basefont {/Helvetica findfont 10 scalefont setfont} def\n"); printf("/mm {72.27 mul 25.4 div} def\n"); /* Specify millimeters */ printf("/M\n"); /* Move macro */ printf("{\n"); printf(" /Ymove exch def\n"); printf(" /Xmove exch def\n"); printf(" Xmove mm Ymove mm moveto\n"); printf("} def\n"); printf("/R\n"); /* Relative move macro */ printf("{\n"); printf(" /Yrmove exch def\n"); printf(" /Xrmove exch def\n"); printf(" Xrmove mm Yrmove mm rmoveto\n"); printf("} def\n"); printf("/D\n"); /* Draw macro */ printf("{\n"); printf(" /Ydraw exch def\n"); printf(" /Xdraw exch def\n"); printf(" Xdraw mm Ydraw mm lineto\n"); printf("} def\n"); printf("/I\n"); /* Relative draw macro */ printf("{\n"); printf(" /Yrdraw exch def\n"); printf(" /Xrdraw exch def\n"); printf(" Xrdraw mm Yrdraw mm rlineto\n"); printf("} def\n"); /* * Procedure to change font and size of font * ----> font size Font <---- */ printf("/Font\n"); printf("{\n"); printf(" /Height exch def\n"); printf(" /FontName exch def\n"); printf(" FontName findfont Height mm scalefont setfont\n"); printf("} def\n"); /* * Procedure to change font, width, slant and height * ----> font width height slant DefFont <---- * * Note: slant = height * tan( slant_angle ) */ printf("/DefFont\n"); printf("{\n"); printf(" /Slant exch def\n"); printf(" /Height exch def\n"); printf(" /Width exch def\n"); printf(" /FontName exch def\n"); printf(" FontName findfont [ Width mm 0 Slant mm Height mm 0 0] makefont setfont\n"); printf("} def\n"); /* * General Text Layout Procedure * ----> x y pos_num angle (text) Text <---- */ printf("/Text\n"); printf("{\n"); printf(" /String exch def\n"); printf(" /Angle exch def\n"); printf(" /Position exch def\n"); printf(" /Ymove exch def\n"); printf(" /Xmove exch def\n"); printf(" Position 1 lt {/hpf 0 def /lpf 0 def} if\n"); printf(" Position 1 eq {/hpf 0 def /lpf 0 def} if\n"); printf(" Position 2 eq {/hpf 0 def /lpf 0.5 def} if\n"); printf(" Position 3 eq {/hpf 0 def /lpf 1 def} if\n"); printf(" Position 4 eq {/hpf 0.5 def /lpf 0 def} if\n"); printf(" Position 5 eq {/hpf 0.5 def /lpf 0.5 def} if\n"); printf(" Position 6 eq {/hpf 0.5 def /lpf 1 def} if\n"); printf(" Position 7 eq {/hpf 1 def /lpf 0 def} if\n"); printf(" Position 8 eq {/hpf 1 def /lpf 0.5 def} if\n"); printf(" Position 9 eq {/hpf 1 def /lpf 1 def} if\n"); printf(" Position 9 gt {/hpf 1 def /lpf 1 def} if\n"); printf(" /StrLen String stringwidth pop lpf mul def\n"); printf(" /StrHt Height mm hpf mul def\n"); printf(" /Xdiff StrHt Angle sin mul StrLen Angle cos mul sub def\n"); printf(" /Ydiff StrHt Angle cos mul StrLen Angle sin mul add def\n"); printf(" Xmove mm Xdiff add Ymove mm Ydiff sub moveto\n"); printf(" gsave\n"); printf(" Angle rotate\n"); printf(" String show\n"); printf(" grestore\n"); printf(" /PosterOnly 0 def\n"); printf("} def\n"); /* * Ellipse and Circle procedure. * ----> xcen ycen xrad yrad start_angle end_angle Ellipse <---- */ printf("/EllipseDict 8 dict def\n"); printf("EllipseDict /mtrx matrix put\n"); printf("/Ellipse \n"); printf("{ EllipseDict begin\n"); printf(" /endangle exch def\n"); printf(" /startangle exch def\n"); printf(" /yradius exch def\n"); printf(" /xradius exch def\n"); printf(" /ycenter exch def\n"); printf(" /xcenter exch def\n"); printf(" /savematrix mtrx currentmatrix def\n"); printf(" xcenter mm ycenter mm translate\n"); printf(" xradius mm yradius mm div 1 scale\n"); printf(" newpath\n"); printf(" 0 0 xradius mm startangle endangle arc\n"); printf(" stroke\n"); printf(" savematrix setmatrix\n"); printf(" end\n"); printf("} def\n"); printf("basefont\n"); /* Set the default font */ printf("1 setlinecap\n"); /* Use round caps */ printf("1 setlinejoin\n"); /* Use round joins */ printf("3 setmiterlimit\n"); /* Bevel small angle miters */ } //E*O*F ps_macros.c// echo x - rectangle.c cat > "rectangle.c" << '//E*O*F rectangle.c//' #include "defn.h" rectangle() { int hatch; float width, height; float hatch_spacing; float hatch_angle; if (SIGNED_NUMERIC) hatch = getval(); if (SIGNED_NUMERIC) width = getval() * XSCALE; if (SIGNED_NUMERIC) height = getval() * YSCALE; if (SIGNED_NUMERIC) hatch_spacing = getval() * XSCALE; if (SIGNED_NUMERIC) hatch_angle = getval(); end_draw(); printf("%g %g M\n", xval, yval); printf("%g 0 I\n", width); printf("0 %g I\n", height); printf("-%g 0 I\n", width); printf("closepath stroke\n"); if (hatch != 2) fprintf(stderr, "Warning: Cross hatching not implemented yet\n"); } //E*O*F rectangle.c// echo x - textps.c cat > "textps.c" << '//E*O*F textps.c//' #include "defn.h" #define MAXBUFSIZE 100 textps(type) int type; { int chr; char buffer[MAXBUFSIZE]; int intval; int i; end_draw(); if (type == TEXT) { for (i = 0 ; i < MAXBUFSIZE; i++) /* Clear buffer */ buffer[i] = NULL; i = 0; /* Reset buffer counter */ /* * For a mono spaced font (Emulates the plotter) */ while (((chr = getc(stream)) != EOF) && chr != CR && chr != LF && chr != EOL) { buffer[i++] = chr; if (chr == '(' || chr == ')') printf("%g %g 1 %g (\\%c) Text\n", absX, absY, char_angle, chr); else printf("%g %g 1 %g (%c) Text\n", absX, absY, char_angle, chr); absX += (char_width) * cos(char_angle * deg2rad); absY += (char_width) * sin(char_angle * deg2rad); } } else /* Must be a MARK */ { int symb_num; char *symbol; if (SIGNED_NUMERIC) symb_num = getval(); else { fprintf(stderr, "Error: expecting a symbol number not %c (%d)", symb_num, symb_num); exit(1); } intval = (int)(getval() + 0.5); switch (intval) { case 0: strcpy(symbol, "*"); break; case 1: strcpy(symbol, "+"); break; case 2: strcpy(symbol, "#"); break; case 3: strcpy(symbol, "@"); break; case 4: strcpy(symbol, "%"); break; case 5: strcpy(symbol, "|"); break; case 6: strcpy(symbol, "="); break; case 7: strcpy(symbol, "&"); break; case 9: strcpy(symbol, "O"); break; case 10: strcpy(symbol, "0"); break; case 11: strcpy(symbol, "Y"); break; case 12: strcpy(symbol, "X"); break; case 13: strcpy(symbol, "Z"); break; case 14: strcpy(symbol, "S"); break; case 15: strcpy(symbol, "Q"); break; default: fprintf(stderr, "Warning symbol number is %d\n", symb_num); strcpy(symbol, "*"); break; } printf("%g %g 5 %g (%s) Text\n", absX, absY, char_angle, symbol); } } //E*O*F textps.c// echo x - viewport.c cat > "viewport.c" << '//E*O*F viewport.c//' /* * This procedure sets up the variables for the translation of plotter * coordinates to PostScript coordinates. * * Don McCormick */ #include "defn.h" static float psxmax, psymax ; /* Sizes scaled to the viewport */ static float DefXScale, DefYScale ; /* Default scales */ viewport(status) int status ; { float margin ; /* Non printing area around paper */ float pagewidth, pageheight ; /* Maximum paper sizes */ pagewidth = PAGEWIDTH ; pageheight = PAGEHEIGHT ; margin = PAGEMARGIN ; if (status == 1) /* Set up initial conditions */ { if (LANDSCAPE) /* Create a positive Y axis */ { printf("90 rotate\n") ; printf("0 -%g mm translate\n", pagewidth) ; psymax = pagewidth - margin * 2 ; psxmax = psymax * (maxXrange) / (maxYrange) ; XOFFSET = xoffset + (pageheight - psxmax) / 2.0 ; YOFFSET = yoffset + (margin) ; } else { psxmax = pagewidth - margin * 2 ; psymax = psxmax * (maxYrange) / (maxXrange) ; XOFFSET = yoffset + (margin) ; YOFFSET = yoffset + (pageheight - psymax) / 2.0 ; } printf("/%s %g Font\n", font, char_height) ; DefXScale = psxmax / (maxXrange) * SCALE ; DefYScale = psymax / (maxYrange) * SCALE ; } if (SCALING) { XSCALE = DefXScale * (P2x - P1x) / (U2x - U1x) ; YSCALE = DefYScale * (P2y - P1y) / (U2y - U1y) ; } else { XSCALE = DefXScale ; YSCALE = DefYScale ; } if (DEBUG) { fprintf(stderr,"Xscale= %g, Yscale = %g\n", XSCALE, YSCALE) ; fprintf(stderr,"Xoffset= %g, Yoffset = %g\n", XOFFSET, YOFFSET) ; } } //E*O*F viewport.c// echo x - window.c cat > "window.c" << '//E*O*F window.c//' /* * The input window provides a means of restricting the plotting outside * the specific rectangular area defined. * Used with the "IW" command (HPGL). * * NOTE There is no checking if the HPGL code is correct. */ #include "defn.h" window() { float XloLeft, YloLeft; float XupRight, YupRight; if (SIGNED_NUMERIC) XloLeft = getval() * XSCALE + XOFFSET; else { printf("newpath\n"); printf(" 0 0 moveto\n"); printf(" 300 mm 0 lineto\n"); printf(" 300 mm 210 mm lineto\n"); printf(" 0 210 mm lineto\n"); printf("closepath clip\n"); return; } if (SIGNED_NUMERIC) YloLeft = getval() * YSCALE + YOFFSET; if (SIGNED_NUMERIC) XupRight = getval() * XSCALE + XOFFSET; if (SIGNED_NUMERIC) YupRight = getval() * YSCALE + YOFFSET; printf("newpath\n"); printf(" %g %g %s\n", XloLeft, YloLeft, MOVE); printf(" %g %g %s\n", XupRight, YloLeft, DRAW); printf(" %g %g %s\n", XupRight, YupRight, DRAW); printf(" %g %g %s\n", XloLeft, YupRight, DRAW); printf("closepath clip\n"); } //E*O*F window.c// echo x - test1.dxy cat > "test1.dxy" << '//E*O*F test1.dxy//' J1 M 1000, 1000 N 2 I 100, 0, -200,0, 100, 0, 0,100,0, -200 P Hi There C 1000, 1000, 500, 0, 250 M 2000,1000 I 100, 0, -200,0, 100, 0, 0,100,0, -200 L 2 J5 C 2000, 1000, 500, 250, 0 J3 M 0 0 I 3800,0,0,2700,-3800,0,0,-2700 M 500,2000 ^SL1;S50PDXY-880 ^SL;S3 //E*O*F test1.dxy// echo x - test1.hpgl cat > "test1.hpgl" << '//E*O*F test1.hpgl//' IN;LT; PU1000,1000;PD2000,1000,2000,2000,1000,2000,1000,1000; PR-100,0,0,-100,100,0,0,100; PU;PA0,0;PD10800,0,10800,7680,0,7680,0,0;PU; LT6,2;PA;PU4000,1400;PD;PR4000,0; LT5,2;PA;PU4000,1300;PD;PR4000,0; LT4,2;PA;PU4000,1200;PD;PR4000,0; LT3,2;PA;PU4000,1100;PD;PR4000,0; LT2,2;PA;PU4000,1000;PD;PR4000,0; LT1,2;PA;PU4000,900;PD;PR4000,0; LT0;PA;PU4000,800;PD;PR4000,0; LT-1,2;PA;PU4000,700;PD;PR4000,0; LT-2,2;PA;PU4000,600;PD;PR4000,0; LT-3,2;PA;PU4000,500;PD;PR4000,0; LT-4,2;PA;PU4000,400;PD;PR4000,0; LT-5,2;PA;PU4000,300;PD;PR4000,0; LT-6,2;PA;PU4000,200;PD;PR4000,0; PU;PA8000,3000; SI.15,.3; DI;LB -- 0deg -- DI1,1;LB -- 45deg -- DI0,1;LB -- 90deg -- DI-1,1;LB -- 135deg -- DI-1,0;LB -- 180deg -- DI-1,-1;LB -- 225deg -- DI0,-1;LB -- 270deg -- DI1,-1;LB -- 315deg -- PA500,4000; SI; DI;SL1;LB SLANT of 45deg PA500,3600; SL-1;LB SLANT of -45deg PA500,6000; SL;SR;LB Size is relative PA1000,5500; SI;LB DEFAULT sizes PA500,5000; SI.4,.6;LBLARGE size (w=4mm, h=6mm) LT; PA 9000,1000;CI500,20;CI400;CI300;CI200,1;CI100;CI50; IN;SM+;PA9000,1000,10000,1000;SM%;PR0,500,0,-1000; SM; //E*O*F test1.hpgl// exit 0