Line data Source code
1 : /* Copyright 1989-2024 Free Software Foundation, Inc.
2 : Written by James Clark (jjc@jclark.com)
3 :
4 : This file is part of groff, the GNU roff typesetting system.
5 :
6 : groff is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation, either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 :
19 : #include <stdckdint.h>
20 :
21 : class vunits {
22 : int n;
23 : public:
24 : vunits();
25 : vunits(units);
26 : units to_units();
27 : bool is_zero();
28 : vunits& operator +=(const vunits&);
29 : vunits& operator -=(const vunits&);
30 : // scale n by x/y
31 : friend inline vunits scale(vunits n, units x, units y);
32 : friend inline vunits scale(vunits n, vunits x, vunits y);
33 : friend inline vunits operator +(const vunits&, const vunits&);
34 : friend inline vunits operator -(const vunits&, const vunits&);
35 : friend inline vunits operator -(const vunits&);
36 : friend inline int operator /(const vunits&, const vunits&);
37 : friend inline vunits operator /(const vunits&, int);
38 : friend inline vunits operator *(const vunits&, int);
39 : friend inline vunits operator *(int, const vunits&);
40 : friend inline bool operator <(const vunits&, const vunits&);
41 : friend inline bool operator >(const vunits&, const vunits&);
42 : friend inline bool operator <=(const vunits&, const vunits&);
43 : friend inline bool operator >=(const vunits&, const vunits&);
44 : friend inline bool operator ==(const vunits&, const vunits&);
45 : friend inline bool operator !=(const vunits&, const vunits&);
46 : };
47 :
48 : extern const vunits V0;
49 :
50 : class hunits {
51 : int n;
52 : public:
53 : hunits();
54 : hunits(units);
55 : units to_units();
56 : bool is_zero();
57 : hunits& operator +=(const hunits&);
58 : hunits& operator -=(const hunits&);
59 : // scale n by x/y
60 : friend inline hunits scale(hunits n, units x, units y);
61 : friend inline hunits scale(hunits n, double x);
62 : friend inline hunits operator +(const hunits&, const hunits&);
63 : friend inline hunits operator -(const hunits&, const hunits&);
64 : friend inline hunits operator -(const hunits&);
65 : friend inline int operator /(const hunits&, const hunits&);
66 : friend inline hunits operator /(const hunits&, int);
67 : friend inline hunits operator *(const hunits&, int);
68 : friend inline hunits operator *(int, const hunits&);
69 : friend inline bool operator <(const hunits&, const hunits&);
70 : friend inline bool operator >(const hunits&, const hunits&);
71 : friend inline bool operator <=(const hunits&, const hunits&);
72 : friend inline bool operator >=(const hunits&, const hunits&);
73 : friend inline bool operator ==(const hunits&, const hunits&);
74 : friend inline bool operator !=(const hunits&, const hunits&);
75 : };
76 :
77 : extern const hunits H0;
78 :
79 : extern bool read_vunits(vunits *, unsigned char si);
80 : extern bool read_hunits(hunits *, unsigned char si);
81 : extern bool read_vunits(vunits *, unsigned char si, vunits prev_value);
82 : extern bool read_hunits(hunits *, unsigned char si, hunits prev_value);
83 :
84 8842634 : inline vunits:: vunits() : n(0)
85 : {
86 8842634 : }
87 :
88 9526943 : inline units vunits::to_units()
89 : {
90 : units r;
91 9526943 : if (ckd_mul(&r, n, vresolution))
92 0 : warning(WARN_RANGE, "integer multiplication saturated");
93 9526943 : return r;
94 : }
95 :
96 : inline bool vunits::is_zero()
97 : {
98 : return n == 0;
99 : }
100 :
101 1968238 : inline vunits operator +(const vunits & x, const vunits & y)
102 : {
103 1968238 : vunits r;
104 1968238 : r = x;
105 1968238 : if (ckd_add(&r.n, r.n, y.n))
106 0 : warning(WARN_RANGE, "integer addition saturated");
107 1968238 : return r;
108 : }
109 :
110 449726 : inline vunits operator -(const vunits & x, const vunits & y)
111 : {
112 449726 : vunits r;
113 449726 : r = x;
114 449726 : if (ckd_sub(&r.n, r.n, y.n))
115 0 : warning(WARN_RANGE, "integer subtraction saturated");
116 449726 : return r;
117 : }
118 :
119 2159376 : inline vunits operator -(const vunits & x)
120 : {
121 2159376 : vunits r;
122 : // Why? Consider -(INT_MIN) in two's complement.
123 2159376 : if (ckd_mul(&r.n, x.n, -1))
124 0 : warning(WARN_RANGE, "integer multiplication saturated");
125 2159376 : return r;
126 : }
127 :
128 0 : inline int operator /(const vunits & x, const vunits & y)
129 : {
130 0 : return x.n / y.n;
131 : }
132 :
133 0 : inline vunits operator /(const vunits & x, int n)
134 : {
135 0 : vunits r;
136 0 : r = x;
137 0 : r.n /= n;
138 0 : return r;
139 : }
140 :
141 0 : inline vunits operator *(const vunits & x, int n)
142 : {
143 0 : vunits r;
144 0 : r = x;
145 0 : if (ckd_mul(&r.n, x.n, n))
146 0 : warning(WARN_RANGE, "integer multiplication saturated");
147 0 : return r;
148 : }
149 :
150 4 : inline vunits operator *(int n, const vunits & x)
151 : {
152 4 : vunits r;
153 4 : r = x;
154 4 : if (ckd_mul(&r.n, n, x.n))
155 0 : warning(WARN_RANGE, "integer multiplication saturated");
156 4 : return r;
157 : }
158 :
159 4868366 : inline bool operator <(const vunits & x, const vunits & y)
160 : {
161 4868366 : return x.n < y.n;
162 : }
163 :
164 2923172 : inline bool operator >(const vunits & x, const vunits & y)
165 : {
166 2923172 : return x.n > y.n;
167 : }
168 :
169 27577 : inline bool operator <=(const vunits & x, const vunits & y)
170 : {
171 27577 : return x.n <= y.n;
172 : }
173 :
174 1940676 : inline bool operator >=(const vunits & x, const vunits & y)
175 : {
176 1940676 : return x.n >= y.n;
177 : }
178 :
179 4781 : inline bool operator ==(const vunits & x, const vunits & y)
180 : {
181 4781 : return x.n == y.n;
182 : }
183 :
184 0 : inline bool operator !=(const vunits & x, const vunits & y)
185 : {
186 0 : return x.n != y.n;
187 : }
188 :
189 2825803 : inline vunits& vunits::operator +=(const vunits & x)
190 : {
191 2825803 : n += x.n;
192 2825803 : return *this;
193 : }
194 :
195 2 : inline vunits& vunits::operator -=(const vunits & x)
196 : {
197 2 : n -= x.n;
198 2 : return *this;
199 : }
200 :
201 127365568 : inline hunits:: hunits() : n(0)
202 : {
203 127365568 : }
204 :
205 15124461 : inline units hunits::to_units()
206 : {
207 : units r;
208 15124461 : if (ckd_mul(&r, n, hresolution))
209 0 : warning(WARN_RANGE, "integer multiplication saturated");
210 15124461 : return r;
211 : }
212 :
213 809950 : inline bool hunits::is_zero()
214 : {
215 809950 : return n == 0;
216 : }
217 :
218 68881371 : inline hunits operator +(const hunits & x, const hunits & y)
219 : {
220 68881371 : hunits r;
221 68881371 : r = x;
222 68881371 : if (ckd_add(&r.n, r.n, y.n))
223 0 : warning(WARN_RANGE, "integer addition saturated");
224 68881371 : return r;
225 : }
226 :
227 6073180 : inline hunits operator -(const hunits & x, const hunits & y)
228 : {
229 6073180 : hunits r;
230 6073180 : r = x;
231 6073180 : if (ckd_sub(&r.n, r.n, y.n))
232 0 : warning(WARN_RANGE, "integer subtraction saturated");
233 6073180 : return r;
234 : }
235 :
236 2259 : inline hunits operator -(const hunits & x)
237 : {
238 2259 : hunits r;
239 2259 : r = x;
240 : // Why? Consider -(INT_MIN) in two's complement.
241 2259 : if (ckd_mul(&r.n, x.n, -1))
242 0 : warning(WARN_RANGE, "integer multiplication saturated");
243 2259 : return r;
244 : }
245 :
246 310 : inline int operator /(const hunits & x, const hunits & y)
247 : {
248 310 : return x.n / y.n;
249 : }
250 :
251 375881 : inline hunits operator /(const hunits & x, int n)
252 : {
253 375881 : hunits r;
254 375881 : r = x;
255 375881 : r.n /= n;
256 375881 : return r;
257 : }
258 :
259 1243 : inline hunits operator *(const hunits & x, int n)
260 : {
261 1243 : hunits r;
262 1243 : r = x;
263 1243 : if (ckd_mul(&r.n, x.n, n))
264 0 : warning(WARN_RANGE, "integer multiplication saturated");
265 1243 : return r;
266 : }
267 :
268 92 : inline hunits operator *(int n, const hunits & x)
269 : {
270 92 : hunits r;
271 92 : r = x;
272 92 : if (ckd_mul(&r.n, x.n, n))
273 0 : warning(WARN_RANGE, "integer multiplication saturated");
274 92 : return r;
275 : }
276 :
277 47742339 : inline bool operator <(const hunits & x, const hunits & y)
278 : {
279 47742339 : return x.n < y.n;
280 : }
281 :
282 1213074 : inline bool operator >(const hunits & x, const hunits & y)
283 : {
284 1213074 : return x.n > y.n;
285 : }
286 :
287 47587802 : inline bool operator <=(const hunits & x, const hunits & y)
288 : {
289 47587802 : return x.n <= y.n;
290 : }
291 :
292 49 : inline bool operator >=(const hunits & x, const hunits & y)
293 : {
294 49 : return x.n >= y.n;
295 : }
296 :
297 53849 : inline bool operator ==(const hunits & x, const hunits & y)
298 : {
299 53849 : return x.n == y.n;
300 : }
301 :
302 147 : inline bool operator !=(const hunits & x, const hunits & y)
303 : {
304 147 : return x.n != y.n;
305 : }
306 :
307 73464080 : inline hunits& hunits::operator +=(const hunits & x)
308 : {
309 73464080 : n += x.n;
310 73464080 : return *this;
311 : }
312 :
313 689118 : inline hunits& hunits::operator -=(const hunits & x)
314 : {
315 689118 : n -= x.n;
316 689118 : return *this;
317 : }
318 :
319 1591979 : inline hunits scale(hunits n, units x, units y)
320 : {
321 1591979 : hunits r;
322 1591979 : r.n = scale(n.n, x, y);
323 1591979 : return r;
324 : }
325 :
326 3112 : inline vunits scale(vunits n, units x, units y)
327 : {
328 3112 : vunits r;
329 3112 : r.n = scale(n.n, x, y);
330 3112 : return r;
331 : }
332 :
333 : inline vunits scale(vunits n, vunits x, vunits y)
334 : {
335 : vunits r;
336 : r.n = scale(n.n, x.n, y.n);
337 : return r;
338 : }
339 :
340 : inline hunits scale(hunits n, double x)
341 : {
342 : hunits r;
343 : r.n = int(n.n * x);
344 : return r;
345 : }
346 :
347 : inline units scale(units n, double x)
348 : {
349 : return int(n * x);
350 : }
351 :
352 7909 : inline units points_to_units(units n)
353 : {
354 7909 : return scale(n, units_per_inch, 72);
355 : }
356 :
357 : // Local Variables:
358 : // fill-column: 72
359 : // mode: C++
360 : // End:
361 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:
|