staden-lg/src/staden/postscript.c

210 lines
5.1 KiB
C

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "FtoC.h" /* IMPORT: Fstr2Cstr */
#include "postscript.h"
#include "fort.h"
static FILE *psfp = NULL; /* pointer to ps output file */
static int pspages; /* num of pages in current file */
static int psupdated = 0; /* any updates since last 'showpage'? */
/* --- externable functions --- */
/* returns 1 for open, 0 for closed */
int_f openp_x(char *FILE_p,
int_f *x1_p, int_f *y1_p, int_f *x2_p, int_f *y2_p,
int_f *width_p, int_f *lndscp_p, int_fl FILE_l) {
char fname[256];
struct stat buf;
Fstr2Cstr(FILE_p, FILE_l, fname, 256);
/*
* If given null filename then do nothing - gives us a chance to
* close the file without opening another!
*/
if (fname[0] == '\0') {
/*fprintf(stdout, "Closing PostScript output file\n");*/
closep_x();
return 0;
}
/*
* Otherwise if we've already a file open then close it too before
* opening a new one.
*/
if (psfp != NULL) {
closep_x();
psfp = NULL;
}
/* now open our file */
if (stat(fname, &buf) != -1) {
fprintf(stdout, "*** Error - file already exists\n");
return 0;
}
if ((psfp = fopen(fname,"w")) == NULL) {
fprintf(stdout,
"*** Error - could not open postscript output file '%s'\n",
fname);
return 0;
} /*else
fprintf(stdout, "Sucessfully opened PostScript file '%s'.\n", fname);
*/
/* and write out the standard PostScript header */
fputs("%!PS-Adobe-1.0\n\
%%DocumentFonts: Times-Roman\n\
%%For: Staden software package\n\
%%Title: graphics_output.ps\n\
%%Creator: Staden software package\n\
%%CreationDate: (of header) 10/08/92\n\
%%Pages: (atend)\n\
%%EndComments\n\
\n\
% User tunable variables\n\
", psfp);
fprintf(psfp, "/landscape %d def %% portrait vs landscape mode\n\
/linewidth %2d def %% thickness of lines\n\
\n\
%% (x1,y1) must be bottom left and (x2,y2) must be top right\n\
/x1 %4d def %% size and\n\
/y1 %4d def %% location of the\n\
/x2 %4d def %% box on graphics\n\
/y2 %4d def %% window to draw\n\
", *lndscp_p, *width_p, *x1_p, *y1_p, *x2_p, *y2_p);
fputs("\n\
% location on postscript page\n\
/inch {72 mul} def\n\
/leftborder {.5 inch} def % left/right margin in inches\n\
/botborder {.5 inch} def % top/bottom margin in inches\n\
\n\
% size of an A4 page\n\
/pagew {11.75 inch} def\n\
/pageh { 8.25 inch} def\n\
\n\
botborder leftborder\n\
landscape 1 eq {\n\
90 rotate\n\
/width {pagew botborder 2 mul sub} def\n\
/height {pageh leftborder 2 mul sub} def\n\
0 -612 translate\n\
exch\n\
} {\n\
/width {pageh botborder 2 mul sub} def\n\
/height {pagew leftborder 2 mul sub} def\n\
} ifelse translate\n\
/conv {width 10000 div mul} def\n\
\n\
x2 x1 sub conv width div\n\
y2 y1 sub conv height div\n\
dup 3 2 roll dup 4 1 roll exch\n\
\n\
% centre drawing\n\
dup 3 2 roll dup 4 1 roll exch\n\
gt {width mul height exch sub 2 div 0 exch 3 -1 roll pop}\n\
{pop width mul 2 div 0} ifelse pop pop 0 0 translate\n\
\n\
% scale drawing to large as possible, but still maintaining the aspect ratio\n\
dup 3 2 roll dup 4 1 roll exch\n\
gt {pop 1 exch div}\n\
{1 exch div exch pop} ifelse dup scale\n\
\n\
x1 conv neg y1 conv neg translate\n\
\n\
% abbreiviations to shrink the drawing data\n\
/s {stroke} def\n\
/l {2 copy lineto s moveto} def\n\
/m {moveto} def\n\
/r {currentlinewidth 0 rlineto s} def\n\
/p {showpage} def\n\
/t {show} def\n\
/n {newpath} def\n\
/i {\n\
/Times-Roman findfont 290 scalefont setfont\n\
2 setlinecap % square caps => equiv to square pixels\n\
linewidth setlinewidth\n\
1 conv dup scale\n\
} def\n\
\n\
%%EndProlog\n\
", psfp);
pspages = 0;
psupdated = 0;
return 1;
}
void closep_x() {
if (psfp != NULL) {
/* do showpage etc if we've written any more since last showpage */
if (psupdated)
clearp_x();
fputs("%%Trailer\n", psfp);
fprintf(psfp, "%%%%Pages: %d\n", pspages);
fclose(psfp);
}
}
void clearp_x() {
if (psfp != NULL) {
fputs("s\n", psfp);
fputs("p\n", psfp);
psupdated = 0;
}
}
/*
* starts a new page - called when we do the first piece of PostScript
* after clearp_x().
*/
static void psnext() {
if (psupdated == 0) {
psupdated = 1;
pspages++;
fprintf(psfp, "%%%%Page: %d %d\n", pspages, pspages);
fputs("i n\n", psfp);
}
}
void movep_x(int_f *IX_p, int_f *IY_p) {
if (psfp) {
psnext();
fprintf(psfp, "%d %d m\n", (int)*IX_p, (int)*IY_p);
}
}
void drawp_x(int_f *IX_p, int_f *IY_p) {
if (psfp) {
psnext();
fprintf(psfp, "%d %d l\n", (int)*IX_p, (int)*IY_p);
}
}
void pointp_x(int_f *IX_p, int_f *IY_p) {
if (psfp) {
psnext();
fprintf(psfp, "%d %d m\nr\n", (int)*IX_p, (int)*IY_p);
}
}
void writep_x(int_f *IX_p, int_f *IY_p, char *TEXT_p, int_f *NCHAR_p,
int_fl TEXT_l) {
int_f len = *NCHAR_p, i;
char c;
if (psfp) {
psnext();
fprintf(psfp, "%d %d m\n(", (int)*IX_p, (int)*IY_p);
/* need to check for '\', '(' and ')' */
for (i=0; i<len; i++) {
if (isprint(c = TEXT_p[i])) {
if (c == '(' || c == ')' || c == '\\')
fputc('\\', psfp);
fputc(c, psfp);
}
}
fputs(") t\n", psfp);
}
}