bea891742e7253c2cfc7b43c2dde5e5abeac86a2
1 /*\r
2 * Inkscape::Util::FixedPoint - fixed point type\r
3 *\r
4 * Authors:\r
5 * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
6 *\r
7 * Copyright (C) 2006 Jasper van de Gronde\r
8 *\r
9 * Released under GNU GPL, read the file 'COPYING' for more information\r
10 */\r
11 \r
12 #ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
13 #define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
14 \r
15 #include "traits/reference.h"\r
16 #include <math.h>\r
17 #include <algorithm>\r
18 #include <limits>\r
19 \r
20 namespace Inkscape {\r
21 \r
22 namespace Util {\r
23 \r
24 template <typename T, unsigned int precision>\r
25 class FixedPoint {\r
26 public:\r
27 FixedPoint() {}\r
28 FixedPoint(const FixedPoint& value) : v(value.v) {}\r
29 FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
30 FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
31 FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
32 FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
33 FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
34 FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
35 FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
36 \r
37 FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
38 FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
39 FixedPoint& operator*=(FixedPoint val) {\r
40 const unsigned int half_size = 8*sizeof(T)/2;\r
41 const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
42 const T ah = v>>half_size, bh = val.v>>half_size;\r
43 v = static_cast<unsigned int>(al*bl)>>precision;\r
44 if ( half_size >= precision ) {\r
45 v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
46 } else {\r
47 v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
48 v += (ah*bh)<<(2*half_size-precision);\r
49 }\r
50 return *this;\r
51 }\r
52 \r
53 FixedPoint& operator*=(char val) { v *= val; return *this; }\r
54 FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
55 FixedPoint& operator*=(short val) { v *= val; return *this; }\r
56 FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
57 FixedPoint& operator*=(int val) { v *= val; return *this; }\r
58 FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
59 \r
60 FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
61 FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
62 FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
63 \r
64 FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
65 FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
66 FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
67 FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
68 FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
69 FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
70 \r
71 float operator*(float val) const { return static_cast<float>(*this)*val; }\r
72 double operator*(double val) const { return static_cast<double>(*this)*val; }\r
73 \r
74 operator char() const { return v>>precision; }\r
75 operator unsigned char() const { return v>>precision; }\r
76 operator short() const { return v>>precision; }\r
77 operator unsigned short() const { return v>>precision; }\r
78 operator int() const { return v>>precision; }\r
79 operator unsigned int() const { return v>>precision; }\r
80 \r
81 operator float() const { return ldexpf(v,-precision); }\r
82 operator double() const { return ldexp(v,-precision); }\r
83 private:\r
84 T v;\r
85 };\r
86 \r
87 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
88 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
89 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
90 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
91 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
92 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
93 \r
94 template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
95 template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
96 \r
97 }\r
98 \r
99 }\r
100 \r
101 #endif\r
102 /*\r
103 Local Variables:\r
104 mode:c++\r
105 c-file-style:"stroustrup"\r
106 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
107 indent-tabs-mode:nil\r
108 fill-column:99\r
109 End:\r
110 */\r
111 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
112 /*\r
113 * Inkscape::Util::FixedPoint - fixed point type\r
114 *\r
115 * Authors:\r
116 * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
117 *\r
118 * Copyright (C) 2006 Jasper van de Gronde\r
119 *\r
120 * Released under GNU GPL, read the file 'COPYING' for more information\r
121 */\r
122 \r
123 #ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
124 #define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
125 \r
126 #include "traits/reference.h"\r
127 #include <math.h>\r
128 #include <algorithm>\r
129 #include <limits>\r
130 \r
131 namespace Inkscape {\r
132 \r
133 namespace Util {\r
134 \r
135 template <typename T, unsigned int precision>\r
136 class FixedPoint {\r
137 public:\r
138 FixedPoint() {}\r
139 FixedPoint(const FixedPoint& value) : v(value.v) {}\r
140 FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
141 FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
142 FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
143 FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
144 FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
145 FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
146 FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
147 \r
148 FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
149 FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
150 FixedPoint& operator*=(FixedPoint val) {\r
151 const unsigned int half_size = 8*sizeof(T)/2;\r
152 const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
153 const T ah = v>>half_size, bh = val.v>>half_size;\r
154 v = static_cast<unsigned int>(al*bl)>>precision;\r
155 if ( half_size >= precision ) {\r
156 v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
157 } else {\r
158 v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
159 v += (ah*bh)<<(2*half_size-precision);\r
160 }\r
161 return *this;\r
162 }\r
163 \r
164 FixedPoint& operator*=(char val) { v *= val; return *this; }\r
165 FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
166 FixedPoint& operator*=(short val) { v *= val; return *this; }\r
167 FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
168 FixedPoint& operator*=(int val) { v *= val; return *this; }\r
169 FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
170 \r
171 FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
172 FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
173 FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
174 \r
175 FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
176 FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
177 FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
178 FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
179 FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
180 FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
181 \r
182 float operator*(float val) const { return static_cast<float>(*this)*val; }\r
183 double operator*(double val) const { return static_cast<double>(*this)*val; }\r
184 \r
185 operator char() const { return v>>precision; }\r
186 operator unsigned char() const { return v>>precision; }\r
187 operator short() const { return v>>precision; }\r
188 operator unsigned short() const { return v>>precision; }\r
189 operator int() const { return v>>precision; }\r
190 operator unsigned int() const { return v>>precision; }\r
191 \r
192 operator float() const { return ldexpf(v,-precision); }\r
193 operator double() const { return ldexp(v,-precision); }\r
194 private:\r
195 T v;\r
196 };\r
197 \r
198 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
199 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
200 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
201 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
202 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
203 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
204 \r
205 template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
206 template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
207 \r
208 }\r
209 \r
210 }\r
211 \r
212 #endif\r
213 /*\r
214 Local Variables:\r
215 mode:c++\r
216 c-file-style:"stroustrup"\r
217 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
218 indent-tabs-mode:nil\r
219 fill-column:99\r
220 End:\r
221 */\r
222 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
223 /*\r
224 * Inkscape::Util::FixedPoint - fixed point type\r
225 *\r
226 * Authors:\r
227 * Jasper van de Gronde <th.v.d.gronde@hccnet.net>\r
228 *\r
229 * Copyright (C) 2006 Jasper van de Gronde\r
230 *\r
231 * Released under GNU GPL, read the file 'COPYING' for more information\r
232 */\r
233 \r
234 #ifndef SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
235 #define SEEN_INKSCAPE_UTIL_FIXED_POINT_H\r
236 \r
237 #include "traits/reference.h"\r
238 #include <math.h>\r
239 #include <algorithm>\r
240 #include <limits>\r
241 \r
242 namespace Inkscape {\r
243 \r
244 namespace Util {\r
245 \r
246 template <typename T, unsigned int precision>\r
247 class FixedPoint {\r
248 public:\r
249 FixedPoint() {}\r
250 FixedPoint(const FixedPoint& value) : v(value.v) {}\r
251 FixedPoint(char value) : v(static_cast<T>(value)<<precision) {}\r
252 FixedPoint(unsigned char value) : v(static_cast<T>(value)<<precision) {}\r
253 FixedPoint(short value) : v(static_cast<T>(value)<<precision) {}\r
254 FixedPoint(unsigned short value) : v(static_cast<T>(value)<<precision) {}\r
255 FixedPoint(int value) : v(static_cast<T>(value)<<precision) {}\r
256 FixedPoint(unsigned int value) : v(static_cast<T>(value)<<precision) {}\r
257 FixedPoint(double value) : v(static_cast<T>(floor(value*(1<<precision)))) {}\r
258 \r
259 FixedPoint& operator+=(FixedPoint val) { v += val.v; return *this; }\r
260 FixedPoint& operator-=(FixedPoint val) { v -= val.v; return *this; }\r
261 FixedPoint& operator*=(FixedPoint val) {\r
262 const unsigned int half_size = 8*sizeof(T)/2;\r
263 const T al = v&((1<<half_size)-1), bl = val.v&((1<<half_size)-1);\r
264 const T ah = v>>half_size, bh = val.v>>half_size;\r
265 v = static_cast<unsigned int>(al*bl)>>precision;\r
266 if ( half_size >= precision ) {\r
267 v += ((al*bh)+(ah*bl)+((ah*bh)<<half_size))<<(half_size-precision);\r
268 } else {\r
269 v += ((al*bh)+(ah*bl))>>(precision-half_size);\r
270 v += (ah*bh)<<(2*half_size-precision);\r
271 }\r
272 return *this;\r
273 }\r
274 \r
275 FixedPoint& operator*=(char val) { v *= val; return *this; }\r
276 FixedPoint& operator*=(unsigned char val) { v *= val; return *this; }\r
277 FixedPoint& operator*=(short val) { v *= val; return *this; }\r
278 FixedPoint& operator*=(unsigned short val) { v *= val; return *this; }\r
279 FixedPoint& operator*=(int val) { v *= val; return *this; }\r
280 FixedPoint& operator*=(unsigned int val) { v *= val; return *this; }\r
281 \r
282 FixedPoint operator+(FixedPoint val) const { FixedPoint r(*this); return r+=val; }\r
283 FixedPoint operator-(FixedPoint val) const { FixedPoint r(*this); return r-=val; }\r
284 FixedPoint operator*(FixedPoint val) const { FixedPoint r(*this); return r*=val; }\r
285 \r
286 FixedPoint operator*(char val) const { FixedPoint r(*this); return r*=val; }\r
287 FixedPoint operator*(unsigned char val) const { FixedPoint r(*this); return r*=val; }\r
288 FixedPoint operator*(short val) const { FixedPoint r(*this); return r*=val; }\r
289 FixedPoint operator*(unsigned short val) const { FixedPoint r(*this); return r*=val; }\r
290 FixedPoint operator*(int val) const { FixedPoint r(*this); return r*=val; }\r
291 FixedPoint operator*(unsigned int val) const { FixedPoint r(*this); return r*=val; }\r
292 \r
293 float operator*(float val) const { return static_cast<float>(*this)*val; }\r
294 double operator*(double val) const { return static_cast<double>(*this)*val; }\r
295 \r
296 operator char() const { return v>>precision; }\r
297 operator unsigned char() const { return v>>precision; }\r
298 operator short() const { return v>>precision; }\r
299 operator unsigned short() const { return v>>precision; }\r
300 operator int() const { return v>>precision; }\r
301 operator unsigned int() const { return v>>precision; }\r
302 \r
303 operator float() const { return ldexpf(v,-precision); }\r
304 operator double() const { return ldexp(v,-precision); }\r
305 private:\r
306 T v;\r
307 };\r
308 \r
309 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(char a, FixedPoint<T,precision> b) { return b*=a; }\r
310 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned char a, FixedPoint<T,precision> b) { return b*=a; }\r
311 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(short a, FixedPoint<T,precision> b) { return b*=a; }\r
312 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned short a, FixedPoint<T,precision> b) { return b*=a; }\r
313 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(int a, FixedPoint<T,precision> b) { return b*=a; }\r
314 template<typename T, unsigned int precision> FixedPoint<T,precision> operator *(unsigned int a, FixedPoint<T,precision> b) { return b*=a; }\r
315 \r
316 template<typename T, unsigned int precision> float operator *(float a, FixedPoint<T,precision> b) { return b*a; }\r
317 template<typename T, unsigned int precision> double operator *(double a, FixedPoint<T,precision> b) { return b*a; }\r
318 \r
319 }\r
320 \r
321 }\r
322 \r
323 #endif\r
324 /*\r
325 Local Variables:\r
326 mode:c++\r
327 c-file-style:"stroustrup"\r
328 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
329 indent-tabs-mode:nil\r
330 fill-column:99\r
331 End:\r
332 */\r
333 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r