/*
* this code taken basically verbatim (changes and deletions only where
* necessary) from the xmgr package by Paul J. Turner. It looks like he
* got if from somewhere else too, so credit to those folks as well.
*/
/*
*
* driver for postscript printer
*
* courtesy of:
*
* Jim Hudgens
* hudgens@ray.met.fsu.edu
*
* Further modifications by,
* Ole Holm Nielsen
* ohnielse@ltf.dth.dk
*
*/
#include <stdio.h>
#include <ctype.h>
#include "version.h"
#define MAX_BUF_LEN 128
static void putps();
static int isoneof();
static void stripspecial ();
/* postscript page at scale = 0.25 */
/*
* the following defines are tuned for our HP LaserJet IV
* and may need adjustment for other printers
*/
#define PSXMIN 100
#define PSXMAX 2350
#define PSYMIN 100
#define PSYMAX 3045
#define DXPS 2250
#define DYPS 2945
#define CHARS 1.8
#define MINCOLOR 0
#define PSMAXPAT 30
#define MAXLINEWIDTH 9
static int psxmin = PSXMIN;
static int psxmax = PSXMAX;
static int psymin = PSYMIN;
static int psymax = PSYMAX;
static int psdx = DXPS;
static int psdy = DYPS;
static int pscolor = -1;
static int pslinewidth = -1;
static int psdmode;
static int pspattern = 0;
static int psfont = 0;
static double pscharsize = 1.7;
static int pslinestyle;
static char *fname;
/* reduced from 1000 to 800 PJT */
#define MAXPATHLEN 800 /* MAXPATHLEN points in a path between
* strokes */
static int pathlength = 0;
static FILE *psout;
static int prevx = 99999,
prevy = 99999,
prevmode;
static void stroke()
{
if (pathlength) {
fprintf(psout, "stroke\n");
prevx = 99999;
prevy = 99999;
pathlength = 0;
}
}
int pssetmode(mode, ps_fp)
int mode;
FILE *ps_fp;
{
if (mode % 2) {
psout = ps_fp;
if (psout == NULL)
return 0;
}
switch (mode) {
case 3: /* EPS portrait */
pscharsize = CHARS;
psxmin = PSXMIN;
psxmax = PSXMAX;
psymin = PSYMIN;
psymax = PSYMAX;
psdx = DXPS;
psdy = DYPS;
break;
case 1: /* EPS landscape */
pscharsize = CHARS;
psxmin = PSYMIN;
psxmax = PSYMAX;
psymin = PSXMIN;
psymax = PSXMAX;
psdx = DYPS;
psdy = DXPS;
break;
case 2:
case 4:
stroke();
fprintf(psout, "showpage\n");
fprintf(psout, "%%%%Trailer\n");
fclose(psout);
break;
}
return mode;
}
void drawps(x2, y2, mode)
int x2, y2, mode;
{
int xtmp, ytmp;
if (x2 < 0 || y2 < 0) { /* Eliminate garbage on output */
return;
}
xtmp = x2;
ytmp = y2;
if (mode) {
if (prevmode && xtmp == prevx && ytmp == prevy) {
return; /* previous mode was draw and points are the
* same */
}
fprintf(psout, "%d %d l\n", xtmp, ytmp); /* lineto */
} else {
/* Avoid excessive moveto */
if (xtmp == prevx && ytmp == prevy) {
return;
}
fprintf(psout, "%d %d m\n", xtmp, ytmp); /* moveto */
}
pathlength++;
prevx = xtmp;
prevy = ytmp;
/*
* Printers have some maximum number of points in a path. See PostScript
* Language Reference Manual (Red book), p. 261. Hence the fix that
* follows
*/
prevmode = mode;
if (pathlength > MAXPATHLEN) {
stroke();
prevmode = 0;
fprintf(psout, "%d %d m\n", xtmp, ytmp); /* moveto */
}
}
int xconvps(x)
double x;
{
return ((int) (psxmin + x));
}
int yconvps(y)
double y;
{
return ((int) (psymin + y));
}
int pssetcolor(c)
int c;
{
static int first_time = 1;
static unsigned char red[16],
green[16],
blue[16];
if (first_time) {
first_time = 0;
/* white */ red[0] = 255; green[0] = 255; blue[0] = 255;
/* black */ red[1] = 0; green[1] = 0; blue[1] = 0;
/* red */ red[2] = 255; green[2] = 0; blue[2] = 0;
/* green */ red[3] = 0; green[3] = 255; blue[3] = 0;
/* blue */ red[4] = 0; green[4] = 0; blue[4] = 255;
/* yellow */ red[5] = 255; green[5] = 255; blue[5] = 0;
/* brown */ red[6] = 188; green[6] = 143; blue[6] = 143;
/* gray */ red[7] = 220; green[7] = 220; blue[7] = 220;
/* violet */ red[8] = 148; green[8] = 0; blue[8] = 211;
/* cyan */ red[9] = 0; green[9] = 255; blue[9] = 255;
/* magenta*/ red[10] = 255; green[10] = 0; blue[10] = 211;
/* orange */ red[11] = 255; green[11] = 138; blue[11] = 0;
/* b violet*/ red[12] = 114; green[12] = 33; blue[12] = 188;
/* maroon */ red[13] = 103; green[13] = 7; blue[13] = 72;
/* turq */ red[14] = 72; green[14] = 209; blue[14] = 204;
/* f green*/ red[15] = 85; green[15] = 192; blue[15] = 52;
}
stroke();
if (c != pscolor) {
if (c >= 0) {
fprintf(psout, "%f %f %f setrgbcolor\n", red[c] / 255.0,
green[c] / 255.0,
blue[c] / 255.0);
pscolor = 1;
}
}
pscolor = c;
return c;
}
int pssetlinewidth(c)
int c;
{
stroke();
if (c != pslinewidth) {
c = c % (MAXLINEWIDTH + 1);
if (c == 1)
fprintf(psout, "1 setlinewidth\n");
else
fprintf(psout, "%d setlinewidth\n", (int) (3.5 * c + 0.51));
}
pslinewidth = c;
return c;
}
int pssetlinestyle(style)
int style;
{
stroke();
if (style == pslinestyle) {
return (pslinestyle);
}
switch (style) {
case 1: /* solid */
fprintf(psout, "[] 0 setdash\n");
break;
case 2: /* dotted */
fprintf(psout, "[4 8] 0 setdash\n");
break;
case 3: /* long dash */
fprintf(psout, "[20 20] 0 setdash\n");
break;
case 4: /* short dash */
fprintf(psout, "[40 20] 0 setdash\n");
break;
case 5: /* dot-dashed */
fprintf(psout, "[40 20 12 20] 0 setdash\n");
break;
}
return (pslinestyle = style);
}
char pscurfont[MAX_BUF_LEN] = "/Times-Roman findfont \n60 scalefont\n setfont";
int psfontsize = 60;
void pssetfont(n)
int n;
{
if (psfont == n) {
return;
}
switch (n) {
case 0:
sprintf(pscurfont, "/Times-Roman findfont \n%d scalefont\n setfont", psfontsize);
break;
case 1:
sprintf(pscurfont, "/Times-Bold findfont \n%d scalefont\n setfont", psfontsize);
break;
case 2:
sprintf(pscurfont, "/Times-Italic findfont \n%d scalefont\n setfont", psfontsize);
break;
case 3:
sprintf(pscurfont, "/Times-BoldItalic findfont \n%d scalefont\n setfont", psfontsize);
break;
case 4:
sprintf(pscurfont, "/Helvetica findfont \n%d scalefont\n setfont", psfontsize);
break;
case 5:
sprintf(pscurfont, "/Helvetica-Bold findfont \n%d scalefont\n setfont", psfontsize);
break;
case 6:
sprintf(pscurfont, "/Helvetica-Oblique findfont \n%d scalefont\n setfont", psfontsize);
break;
case 7:
sprintf(pscurfont, "/Helvetica-BoldOblique findfont \n%d scalefont\n setfont", psfontsize);
break;
case 8:
sprintf(pscurfont, "/Courier findfont \n%d scalefont\n setfont", psfontsize);
break;
case 9:
sprintf(pscurfont, "/Courier-Bold findfont \n%d scalefont\n setfont", psfontsize);
break;
case 10:
sprintf(pscurfont, "/Courier-Oblique findfont \n%d scalefont\n setfont", psfontsize);
break;
case 11:
sprintf(pscurfont, "/Courier-BoldOblique findfont \n%d scalefont\n setfont", psfontsize);
break;
case 12:
sprintf(pscurfont, "/Symbol findfont \n%d scalefont\n setfont", psfontsize);
break;
case 13:
sprintf(pscurfont, "/Symbol findfont \n%d scalefont\n setfont", psfontsize);
break;
case 14:
sprintf(pscurfont, "/Symbol findfont \n%d scalefont\n setfont", psfontsize);
break;
}
fprintf(psout, "%s\n", pscurfont);
psfont = n;
}
void pssetfontsize(size)
double size;
{
static double prev_size;
int sf = psfont;
if (size == prev_size)
return;
psfontsize = (int) (size * 4); /* to account for the 0.25 scaling */
psfont = -1;
pssetfont(sf);
}
static void escape_paren(s)
char *s;
{
char t[256];
int i, cnt = 0;
for (i = 0; i < strlen(s); i++) {
if (s[i] == '(' || s[i] == ')') {
t[cnt++] = '\\';
}
t[cnt++] = s[i];
}
t[cnt] = 0;
strcpy(s, t);
}
void dispstrps(x, y, rot, s, just, fudge)
int x, y, rot, just, fudge;
char *s;
{
char tmpstr[256];
stroke();
if (psfontsize == 0 || s == NULL || strlen(s) == 0) {
return;
}
fprintf(psout, "%d %d m\n", x, y);
fprintf(psout, "gsave\n");
fprintf(psout, "%d %d translate\n", x, y);
fprintf(psout, "%d rotate\n", rot);
if (fudge) {
fprintf(psout, "%d 0 m\n", psfontsize / 4);
} else {
fprintf(psout, "0 0 m\n");
}
switch (just) {
case 0:
break;
case 1:
stripspecial(s, tmpstr);
escape_paren(tmpstr);
fprintf(psout, "(%s) RJ\n", tmpstr);
break;
case 2:
stripspecial(s, tmpstr);
escape_paren(tmpstr);
fprintf(psout, "(%s) CS\n", tmpstr);
break;
}
putps(s);
fprintf(psout, "grestore\n");
fprintf(psout, "newpath\n");
}
static void putps(s)
char *s;
{
int i, slen = strlen(s), curcnt = 0;
int underline = 0, offset = 0;
double saves = psfontsize / 60.0, scale = psfontsize / 60.0;
char curstr[256];
int upperset = 0;
int symfont = 0;
if (psfont == 9) {
symfont = 1;
upperset = 0x80;
} else {
symfont = 0;
upperset = 0;
}
for (i = 0; i < slen; i++) {
if (s[i] == '-' && isdigit(s[i + 1])) {
/* s[i] = 0261; */
} else if (s[i] == '\\' && isdigit(s[i + 1])) {
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
if (symfont) {
symfont = 0;
upperset = 0;
}
pssetfont(s[i + 1] - '0');
if (psfont == 9) {
symfont = 1;
upperset = 0x80;
}
i++;
continue;
} else if (s[i] == '(' || s[i] == ')') {
curstr[curcnt++] = '\\';
} else if (s[i] == '\\' && isoneof(s[i + 1], "cCbxsSNuU+-")) {
switch (s[i + 1]) {
case 'x':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
if (symfont == 0) {
symfont = 1;
upperset = 0x80;
}
pssetfont(10);
i++;
break;
case 's':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
pssetfontsize(scale = 0.6 * saves);
offset -= psfontsize / 2;
fprintf(psout, "0 %d rmoveto\n", -(psfontsize / 2));
i++;
break;
case 'S':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
pssetfontsize(scale = 0.6 * saves);
offset += psfontsize;
fprintf(psout, "0 %d rmoveto\n", psfontsize);
i++;
break;
case 'N':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
scale = saves;
pssetfontsize(scale);
fprintf(psout, "0 %d rmoveto\n", -offset);
offset = 0;
/*
fprintf(psout, "0 %d rmoveto\n", psfontsize);
*/
i++;
break;
case 'b':
i++;
break;
case 'c':
upperset = 0x80;
i++;
break;
case 'C':
upperset = 0;
i++;
break;
case 'u':
underline = 1;
i++;
break;
case 'U':
underline = 0;
i++;
break;
case '-':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
scale -= 0.2;
if (scale < 0.2) {
scale = 0.2;
}
pssetfontsize(scale);
i++;
break;
case '+':
curstr[curcnt] = 0;
if (curcnt >= 1) {
fprintf(psout, "(%s) show\n", curstr);
}
curcnt = 0;
scale += 0.2;
pssetfontsize(scale);
i++;
break;
}
continue;
} else if (s[i] == '\\' && s[i + 1] == '\\') {
curstr[curcnt++] = '\\';
curstr[curcnt++] = s[i];
i++;
continue;
}
curstr[curcnt++] = s[i] + upperset;
}
curstr[curcnt] = 0;
fprintf(psout, "(%s) show\n", curstr);
}
int pssetpat(k)
int k;
{
stroke();
if (k > PSMAXPAT) {
k = PSMAXPAT;
} else if (k < 0) {
k = 0;
fprintf(psout, "0.0 setgray\n");
}
return (pspattern = k);
}
void psfill(n, px, py)
int n;
int px[], py[];
{
int i;
stroke();
drawps(px[0], py[0], 0);
for (i = 1; i < n; i++) {
drawps(px[i], py[i], 1);
}
fprintf(psout, "closepath\n");
fprintf(psout, "%f setgray\n", 1.0 - pspattern / (double) PSMAXPAT);
fprintf(psout, "gsave eofill grestore\n");
stroke();
fprintf(psout, "0 setgray\n");
}
void psfillcolor(n, px, py)
int n;
int px[], py[];
{
int i;
stroke();
drawps(px[0], py[0], 0);
for (i = 1; i < n; i++) {
drawps(px[i], py[i], 1);
}
fprintf(psout, "closepath\n");
fprintf(psout, "gsave eofill grestore\n");
stroke();
}
void psdrawarc(x, y, r, start, end)
int x, y, r, start, end;
{
stroke();
fprintf(psout, "%d %d %d %d %d arc\n", x, y, r, start, end);
fprintf(psout, "stroke\n");
}
void psfillarc(x, y, r, start, end)
int x, y, r, start, end;
{
stroke();
fprintf(psout, "%d %d %d %d %d arc\n", x, y, r, start, end);
fprintf(psout, "gsave fill grestore\n");
fprintf(psout, "stroke\n");
}
void psdrawellipse(x, y, xm, ym, start, end)
int x, y, xm, ym, start, end;
{
double scalex = (double) xm / (double) ym, scaley = 1.0;
stroke();
fprintf(psout, "gsave\n");
fprintf(psout, "%f %f scale\n", scalex, scaley);
fprintf(psout, "%d %d %d %d %d arc\n", (int) (x * 1.0 / scalex),
y, ym, start, end);
fprintf(psout, "stroke\n");
fprintf(psout, "grestore\n");
}
void psfillellipse(x, y, xm, ym, start, end)
int x, y, xm, ym, start, end;
{
double scalex = (double) xm / (double) ym, scaley = 1.0;
stroke();
fprintf(psout, "gsave\n");
fprintf(psout, "%f %f scale\n", scalex, scaley);
/*
fprintf(psout, "%d %d %d %d %d arc\n", x, y, ym, start, end);
*/
fprintf(psout, "%d %d %d %d %d arc\n", (int) (x * 1.0 / scalex),
y, ym, start, end);
fprintf(psout, "gsave fill grestore\n");
fprintf(psout, "stroke\n");
fprintf(psout, "grestore\n");
}
int psgetextents (x, y)
int *x, *y;
{
*x = psdx;
*y = psdy;
return 0;
}
void psleavegraphics(fp)
FILE *fp;
{
pssetmode(psdmode + 1, fp);
}
/* postscript initialization routine */
int psinitgraphics(dmode, ps_fp)
int dmode;
FILE *ps_fp;
{
psdmode = dmode;
if (!pssetmode(psdmode, ps_fp)) {
return -1;
}
fprintf(psout, "%%!PostScript\n");
fprintf(psout, "%%%%Creator: Velvet %s\n", VERSION);
fprintf(psout, "%%%%Title: %s\n", fname);
fprintf(psout, "%%%%EndComments\n");
fprintf(psout, "/m {moveto} bind def\n");
fprintf(psout, "/l {lineto} bind def\n");
fprintf(psout, "/RJ {\n");
fprintf(psout, " stringwidth neg exch neg exch\n");
fprintf(psout, " rmoveto\n");
fprintf(psout, "} bind def\n");
fprintf(psout, "/CS {\n");
fprintf(psout, " stringwidth\n");
fprintf(psout, " 2 div neg exch 2 div neg exch\n");
fprintf(psout, " rmoveto\n");
fprintf(psout, "} bind def\n");
fprintf(psout, "0.25 0.25 scale\n");
fprintf(psout, "1 setlinecap\n");
/*
* rotate if in landscape mode
*/
if (dmode == 1) {
fprintf(psout, "%d 0 translate\n", 2 * psymin + psdy);
fprintf(psout, "90 rotate\n");
}
pssetcolor(1);
pssetlinewidth(1);
pssetlinestyle(0);
psfont = -1;
pssetfont(2);
return 0;
}
static int isoneof(c, s)
int c;
char *s;
{
while (*s) {
if (c == *s) {
return 1;
} else {
s++;
}
}
return 0;
}
static void stripspecial(s, cs)
char *s, *cs;
{
int i, slen = strlen(s), curcnt = 0;
for (i = 0; i < slen; i++) {
if (s[i] == '\\' && isdigit(s[i + 1])) {
i++;
} else if (s[i] == '\\' && isoneof(s[i + 1], "cCbxsSNuU+-")) {
i++;
} else if (s[i] == '\\' && s[i + 1] == '\\') {
i++;
} else {
cs[curcnt++] = s[i];
}
}
cs[curcnt] = 0;
}
syntax highlighted by Code2HTML, v. 0.9.1