V10/cmd/picasso/ps_include.c
/* Copyright (c) 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* @(#)picasso:ps_include.c 1.0 */
/*
*
* Picture inclusion code for PostScript printers, taken from Rich Drechsler
*
*/
#include "picasso.h"
#include "ps_include.h"
/* in SVR4, the C-preprocessor will not accept the tricky definitions of lq
and rq. However, we should be able to do it using the following
define var(x) fprintf(fout, "/%s %g def\n", #x, x)
*/
#define lq(x) "x
#define rq(x) x"
#define quote(x) rq(lq(x))
#define var(x) fprintf(fout, "/%s %g def\n", quote(x), x)
#define has(word) (strncmp(buf, word, strlen(word)) == 0)
#define grab(n) ((Section *)(nglobal \
? realloc((char *)global, n*sizeof(Section)) \
: calloc(n, sizeof(Section))))
char buf[512];
typedef struct {long start, end;} Section;
puteqn(x, y, type, neqn)
double x, y;
int type, neqn;
{
extern FILE *eqnfp, *outfp;
extern float eqn_move;
double ax, ay;
ax = 0;
ay = 0;
if (type & LJUST|RJUST|ABOVE|BELOW) {
/* modify ax,ay if text_bounds can get the bounding box */
}
if (eqnfp != NULL)
ps_include(eqnfp, outfp, neqn, x, y + eqn_move, 0., 0., ax, ay/*,0.*/);
}
ps_include(fin, fout, page_no, cx, cy, sx, sy, ax, ay /*, rot */)
FILE *fin, *fout; /* input and output files */
int page_no; /* physical page number from *fin */
double cx, cy; /* center of the picture and */
double sx, sy; /* its size - in current coordinates */
double ax, ay; /* left-right, up-down adjustment */
/* double rot; /* rotation - in clockwise degrees */
{
int foundpage = 0; /* found the page when non zero */
int foundpbox = 0; /* found the page bounding box */
int nglobal = 0; /* number of global defs so far */
int maxglobal = 0; /* and the number we've got room for */
Section prolog, setup, /* major divisions in document */
page, trailer;
Section *global; /* offsets for all global definitions */
double llx, lly; /* lower left and upper right corners */
double urx, ury; /* (default -- printer pt -- coords) */
int i = 0; /* found page number */
/*
*
* Reads a PostScript file (*fin), and uses structuring comments to locate the
* prologue, trailer, global definitions, and the requested page. After the
* file is scanned, the special ps_include PostScript definitions are copied to
* *fout, followed by the prologue, global definitions, the requested page, and
* the trailer. Before returning the initial environment (saved in PS_head) is
* restored.
*
* By default we assume the picture is 8.5 by 11 inches, but the BoundingBox
* comment, if found, takes precedence.
*
*/
llx = lly = 0; /* default BoundingBox - 8.5x11 inches */
urx = 72 * 8.5;
ury = 72 * 11.0;
/* section boundaries and bounding box */
prolog.start = prolog.end = 0;
setup.start = setup.end = 0;
page.start = page.end = 0;
trailer.start = 0;
fseek(fin, 0L, 0);
while ( fgets(buf, sizeof(buf), fin) != NULL ) {
if (!has("%%"))
continue;
else if (has("%%PageBoundingBox: (atend)")
|| has("%%BoundingBox: (atend)"))
continue;
else if (has("%%Page: ")) {
if (!foundpage)
page.start = ftell(fin);
sscanf(buf, "%*s %*s %d", &i);
if (i == page_no)
foundpage = 1;
else if (foundpage && page.end <= page.start)
page.end = ftell(fin);
} else if (has("%%EndPage: ")) {
sscanf(buf, "%*s %*s %d", &i);
if (i == page_no) {
foundpage = 1;
page.end = ftell(fin);
}
if (!foundpage)
page.start = ftell(fin);
} else if (has("%%PageBoundingBox: ")) {
if (i > page_no & !foundpbox) {
foundpbox = 1;
llx = lly = urx = ury = 0;
} else if (i == page_no) {
sscanf(buf, "%*s %lf %lf %lf %lf",
&llx, &lly, &urx, &ury);
foundpbox = 1;
}
} else if (has("%%BoundingBox: ")) {
if (!foundpbox)
sscanf(buf,"%*s %lf %lf %lf %lf",
&llx, &lly, &urx, &ury);
} else if (has("%%EndProlog"))
prolog.end = setup.start = page.start = ftell(fin);
else if (has("%%BeginSetup")
|| has("%%BeginDocumentSetup")) {
if (!setup.start) setup.start = ftell(fin);
} else if (has("%%EndSetup")
|| has("%%EndDocumentSetup"))
setup.end = page.start = ftell(fin);
else if (has("%%Trailer"))
trailer.start = ftell(fin);
else if (has("%%BeginGlobal"))
if (page.end <= page.start) {
if (nglobal >= maxglobal) {
maxglobal += 20;
global = grab(maxglobal);
}
global[nglobal].start = ftell(fin);
}
else if (has("%%EndGlobal"))
if (page.end <= page.start)
global[nglobal++].end = ftell(fin);
}
if (urx == llx && ury == lly)
return;
fseek(fin, 0L, 2);
if (trailer.start == 0)
trailer.start = ftell(fin);
trailer.end = ftell(fin);
if (page.end <= page.start)
page.end = trailer.start;
ps_print(fout, PS_head);
if (sx == 0)
sx = (urx-llx)/pgscale;
if (sy == 0)
sy = (ury-lly)/pgscale;
track_bounds(cx-sx/2, cy-sy/2, cx+sy/2, cy+sy/2);
fprintf(fout, "/llx %g def\n", llx);
fprintf(fout, "/lly %g def\n", lly);
fprintf(fout, "/urx %g def\n", urx);
fprintf(fout, "/ury %g def\n", ury);
fprintf(fout, "/cx %g def\n", cx);
fprintf(fout, "/cy %g def\n", cy);
fprintf(fout, "/sx %g def\n", sx);
fprintf(fout, "/sy %g def\n", sy);
fprintf(fout, "/ax %g def\n", ax);
fprintf(fout, "/ay %g def\n", ay);
ps_print(fout, PS_setup);
ps_copy(fin, fout, &prolog);
fprintf(fout,"/useclippath false def\n");
ps_copy(fin, fout, &setup);
for(i = 0; i < nglobal; i++)
ps_copy(fin, fout, &global[i]);
ps_copy(fin, fout, &page);
ps_copy(fin, fout, &trailer);
ps_print(fout, PS_tail);
if(nglobal)
free(global);
}
pic_include(fin, fout, page_no, o)
FILE *fin, *fout; /* input and output files */
int page_no; /* physical page number from *fin */
obj *o; /* has bounds and transformation */
{
int foundpage = 0; /* found the page when non zero */
int foundpbox = 0; /* found the page bounding box */
int nglobal = 0; /* number of global defs so far */
int maxglobal = 0; /* and the number we've got room for */
Section prolog, setup, /* major divisions in document */
page, trailer;
Section *global; /* offsets for all global definitions */
double cx, cy;
double sx, sy;
double llx, lly; /* lower left and upper right corners */
double urx, ury; /* (default -- printer pt -- coords) */
int i = 0; /* found page number */
/*
*
* Reads a PostScript file (*fin), and uses structuring comments to locate the
* prologue, trailer, global definitions, and the requested page. After the
* file is scanned, the special ps_include PostScript definitions are copied to
* *fout, followed by the prologue, global definitions, the requested page, and
* the trailer. Before returning the initial environment (saved in PS_head) is
* restored.
*
* By default we assume the picture is 8.5 by 11 inches, but the BoundingBox
* comment, if found, takes precedence.
*
*/
llx = lly = 0; /* default BoundingBox - 8.5x11 inches */
urx = 72 * 8.5;
ury = 72 * 11.0;
cx = o->o_x;
cy = o->o_y;
sx = o->o_wid;
sy = o->o_ht;
/* section boundaries and bounding box */
prolog.start = prolog.end = 0;
setup.start = setup.end = 0;
page.start = page.end = 0;
trailer.start = 0;
fseek(fin, 0L, 0);
while ( fgets(buf, sizeof(buf), fin) != NULL ) {
if (!has("%%"))
continue;
else if (has("%%PageBoundingBox: (atend)")
|| has("%%BoundingBox: (atend)"))
continue;
else if (has("%%Page: ")) {
if (!foundpage)
page.start = ftell(fin);
sscanf(buf, "%*s %*s %d", &i);
if (i == page_no)
foundpage = 1;
else if (foundpage && page.end <= page.start)
page.end = ftell(fin);
} else if (has("%%EndPage: ")) {
sscanf(buf, "%*s %*s %d", &i);
if (i == page_no) {
foundpage = 1;
page.end = ftell(fin);
}
if (!foundpage)
page.start = ftell(fin);
} else if (has("%%PageBoundingBox: ")) {
if (i > page_no & !foundpbox) {
foundpbox = 1;
llx = lly = urx = ury = 0;
} else if (i == page_no) {
sscanf(buf, "%*s %lf %lf %lf %lf",
&llx, &lly, &urx, &ury);
foundpbox = 1;
}
} else if (has("%%BoundingBox: ")) {
if (!foundpbox)
sscanf(buf,"%*s %lf %lf %lf %lf",
&llx, &lly, &urx, &ury);
} else if (has("%%EndProlog"))
prolog.end = setup.start = page.start = ftell(fin);
else if (has("%%BeginSetup")
|| has("%%BeginDocumentSetup")) {
if (!setup.start) setup.start = ftell(fin);
} else if (has("%%EndSetup")
|| has("%%EndDocumentSetup"))
setup.end = page.start = ftell(fin);
else if (has("%%Trailer"))
trailer.start = ftell(fin);
else if (has("%%BeginGlobal"))
if (page.end <= page.start) {
if (nglobal >= maxglobal) {
maxglobal += 20;
global = grab(maxglobal);
}
global[nglobal].start = ftell(fin);
}
else if (has("%%EndGlobal"))
if (page.end <= page.start)
global[nglobal++].end = ftell(fin);
}
if (urx == llx && ury == lly)
return;
fseek(fin, 0L, 2);
if (trailer.start == 0)
trailer.start = ftell(fin);
trailer.end = ftell(fin);
if (page.end <= page.start)
page.end = trailer.start;
ps_print(fout, PS_head);
if (sx == 0)
sx = (urx-llx)/pgscale;
if (sy == 0)
sy = (ury-lly)/pgscale;
track_bounds(cx-sx/2, cy-sy/2, cx+sy/2, cy+sy/2);
fprintf(fout, "/llx %g def\n", llx);
fprintf(fout, "/lly %g def\n", lly);
fprintf(fout, "/urx %g def\n", urx);
fprintf(fout, "/ury %g def\n", ury);
fprintf(fout, "/cx %g def\n", cx);
fprintf(fout, "/cy %g def\n", cy);
fprintf(fout, "/sx %g def\n", sx);
fprintf(fout, "/sy %g def\n", sy);
fprintf(fout, "/B [ %g %g %g %g 0 0 ] def\n", o->o_mxx, o->o_myx,
o->o_mxy, o->o_myy);
ps_print(fout, Pic_setup);
ps_copy(fin, fout, &prolog);
fprintf(fout,"/useclippath false def\n");
ps_copy(fin, fout, &setup);
for(i = 0; i < nglobal; i++)
ps_copy(fin, fout, &global[i]);
ps_copy(fin, fout, &page);
ps_copy(fin, fout, &trailer);
ps_print(fout, PS_tail);
if(nglobal)
free(global);
}
static
ps_print(fout, s)
FILE *fout;
char **s;
{
while (*s)
fprintf(fout, "%s\n", *s++);
}
static
ps_copy(fin, fout, s)
FILE *fin, *fout;
Section *s;
{
if (s->end <= s->start)
return;
fseek(fin, s->start, 0);
while (ftell(fin) < s->end && fgets(buf, sizeof(buf), fin) != NULL)
if (buf[0] != '%')
fprintf(fout, "%s", buf);
}