7 static char *ps_head
[] = {
8 "%ps_include: begin\n",
10 "/ed {exch def} def\n",
15 "currentdict /findfont known systemdict /findfont known and {\n",
16 " /findfont systemdict /findfont get def\n",
18 "36 dict dup /PS-include-dict-dw ed begin\n",
20 "count array astore /o-stack ed\n",
21 "%ps_include: variables begin\n",
25 static char *ps_setup
[] = {
26 "%ps_include: variables end\n",
27 "{llx lly urx ury} /bbox ed\n",
28 "{newpath 2 index exch 2 index exch dup 6 index exch\n",
29 " moveto 3 {lineto} repeat closepath} /boxpath ed\n",
30 "{dup mul exch dup mul add sqrt} /len ed\n",
31 "{2 copy gt {exch} if pop} /min ed\n",
32 "{2 copy lt {exch} if pop} /max ed\n",
33 "{transform round exch round exch A itransform} /nice ed\n",
35 "n defaultmatrix n currentmatrix n invertmatrix n concatmatrix /A ed\n",
36 "urx llx sub 0 A dtransform len /Sx ed\n",
37 "0 ury lly sub A dtransform len /Sy ed\n",
38 "llx urx add 2 div lly ury add 2 div A transform /Cy ed /Cx ed\n",
39 "rot dup sin abs /S ed cos abs /C ed\n",
40 "Sx S mul Sy C mul add /H ed\n",
41 "Sx C mul Sy S mul add /W ed\n",
42 "sy H div /Scaley ed\n",
43 "sx W div /Scalex ed\n",
44 "s 0 eq {Scalex Scaley min dup /Scalex ed /Scaley ed} if\n",
45 "sx Scalex W mul sub 0 max ax 0.5 sub mul cx add /cx ed\n",
46 "sy Scaley H mul sub 0 max ay 0.5 sub mul cy add /cy ed\n",
47 "urx llx sub 0 A dtransform exch atan rot exch sub /rot ed\n",
48 "n currentmatrix initgraphics setmatrix\n",
50 "Scalex Scaley scale\n",
52 "Cx neg Cy neg translate\n",
54 "bbox boxpath clip newpath\n",
55 "w 0 ne {gsave bbox boxpath 1 setgray fill grestore} if\n",
58 "%ps_include: inclusion begin\n",
62 static char *ps_tail
[] = {
63 "%ps_include: inclusion end\n",
65 "PS-include-dict-dw begin\n",
66 "o 0 ne {gsave A defaultmatrix /A ed llx lly nice urx ury nice\n",
67 " initgraphics 0.1 setlinewidth boxpath stroke grestore} if\n",
68 "clear o-stack aload pop\n",
69 "context end restore\n",
74 extern int curpostfontid
;
75 extern int curfontsize
;
77 typedef struct {long start
, end
;} Section
;
78 static char buf
[1 << 12];
80 static void copy(struct ustr
*ustr
, FILE *fout
, Section
*s
)
82 if (s
->end
<= s
->start
)
84 ustr_seek(ustr
, s
->start
);
86 * We have to be careful here, because % can legitimately appear
87 * in Ascii85 encodings, and must not be elided.
88 * The goal here is to make any DSC comments impotent without
89 * actually changing the behavior of the Postscript.
90 * Since stripping ``comments'' breaks Ascii85, we can instead just
91 * indent comments a space, which turns DSC comments into non-DSC comments
92 * and has no effect on binary encodings, which are whitespace-blind.
94 while (ustr_pos(ustr
) < s
->end
&& ustr_line(ustr
, buf
, sizeof(buf
)) > 0) {
103 * Reads a PostScript file (*fin), and uses structuring comments to locate the
104 * prologue, trailer, global definitions, and the requested page. After the whole
105 * file is scanned, the special ps_include PostScript definitions are copied to
106 * *fout, followed by the prologue, global definitions, the requested page, and
107 * the trailer. Before returning the initial environment (saved in ps_head) is
110 * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox
111 * comment, if found, takes precedence.
113 * *fin, *fout; input and output files
114 * page_no; physical page number from *fin
115 * whiteout; erase picture area
116 * outline; draw a box around it and
117 * scaleboth; scale both dimensions - if not zero
118 * cx, cy; center of the picture and
119 * sx, sy; its size - in current coordinates
120 * ax, ay; left-right, up-down adjustment
121 * rot; rotation - in clockwise degrees
123 void ps_include(struct ustr
*ustr
, FILE *fout
, int page_no
, int whiteout
,
124 int outline
, int scaleboth
, double cx
, double cy
, double sx
, double sy
,
125 double ax
, double ay
, double rot
)
128 int foundpage
= 0; /* found the page when non zero */
129 int foundpbox
= 0; /* found the page bounding box */
130 int nglobal
= 0; /* number of global defs so far */
131 int maxglobal
= 0; /* and the number we've got room for */
132 Section prolog
, page
, trailer
; /* prologue, page, and trailer offsets */
133 Section
*global
; /* offsets for all global definitions */
134 double llx
, lly
; /* lower left and */
135 double urx
, ury
; /* upper right corners - default coords */
136 double w
= whiteout
!= 0; /* mostly for the var() macro */
137 double o
= outline
!= 0;
138 double s
= scaleboth
!= 0;
141 #define has(word) (strncmp(buf, word, strlen(word)) == 0)
142 #define grab(n) ((Section *)(nglobal \
143 ? realloc((char *)global, n*sizeof(Section)) \
144 : calloc(n, sizeof(Section))))
146 llx
= lly
= 0; /* default BoundingBox - 8.5x11 inches */
150 /* section boundaries and bounding box */
152 prolog
.start
= prolog
.end
= 0;
153 page
.start
= page
.end
= 0;
158 while (ustr_line(ustr
, buf
, sizeof(buf
)) > 0) {
161 else if (has("%%Page: ")) {
163 page
.start
= ustr_pos(ustr
);
164 sscanf(buf
, "%*s %*s %d", &i
);
167 else if (foundpage
&& page
.end
<= page
.start
)
168 page
.end
= ustr_pos(ustr
);
169 } else if (has("%%EndPage: ")) {
170 sscanf(buf
, "%*s %*s %d", &i
);
173 page
.end
= ustr_pos(ustr
);
176 page
.start
= ustr_pos(ustr
);
177 } else if (has("%%PageBoundingBox: ")) {
180 sscanf(buf
, "%*s %lf %lf %lf %lf",
181 &llx
, &lly
, &urx
, &ury
);
183 } else if (has("%%BoundingBox: ")) {
185 sscanf(buf
,"%*s %lf %lf %lf %lf",
186 &llx
, &lly
, &urx
, &ury
);
187 } else if (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup"))
188 prolog
.end
= page
.start
= ustr_pos(ustr
);
189 else if (has("%%Trailer"))
190 trailer
.start
= ustr_pos(ustr
);
191 else if (has("%%BeginGlobal")) {
192 if (page
.end
<= page
.start
) {
193 if (nglobal
>= maxglobal
) {
195 global
= grab(maxglobal
);
197 global
[nglobal
].start
= ustr_pos(ustr
);
199 } else if (has("%%EndGlobal"))
200 if (page
.end
<= page
.start
)
201 global
[nglobal
++].end
= ustr_pos(ustr
);
203 if (trailer
.start
== 0)
204 trailer
.start
= ustr_pos(ustr
);
205 trailer
.end
= ustr_pos(ustr
);
207 if (page
.end
<= page
.start
)
208 page
.end
= trailer
.start
;
210 /* all output here */
211 for (strp
= ps_head
; *strp
!= NULL
; strp
++)
214 fprintf(fout
, "/llx %g def\n", llx
);
215 fprintf(fout
, "/lly %g def\n", lly
);
216 fprintf(fout
, "/urx %g def\n", urx
);
217 fprintf(fout
, "/ury %g def\n", ury
);
218 fprintf(fout
, "/w %g def\n", w
);
219 fprintf(fout
, "/o %g def\n", o
);
220 fprintf(fout
, "/s %g def\n", s
);
221 fprintf(fout
, "/cx %g def\n", cx
);
222 fprintf(fout
, "/cy %g def\n", cy
);
223 fprintf(fout
, "/sx %g def\n", sx
);
224 fprintf(fout
, "/sy %g def\n", sy
);
225 fprintf(fout
, "/ax %g def\n", ax
);
226 fprintf(fout
, "/ay %g def\n", ay
);
227 fprintf(fout
, "/rot %g def\n", rot
);
229 for (strp
= ps_setup
; *strp
!= NULL
; strp
++)
232 copy(ustr
, fout
, &prolog
);
233 for(i
= 0; i
< nglobal
; i
++)
234 copy(ustr
, fout
, &global
[i
]);
235 copy(ustr
, fout
, &page
);
236 copy(ustr
, fout
, &trailer
);
237 for (strp
= ps_tail
; *strp
!= NULL
; strp
++)
243 /* force the program to reestablish its state */