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