dpost.ps: increase linewidth to match groff
[troff.git] / tr2ps / bbox.c
blob57ed6458f96dd9df418c21ea3f49dfc54d10f5de
1 /*
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.
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <math.h>
15 #include <sys/types.h>
16 #include <fcntl.h>
17 #include <string.h>
19 #include "comments.h" /* PostScript file structuring comments */
20 #include "gen.h" /* a few general purpose definitions */
21 #include "ext.h" /* external variable declarations */
23 typedef struct bbox {
24 int set;
25 double llx, lly;
26 double urx, ury;
27 } Bbox;
29 static Bbox bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
30 static Bbox docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
32 static double ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
33 static double matrix1[6], matrix2[6];
37 * Adds point (x, y) to bbox. Coordinates are in user space - the transformation
38 * to default coordinates happens in writebbox().
41 void cover(double x, double y)
43 if (bbox.set == FALSE) {
44 bbox.llx = bbox.urx = x;
45 bbox.lly = bbox.ury = y;
46 bbox.set = TRUE;
47 } else {
48 if (x < bbox.llx)
49 bbox.llx = x;
50 if (y < bbox.lly)
51 bbox.lly = y;
52 if (x > bbox.urx)
53 bbox.urx = x;
54 if (y > bbox.ury)
55 bbox.ury = y;
61 * Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
62 * if we really did output on the last page.
64 void resetbbox(int output)
66 if (docbbox.set == TRUE) {
67 cover(docbbox.llx, docbbox.lly);
68 cover(docbbox.urx, docbbox.ury);
71 if (output == TRUE) {
72 docbbox = bbox;
73 docbbox.set = TRUE;
76 bbox.set = FALSE;
80 * Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
81 * (depending on slop) and then writes comment. If *keyword is BoundingBox use
82 * whatever's been saved in docbbox, otherwise assume the comment is just for
83 * the current page.
85 * fp; * the comment is written here
86 * keyword; * the boundingbox comment string
87 * slop; * expand (or contract?) the box a bit
89 void writebbox(FILE *fp, char *keyword, int slop)
91 Bbox ubbox; /* user space bounding box */
92 double x, y;
94 if (strcmp(keyword, BOUNDINGBOX) == 0)
95 bbox = docbbox;
97 if (bbox.set == TRUE) {
98 ubbox = bbox;
99 bbox.set = FALSE; /* so cover() works properly */
100 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
101 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
102 cover(x, y);
103 x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
104 y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
105 cover(x, y);
106 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
107 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
108 cover(x, y);
109 x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
110 y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
111 cover(x, y);
112 bbox.llx -= slop + 0.5;
113 bbox.lly -= slop + 0.5;
114 bbox.urx += slop + 0.5;
115 bbox.ury += slop + 0.5;
116 fprintf(fp, "%s %d %d %d %d\n", keyword, (int) bbox.llx,
117 (int) bbox.lly,(int) bbox.urx, (int) bbox.ury);
118 bbox = ubbox;
121 resetbbox((fp == stdout) ? TRUE : FALSE);
124 /* Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[]. */
125 void concat(double m1[])
127 double m2[6];
129 m2[0] = ctm[0];
130 m2[1] = ctm[1];
131 m2[2] = ctm[2];
132 m2[3] = ctm[3];
133 m2[4] = ctm[4];
134 m2[5] = ctm[5];
136 ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
137 ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
138 ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
139 ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
140 ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
141 ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
144 /* Scales the default matrix. */
145 void scale(double sx, double sy)
147 matrix1[0] = sx;
148 matrix1[1] = 0;
149 matrix1[2] = 0;
150 matrix1[3] = sy;
151 matrix1[4] = 0;
152 matrix1[5] = 0;
154 concat(matrix1);
157 /* Translates the default matrix. */
158 void translate(double tx, double ty)
160 matrix1[0] = 1.0;
161 matrix1[1] = 0.0;
162 matrix1[2] = 0.0;
163 matrix1[3] = 1.0;
164 matrix1[4] = tx;
165 matrix1[5] = ty;
167 concat(matrix1);
170 /* Rotates by angle degrees. */
171 void rotate(double angle)
173 angle *= 3.1416 / 180;
175 matrix1[0] = matrix1[3] = cos(angle);
176 matrix1[1] = sin(angle);
177 matrix1[2] = -matrix1[1];
178 matrix1[4] = 0.0;
179 matrix1[5] = 0.0;
181 concat(matrix1);