1 /*
2 * Copyright (c) 2000 Matthias Elter <elter@kde.org>
3 * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #ifndef KISGLOBAL_H_
20 #define KISGLOBAL_H_
21
22 #include <limits.h>
23
24 #include <KoConfig.h>
25 #include "kis_assert.h"
26
27 #include <QPoint>
28 #include <QPointF>
29
30 const quint8 quint8_MAX = UCHAR_MAX;
31 const quint16 quint16_MAX = 65535;
32
33 const qint32 qint32_MAX = (2147483647);
34 const qint32 qint32_MIN = (-2147483647 - 1);
35
36 const quint8 MAX_SELECTED = UCHAR_MAX;
37 const quint8 MIN_SELECTED = 0;
38 const quint8 SELECTION_THRESHOLD = 1;
39
40 enum OutlineStyle {
41 OUTLINE_NONE = 0,
42 OUTLINE_CIRCLE,
43 OUTLINE_FULL,
44 OUTLINE_TILT,
45
46 N_OUTLINE_STYLE_SIZE
47 };
48
49 enum CursorStyle {
50 CURSOR_STYLE_NO_CURSOR = 0,
51 CURSOR_STYLE_TOOLICON,
52 CURSOR_STYLE_POINTER,
53 CURSOR_STYLE_SMALL_ROUND,
54 CURSOR_STYLE_CROSSHAIR,
55 CURSOR_STYLE_TRIANGLE_RIGHTHANDED,
56 CURSOR_STYLE_TRIANGLE_LEFTHANDED,
57 CURSOR_STYLE_BLACK_PIXEL,
58 CURSOR_STYLE_WHITE_PIXEL,
59
60 N_CURSOR_STYLE_SIZE
61 };
62
63 enum OldCursorStyle {
64 OLD_CURSOR_STYLE_TOOLICON = 0,
65 OLD_CURSOR_STYLE_CROSSHAIR = 1,
66 OLD_CURSOR_STYLE_POINTER = 2,
67
68 OLD_CURSOR_STYLE_OUTLINE = 3,
69
70 OLD_CURSOR_STYLE_NO_CURSOR = 4,
71 OLD_CURSOR_STYLE_SMALL_ROUND = 5,
72
73 OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT = 6,
74 OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS = 7,
75
76 OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED = 8,
77 OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED = 9,
78
79 OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED = 10,
80 OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED = 11
81 };
82
83 const double PRESSURE_MIN = 0.0;
84 const double PRESSURE_MAX = 1.0;
85 const double PRESSURE_DEFAULT = PRESSURE_MAX;
86 const double PRESSURE_THRESHOLD = 5.0 / 255.0;
87
88 // copy of lcms.h
89 #define INTENT_PERCEPTUAL 0
90 #define INTENT_RELATIVE_COLORIMETRIC 1
91 #define INTENT_SATURATION 2
92 #define INTENT_ABSOLUTE_COLORIMETRIC 3
93
94 #include <cmath>
95
96 #ifndef M_PI
97 #define M_PI 3.14159265358979323846
98 #endif
99
100
101 // converts \p a to [0, 2 * M_PI) range
102 template<typename T>
103 typename std::enable_if<std::is_floating_point<T>::value, T>::type
normalizeAngle(T a)104 normalizeAngle(T a) {
105 if (a < T(0.0)) {
106 a = T(2 * M_PI) + std::fmod(a, T(2 * M_PI));
107 }
108
109 return a >= T(2 * M_PI) ? std::fmod(a, T(2 * M_PI)) : a;
110 }
111
112 // converts \p a to [0, 360.0) range
113 template<typename T>
114 typename std::enable_if<std::is_floating_point<T>::value, T>::type
normalizeAngleDegrees(T a)115 normalizeAngleDegrees(T a) {
116 if (a < T(0.0)) {
117 a = T(360.0) + std::fmod(a, T(360.0));
118 }
119
120 return a >= T(360.0) ? std::fmod(a, T(360.0)) : a;
121 }
122
shortestAngularDistance(qreal a,qreal b)123 inline qreal shortestAngularDistance(qreal a, qreal b) {
124 qreal dist = fmod(qAbs(a - b), 2 * M_PI);
125 if (dist > M_PI) dist = 2 * M_PI - dist;
126
127 return dist;
128 }
129
incrementInDirection(qreal a,qreal inc,qreal direction)130 inline qreal incrementInDirection(qreal a, qreal inc, qreal direction) {
131 qreal b1 = a + inc;
132 qreal b2 = a - inc;
133
134 qreal d1 = shortestAngularDistance(b1, direction);
135 qreal d2 = shortestAngularDistance(b2, direction);
136
137 return d1 < d2 ? b1 : b2;
138 }
139
bisectorAngle(qreal a,qreal b)140 inline qreal bisectorAngle(qreal a, qreal b) {
141 const qreal diff = shortestAngularDistance(a, b);
142 return incrementInDirection(a, 0.5 * diff, b);
143 }
144
145 template<typename PointType>
snapToClosestAxis(PointType P)146 inline PointType snapToClosestAxis(PointType P) {
147 if (qAbs(P.x()) < qAbs(P.y())) {
148 P.setX(0);
149 } else {
150 P.setY(0);
151 }
152 return P;
153 }
154
155 template<typename T>
pow2(const T & x)156 inline T pow2(const T& x) {
157 return x * x;
158 }
159
160 template<typename T>
pow3(const T & x)161 inline T pow3(const T& x) {
162 return x * x * x;
163 }
164
165 template<typename T>
kisDegreesToRadians(T degrees)166 inline T kisDegreesToRadians(T degrees) {
167 return degrees * M_PI / 180.0;
168 }
169
170 template<typename T>
kisRadiansToDegrees(T radians)171 inline T kisRadiansToDegrees(T radians) {
172 return radians * 180.0 / M_PI;
173 }
174
175 template<class T, typename U>
kisGrowRect(const T & rect,U offset)176 inline T kisGrowRect(const T &rect, U offset) {
177 return rect.adjusted(-offset, -offset, offset, offset);
178 }
179
kisDistance(const QPointF & pt1,const QPointF & pt2)180 inline qreal kisDistance(const QPointF &pt1, const QPointF &pt2) {
181 return std::sqrt(pow2(pt1.x() - pt2.x()) + pow2(pt1.y() - pt2.y()));
182 }
183
kisSquareDistance(const QPointF & pt1,const QPointF & pt2)184 inline qreal kisSquareDistance(const QPointF &pt1, const QPointF &pt2) {
185 return pow2(pt1.x() - pt2.x()) + pow2(pt1.y() - pt2.y());
186 }
187
188 #include <QLineF>
189
kisDistanceToLine(const QPointF & m,const QLineF & line)190 inline qreal kisDistanceToLine(const QPointF &m, const QLineF &line)
191 {
192 const QPointF &p1 = line.p1();
193 const QPointF &p2 = line.p2();
194
195 qreal distance = 0;
196
197 if (qFuzzyCompare(p1.x(), p2.x())) {
198 distance = qAbs(m.x() - p2.x());
199 } else if (qFuzzyCompare(p1.y(), p2.y())) {
200 distance = qAbs(m.y() - p2.y());
201 } else {
202 qreal A = 1;
203 qreal B = - (p1.x() - p2.x()) / (p1.y() - p2.y());
204 qreal C = - p1.x() - B * p1.y();
205
206 distance = qAbs(A * m.x() + B * m.y() + C) / std::sqrt(pow2(A) + pow2(B));
207 }
208
209 return distance;
210 }
211
kisProjectOnVector(const QPointF & base,const QPointF & v)212 inline QPointF kisProjectOnVector(const QPointF &base, const QPointF &v)
213 {
214 const qreal prod = base.x() * v.x() + base.y() * v.y();
215 const qreal lengthSq = pow2(base.x()) + pow2(base.y());
216 qreal coeff = prod / lengthSq;
217
218 return coeff * base;
219 }
220
221 #include <QRect>
222
kisEnsureInRect(QRect rc,const QRect & bounds)223 inline QRect kisEnsureInRect(QRect rc, const QRect &bounds)
224 {
225 if(rc.right() > bounds.right()) {
226 rc.translate(bounds.right() - rc.right(), 0);
227 }
228
229 if(rc.left() < bounds.left()) {
230 rc.translate(bounds.left() - rc.left(), 0);
231 }
232
233 if(rc.bottom() > bounds.bottom()) {
234 rc.translate(0, bounds.bottom() - rc.bottom());
235 }
236
237 if(rc.top() < bounds.top()) {
238 rc.translate(0, bounds.top() - rc.top());
239 }
240
241 return rc;
242 }
243
244 #include "kis_pointer_utils.h"
245
246 /**
247 * A special wrapper object that converts Qt-style mutexes and locks
248 * into an object that supports Std's (and Boost's) "Lockable"
249 * concept. Basically, it converts tryLock() into try_lock() to comply
250 * with the syntax.
251 */
252
253 template <class T>
254 struct StdLockableWrapper {
StdLockableWrapperStdLockableWrapper255 StdLockableWrapper(T *lock) : m_lock(lock) {}
256
lockStdLockableWrapper257 void lock() {
258 m_lock->lock();
259 }
260
try_lockStdLockableWrapper261 bool try_lock() {
262 return m_lock->tryLock();
263 }
264
unlockStdLockableWrapper265 void unlock() {
266 m_lock->unlock();
267 }
268
269 private:
270 T *m_lock;
271 };
272
273 #endif // KISGLOBAL_H_
274
275