1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 /*
33 *
34 * Picture inclusion code for PostScript printers.
35 *
36 */
37
38
39 #include <stdio.h>
40 #include "ps_include.h"
41
42
43 #if defined(__STDC__)
44 #define var(x) fprintf(fout, "/%s %g def\n", #x, x)
45 #else
46 #define lq(x) "x
47 #define rq(x) x"
48 #define quote(x) rq(lq(x))
49 #define var(x) fprintf(fout, "/%s %g def\n", quote(x), x)
50 #endif
51
52 #define has(word) (strncmp(buf, word, strlen(word)) == 0)
53 #define grab(n) ((Section *)(nglobal \
54 ? realloc((char *)global, n*sizeof(Section)) \
55 : calloc(n, sizeof(Section))))
56
57
58 char buf[512];
59 typedef struct {long start, end;} Section;
60
61 extern char *calloc(), *realloc();
62
63 static void print(FILE *, char **);
64 static void copy(FILE *, FILE *, Section *);
65
66 /*****************************************************************************/
67
68
69 void
ps_include(FILE * fin,FILE * fout,int page_no,int whiteout,int outline,int scaleboth,double cx,double cy,double sx,double sy,double ax,double ay,double rot)70 ps_include(FILE *fin, FILE *fout, int page_no, int whiteout,
71 int outline, int scaleboth, double cx, double cy,
72 double sx, double sy, double ax, double ay, double rot)
73 /* fin, fout - input and output files */
74 /* page_no physical page number from *fin */
75 /* whiteout - erase picture area */
76 /* outline - draw a box around it and */
77 /* scaleboth - scale both dimensions - if not zero */
78 /* cx, cy - center of the picture and */
79 /* sx, sy - its size - in current coordinates */
80 /* ax, ay - left-right, up-down adjustment */
81 /* rot - rotation - in clockwise degrees */
82 {
83 int foundpage = 0; /* found the page when non zero */
84 int nglobal = 0; /* number of global defs so far */
85 int maxglobal = 0; /* and the number we've got room for */
86 Section prolog, page, trailer; /* prologue, page, and trailer offsets */
87 Section *global; /* offsets for all global definitions */
88 double llx, lly; /* lower left and */
89 double urx, ury; /* upper right corners - default coords */
90 double w = whiteout != 0; /* mostly for the var() macro */
91 double o = outline != 0;
92 double s = scaleboth != 0;
93 int i; /* loop index */
94
95
96 /*
97 *
98 * Reads a PostScript file (*fin), and uses structuring comments to locate the
99 * prologue, trailer, global definitions, and the requested page. After the whole
100 * file is scanned, the special ps_include PostScript definitions are copied to
101 * *fout, followed by the prologue, global definitions, the requested page, and
102 * the trailer. Before returning the initial environment (saved in PS_head) is
103 * restored.
104 *
105 * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox
106 * comment, if found, takes precedence.
107 *
108 */
109
110
111 llx = lly = 0; /* default BoundingBox - 8.5x11 inches */
112 urx = 72 * 8.5;
113 ury = 72 * 11.0;
114
115 /* section boundaries and bounding box */
116
117 prolog.start = prolog.end = 0;
118 page.start = page.end = 0;
119 trailer.start = 0;
120 fseek(fin, 0L, 0);
121
122 while ( fgets(buf, sizeof(buf), fin) != NULL )
123 if (!has("%%"))
124 continue;
125 else if (has("%%Page: ")) {
126 if (!foundpage)
127 page.start = ftell(fin);
128 sscanf(buf, "%*s %*s %d", &i);
129 if (i == page_no)
130 foundpage = 1;
131 else if (foundpage && page.end <= page.start)
132 page.end = ftell(fin);
133 } else if (has("%%EndPage: ")) {
134 sscanf(buf, "%*s %*s %d", &i);
135 if (i == page_no) {
136 foundpage = 1;
137 page.end = ftell(fin);
138 }
139 if (!foundpage)
140 page.start = ftell(fin);
141 } else if (has("%%BoundingBox:"))
142 sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury);
143 else if (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup"))
144 prolog.end = page.start = ftell(fin);
145 else if (has("%%Trailer"))
146 trailer.start = ftell(fin);
147 else if (has("%%BeginGlobal")) {
148 if (page.end <= page.start) {
149 if (nglobal >= maxglobal) {
150 maxglobal += 20;
151 global = grab(maxglobal);
152 }
153 global[nglobal].start = ftell(fin);
154 }
155 } else if (has("%%EndGlobal"))
156 if (page.end <= page.start)
157 global[nglobal++].end = ftell(fin);
158
159 fseek(fin, 0L, 2);
160 if (trailer.start == 0)
161 trailer.start = ftell(fin);
162 trailer.end = ftell(fin);
163
164 if (page.end <= page.start)
165 page.end = trailer.start;
166
167 /*
168 fprintf(stderr, "prolog=(%d,%d)\n", prolog.start, prolog.end);
169 fprintf(stderr, "page=(%d,%d)\n", page.start, page.end);
170 for(i = 0; i < nglobal; i++)
171 fprintf(stderr, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end);
172 fprintf(stderr, "trailer=(%d,%d)\n", trailer.start, trailer.end);
173 */
174
175 /* all output here */
176 print(fout, PS_head);
177 var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s);
178 var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot);
179 print(fout, PS_setup);
180 copy(fin, fout, &prolog);
181 for(i = 0; i < nglobal; i++)
182 copy(fin, fout, &global[i]);
183 copy(fin, fout, &page);
184 copy(fin, fout, &trailer);
185 print(fout, PS_tail);
186
187 if(nglobal)
188 free(global);
189
190 }
191
192 static void
print(FILE * fout,char ** s)193 print(FILE *fout, char **s)
194 {
195 while (*s)
196 fprintf(fout, "%s\n", *s++);
197 }
198
199 static void
copy(FILE * fin,FILE * fout,Section * s)200 copy(FILE *fin, FILE *fout, Section *s)
201 {
202 if (s->end <= s->start)
203 return;
204 fseek(fin, s->start, 0);
205 while (ftell(fin) < s->end && fgets(buf, sizeof(buf), fin) != NULL)
206 if (buf[0] != '%')
207 fprintf(fout, "%s", buf);
208 }
209