tbbox.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tbbox.c (5575B)
---
1 /*
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 <string.h>
15 #include <ctype.h>
16 #include <sys/types.h>
17 #include <fcntl.h>
18 #include <math.h>
19
20 #include "comments.h" /* PostScript file structuring comments */
21 #include "gen.h" /* a few general purpose definitions */
22 #include "ext.h" /* external variable declarations */
23
24 typedef struct bbox {
25 int set;
26 double llx, lly;
27 double urx, ury;
28 } Bbox;
29
30 Bbox bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
31 Bbox docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
32
33 double ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
34 double matrix1[6], matrix2[6];
35
36 /*****************************************************************************/
37
38 void
39 cover(x, y)
40
41 double x, y;
42
43 {
44
45 /*
46 *
47 * Adds point (x, y) to bbox. Coordinates are in user space - the transformation
48 * to default coordinates happens in writebbox().
49 *
50 */
51
52 if ( bbox.set == FALSE ) {
53 bbox.llx = bbox.urx = x;
54 bbox.lly = bbox.ury = y;
55 bbox.set = TRUE;
56 } else {
57 if ( x < bbox.llx )
58 bbox.llx = x;
59 if ( y < bbox.lly )
60 bbox.lly = y;
61 if ( x > bbox.urx )
62 bbox.urx = x;
63 if ( y > bbox.ury )
64 bbox.ury = y;
65 } /* End else */
66
67 } /* End of cover */
68
69 /*****************************************************************************/
70 void resetbbox(int);
71
72 void
73 writebbox(fp, keyword, slop)
74
75 FILE *fp; /* the comment is written here */
76 char *keyword; /* the boundingbox comment string */
77 int slop; /* expand (or contract?) the box a bit */
78
79 {
80
81 Bbox ubbox; /* user space bounding box */
82 double x, y;
83
84 /*
85 *
86 * Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
87 * (depending on slop) and then writes comment. If *keyword is BoundingBox use
88 * whatever's been saved in docbbox, otherwise assume the comment is just for
89 * the current page.
90 *
91 */
92
93 if ( strcmp(keyword, BOUNDINGBOX) == 0 )
94 bbox = docbbox;
95
96 if ( bbox.set == TRUE ) {
97 ubbox = bbox;
98 bbox.set = FALSE; /* so cover() works properly */
99 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
100 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
101 cover(x, y);
102 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
103 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
104 cover(x, y);
105 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
106 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
107 cover(x, y);
108 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
109 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
110 cover(x, y);
111 bbox.llx -= slop + 0.5;
112 bbox.lly -= slop + 0.5;
113 bbox.urx += slop + 0.5;
114 bbox.ury += slop + 0.5;
115 fprintf(fp, "%s %d %d %d %d\n", keyword, (int)bbox.llx, (int)bbox.lly,(int)bbox.urx, (int)bbox.ury);
116 bbox = ubbox;
117 } /* End if */
118
119 resetbbox((fp == stdout) ? TRUE : FALSE);
120
121 } /* End of writebbox */
122
123 /*****************************************************************************/
124 void
125 resetbbox(output)
126
127 int output;
128
129 {
130
131 /*
132 *
133 * Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
134 * if we really did output on the last page.
135 *
136 */
137
138 if ( docbbox.set == TRUE ) {
139 cover(docbbox.llx, docbbox.lly);
140 cover(docbbox.urx, docbbox.ury);
141 } /* End if */
142
143 if ( output == TRUE ) {
144 docbbox = bbox;
145 docbbox.set = TRUE;
146 } /* End if */
147
148 bbox.set = FALSE;
149
150 } /* End of resetbbox */
151
152 /*****************************************************************************/
153 void
154 scale(sx, sy)
155
156 double sx, sy;
157
158 {
159
160 /*
161 *
162 * Scales the default matrix.
163 *
164 */
165
166 matrix1[0] = sx;
167 matrix1[1] = 0;
168 matrix1[2] = 0;
169 matrix1[3] = sy;
170 matrix1[4] = 0;
171 matrix1[5] = 0;
172
173 concat(matrix1);
174
175 } /* End of scale */
176
177 /*****************************************************************************/
178 void
179 translate(tx, ty)
180
181 double tx, ty;
182
183 {
184
185 /*
186 *
187 * Translates the default matrix.
188 *
189 */
190
191 matrix1[0] = 1.0;
192 matrix1[1] = 0.0;
193 matrix1[2] = 0.0;
194 matrix1[3] = 1.0;
195 matrix1[4] = tx;
196 matrix1[5] = ty;
197
198 concat(matrix1);
199
200 } /* End of translate */
201
202 /*****************************************************************************/
203 void
204 rotate(angle)
205
206 double angle;
207
208 {
209
210 /*
211 *
212 * Rotates by angle degrees.
213 *
214 */
215
216 angle *= 3.1416 / 180;
217
218 matrix1[0] = matrix1[3] = cos(angle);
219 matrix1[1] = sin(angle);
220 matrix1[2] = -matrix1[1];
221 matrix1[4] = 0.0;
222 matrix1[5] = 0.0;
223
224 concat(matrix1);
225
226 } /* End of rotate */
227
228 /*****************************************************************************/
229
230 void
231 concat(m1)
232
233 double m1[];
234
235 {
236
237 double m2[6];
238
239 /*
240 *
241 * Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[].
242 *
243 */
244
245 m2[0] = ctm[0];
246 m2[1] = ctm[1];
247 m2[2] = ctm[2];
248 m2[3] = ctm[3];
249 m2[4] = ctm[4];
250 m2[5] = ctm[5];
251
252 ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
253 ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
254 ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
255 ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
256 ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
257 ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
258
259 } /* End of concat */
260
261 /*****************************************************************************/