blob: 66a114c22e43562f114529fdee9a161eb2ce0652 [file] [log] [blame]
rsc61f5c352004-05-15 23:55:53 +00001/*
2 *
3 * Boundingbox code for PostScript translators. The boundingbox for each page
4 * is accumulated in bbox - the one for the whole document goes in docbbox. A
5 * call to writebbox() puts out an appropriate comment, updates docbbox, and
6 * resets bbox for the next page. The assumption made at the end of writebbox()
7 * is that we're really printing the current page only if output is now going
8 * to stdout - a valid assumption for all supplied translators. Needs the math
9 * library.
10 *
11 */
12
13#include <stdio.h>
14#include <ctype.h>
15#include <sys/types.h>
16#include <fcntl.h>
17#include <math.h>
18
19#include "comments.h" /* PostScript file structuring comments */
20#include "gen.h" /* a few general purpose definitions */
21#include "ext.h" /* external variable declarations */
22
23typedef struct bbox {
24 int set;
25 double llx, lly;
26 double urx, ury;
27} Bbox;
28
29Bbox bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
30Bbox docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
31
32double ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
33double matrix1[6], matrix2[6];
34
35/*****************************************************************************/
36
wkjb8551482004-05-16 07:54:22 +000037void
rsc61f5c352004-05-15 23:55:53 +000038cover(x, y)
39
40 double x, y;
41
42{
43
44/*
45 *
46 * Adds point (x, y) to bbox. Coordinates are in user space - the transformation
47 * to default coordinates happens in writebbox().
48 *
49 */
50
51 if ( bbox.set == FALSE ) {
52 bbox.llx = bbox.urx = x;
53 bbox.lly = bbox.ury = y;
54 bbox.set = TRUE;
55 } else {
56 if ( x < bbox.llx )
57 bbox.llx = x;
58 if ( y < bbox.lly )
59 bbox.lly = y;
60 if ( x > bbox.urx )
61 bbox.urx = x;
62 if ( y > bbox.ury )
63 bbox.ury = y;
64 } /* End else */
65
66} /* End of cover */
67
68/*****************************************************************************/
wkjb8551482004-05-16 07:54:22 +000069void resetbbox();
rsc61f5c352004-05-15 23:55:53 +000070
wkjb8551482004-05-16 07:54:22 +000071void
rsc61f5c352004-05-15 23:55:53 +000072writebbox(fp, keyword, slop)
73
74 FILE *fp; /* the comment is written here */
75 char *keyword; /* the boundingbox comment string */
76 int slop; /* expand (or contract?) the box a bit */
77
78{
79
80 Bbox ubbox; /* user space bounding box */
81 double x, y;
82
83/*
84 *
85 * Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
86 * (depending on slop) and then writes comment. If *keyword is BoundingBox use
87 * whatever's been saved in docbbox, otherwise assume the comment is just for
88 * the current page.
89 *
90 */
91
92 if ( strcmp(keyword, BOUNDINGBOX) == 0 )
93 bbox = docbbox;
94
95 if ( bbox.set == TRUE ) {
96 ubbox = bbox;
97 bbox.set = FALSE; /* so cover() works properly */
98 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
99 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
100 cover(x, y);
101 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
102 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
103 cover(x, y);
104 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
105 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
106 cover(x, y);
107 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
108 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
109 cover(x, y);
110 bbox.llx -= slop + 0.5;
111 bbox.lly -= slop + 0.5;
112 bbox.urx += slop + 0.5;
113 bbox.ury += slop + 0.5;
114 fprintf(fp, "%s %d %d %d %d\n", keyword, (int)bbox.llx, (int)bbox.lly,(int)bbox.urx, (int)bbox.ury);
115 bbox = ubbox;
116 } /* End if */
117
118 resetbbox((fp == stdout) ? TRUE : FALSE);
119
120} /* End of writebbox */
121
122/*****************************************************************************/
wkjb8551482004-05-16 07:54:22 +0000123void
rsc61f5c352004-05-15 23:55:53 +0000124resetbbox(output)
125
126 int output;
127
128{
129
130/*
131 *
132 * Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
133 * if we really did output on the last page.
134 *
135 */
136
137 if ( docbbox.set == TRUE ) {
138 cover(docbbox.llx, docbbox.lly);
139 cover(docbbox.urx, docbbox.ury);
140 } /* End if */
141
142 if ( output == TRUE ) {
143 docbbox = bbox;
144 docbbox.set = TRUE;
145 } /* End if */
146
147 bbox.set = FALSE;
148
149} /* End of resetbbox */
150
151/*****************************************************************************/
wkjb8551482004-05-16 07:54:22 +0000152void
rsc61f5c352004-05-15 23:55:53 +0000153scale(sx, sy)
154
155 double sx, sy;
156
157{
158
159/*
160 *
161 * Scales the default matrix.
162 *
163 */
164
165 matrix1[0] = sx;
166 matrix1[1] = 0;
167 matrix1[2] = 0;
168 matrix1[3] = sy;
169 matrix1[4] = 0;
170 matrix1[5] = 0;
171
172 concat(matrix1);
173
174} /* End of scale */
175
176/*****************************************************************************/
wkjb8551482004-05-16 07:54:22 +0000177void
rsc61f5c352004-05-15 23:55:53 +0000178translate(tx, ty)
179
180 double tx, ty;
181
182{
183
184/*
185 *
186 * Translates the default matrix.
187 *
188 */
189
190 matrix1[0] = 1.0;
191 matrix1[1] = 0.0;
192 matrix1[2] = 0.0;
193 matrix1[3] = 1.0;
194 matrix1[4] = tx;
195 matrix1[5] = ty;
196
197 concat(matrix1);
198
199} /* End of translate */
200
201/*****************************************************************************/
wkjb8551482004-05-16 07:54:22 +0000202void
rsc61f5c352004-05-15 23:55:53 +0000203rotate(angle)
204
205 double angle;
206
207{
208
209/*
210 *
211 * Rotates by angle degrees.
212 *
213 */
214
215 angle *= 3.1416 / 180;
216
217 matrix1[0] = matrix1[3] = cos(angle);
218 matrix1[1] = sin(angle);
219 matrix1[2] = -matrix1[1];
220 matrix1[4] = 0.0;
221 matrix1[5] = 0.0;
222
223 concat(matrix1);
224
225} /* End of rotate */
226
227/*****************************************************************************/
228
wkjb8551482004-05-16 07:54:22 +0000229void
rsc61f5c352004-05-15 23:55:53 +0000230concat(m1)
231
232 double m1[];
233
234{
235
236 double m2[6];
237
238/*
239 *
240 * Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[].
241 *
242 */
243
244 m2[0] = ctm[0];
245 m2[1] = ctm[1];
246 m2[2] = ctm[2];
247 m2[3] = ctm[3];
248 m2[4] = ctm[4];
249 m2[5] = ctm[5];
250
251 ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
252 ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
253 ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
254 ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
255 ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
256 ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
257
258} /* End of concat */
259
260/*****************************************************************************/
261