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