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 /*
31 *
32 * Picture inclusion code for PostScript printers.
33 *
34 */
35
36
37 #include <stdio.h>
38 #include "ps_include.h"
39
40
41 #define var(x) fprintf(fout, "/%s %g def\n", #x, x)
42 #define has(word) (strncmp(buf, word, strlen(word)) == 0)
43 #define grab(n) ((Section *)(nglobal \
44 ? realloc((char *)global, n * sizeof (Section)) \
45 : calloc(n, sizeof (Section))))
46
47
48 char buf[512];
49 typedef struct {
50 long start;
51 long end;
52 } Section;
53
54 extern char *calloc(), *realloc();
55
56 static void print(FILE *, char **);
57 static void copy(FILE *, FILE *, Section *);
58
59
60 /*
61 * fin, fout - input and output files
62 * page_no physical page number from *fin
63 * whiteout - erase picture area
64 * outline - draw a box around it and
65 * scaleboth - scale both dimensions - if not zero
66 * cx, cy - center of the picture and
67 * sx, sy - its size - in current coordinates
68 * ax, ay - left-right, up-down adjustment
69 * rot - rotation - in clockwise degrees
70 */
71 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)72 ps_include(FILE *fin, FILE *fout, int page_no, int whiteout,
73 int outline, int scaleboth, double cx, double cy,
74 double sx, double sy, double ax, double ay, double rot)
75 {
76 /* found the page when non zero */
77 int foundpage = 0;
78 /* number of global defs so far */
79 int nglobal = 0;
80 /* and the number we've got room for */
81 int maxglobal = 0;
82 /* prologue, page, and trailer offsets */
83 Section prolog, page, trailer;
84 /* offsets for all global definitions */
85 Section *global;
86 /* lower left and */
87 double llx, lly;
88 /* upper right corners - default coords */
89 double urx, ury;
90 /* mostly for the var() macro */
91 double w = whiteout != 0;
92 double o = outline != 0;
93 double s = scaleboth != 0;
94 int i;
95
96
97 /*
98 *
99 * Reads a PostScript file (*fin), and uses structuring comments to
100 * locate the prologue, trailer, global definitions, and the requested
101 * page. After the whole file is scanned, the special ps_include
102 * PostScript definitions are copied to *fout, followed by the
103 * prologue, global definitions, the requested page, and the
104 * trailer. Before returning the initial environment (saved in
105 * PS_head) is restored.
106 *
107 * By default we assume the picture is 8.5 by 11 inches, but the
108 * BoundingBox comment, if found, takes precedence.
109 *
110 */
111
112 /* default BoundingBox - 8.5x11 inches */
113 llx = lly = 0;
114 urx = 72 * 8.5;
115 ury = 72 * 11.0;
116
117 /* section boundaries and bounding box */
118
119 prolog.start = prolog.end = 0;
120 page.start = page.end = 0;
121 trailer.start = 0;
122 fseek(fin, 0L, 0);
123
124 while (fgets(buf, sizeof (buf), fin) != NULL)
125 if (!has("%%"))
126 continue;
127 else if (has("%%Page: ")) {
128 if (!foundpage)
129 page.start = ftell(fin);
130 sscanf(buf, "%*s %*s %d", &i);
131 if (i == page_no)
132 foundpage = 1;
133 else if (foundpage && page.end <= page.start)
134 page.end = ftell(fin);
135 } else if (has("%%EndPage: ")) {
136 sscanf(buf, "%*s %*s %d", &i);
137 if (i == page_no) {
138 foundpage = 1;
139 page.end = ftell(fin);
140 }
141 if (!foundpage)
142 page.start = ftell(fin);
143 } else if (has("%%BoundingBox:"))
144 sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf",
145 &llx, &lly, &urx, &ury);
146 else if (has("%%EndProlog") || has("%%EndSetup") ||
147 has("%%EndDocumentSetup"))
148 prolog.end = page.start = ftell(fin);
149 else if (has("%%Trailer"))
150 trailer.start = ftell(fin);
151 else if (has("%%BeginGlobal")) {
152 if (page.end <= page.start) {
153 if (nglobal >= maxglobal) {
154 maxglobal += 20;
155 global = grab(maxglobal);
156 }
157 global[nglobal].start = ftell(fin);
158 }
159 } else if (has("%%EndGlobal"))
160 if (page.end <= page.start)
161 global[nglobal++].end = ftell(fin);
162
163 fseek(fin, 0L, 2);
164 if (trailer.start == 0)
165 trailer.start = ftell(fin);
166 trailer.end = ftell(fin);
167
168 if (page.end <= page.start)
169 page.end = trailer.start;
170
171 /* all output here */
172 print(fout, PS_head);
173 var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s);
174 var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot);
175 print(fout, PS_setup);
176 copy(fin, fout, &prolog);
177 for (i = 0; i < nglobal; i++)
178 copy(fin, fout, &global[i]);
179 copy(fin, fout, &page);
180 copy(fin, fout, &trailer);
181 print(fout, PS_tail);
182
183 if (nglobal)
184 free(global);
185
186 }
187
188 static void
print(FILE * fout,char ** s)189 print(FILE *fout, char **s)
190 {
191 while (*s)
192 fprintf(fout, "%s\n", *s++);
193 }
194
195 static void
copy(FILE * fin,FILE * fout,Section * s)196 copy(FILE *fin, FILE *fout, Section *s)
197 {
198 if (s->end <= s->start)
199 return;
200 fseek(fin, s->start, 0);
201 while (ftell(fin) < s->end && fgets(buf, sizeof (buf), fin) != NULL)
202 if (buf[0] != '%')
203 fprintf(fout, "%s", buf);
204 }
205