~ubuntu-branches/ubuntu/wily/scribus/wily-proposed

« back to all changes in this revision

Viewing changes to scribus/util_math.cpp

  • Committer: Package Import Robot
  • Author(s): Oleksandr Moskalenko
  • Date: 2012-02-09 21:50:56 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120209215056-2wrx1ara0jbm7fi5
Tags: 1.4.0.dfsg+r17287-1
* New upstream stable release upload into Debian (Closes: #654703).
* Applied the Ubuntu armel patch.
* Removed non-free color swatches from resources.
* debian/control:
  - Moved icc-profiles from Recommends to Suggests (Closes: #655885).
  - Updated Standards-Version to 3.9.2.
  - Updated extended description per lintian warning.
* debian/rules:
  - Update mailcap (Closes: #630751). A request for mime.types update has
    been sent to the mime-support maintainer.
  - Added build-arch and build-indep targets per lintian warning.
* debian/patches:
  - top_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't install the non-free "doc" dir.
  - profiles_cmakelists.patch - don't install non-free sRGB profile.
* debian/copyright: 
  - Converted to the DEP5 machine readable foramt.
  - Added licenses for free color swatches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
 
to the COPYING file provided with the program. Following this notice may exist
4
 
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
 
for which a new license (GPL+exception) is in place.
6
 
*/
7
 
/***************************************************************************
8
 
                          util.cpp  -  description
9
 
                             -------------------
10
 
    begin                : Fri Sep 14 2001
11
 
    copyright            : (C) 2001 by Franz Schmid
12
 
    email                : Franz.Schmid@altmuehlnet.de
13
 
 ***************************************************************************/
14
 
 
15
 
/***************************************************************************
16
 
 *                                                                         *
17
 
 *   This program is free software; you can redistribute it and/or modify  *
18
 
 *   it under the terms of the GNU General Public License as published by  *
19
 
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 
 *   (at your option) any later version.                                   *
21
 
 *                                                                         *
22
 
 ***************************************************************************/
23
 
 
24
 
#include "util_math.h"
25
 
#include "scconfig.h"
26
 
#include "fpoint.h"
27
 
#include "fpointarray.h"
28
 
 
29
 
using namespace std;
30
 
 
31
 
 
32
 
 
33
 
uint getDouble(QString in, bool raw)
34
 
{
35
 
        QByteArray bb(4, ' ');
36
 
        if (raw)
37
 
        {
38
 
                // Qt4
39
 
/*              bb[3] = static_cast<uchar>(QChar(in.at(0)));
40
 
                bb[2] = static_cast<uchar>(QChar(in.at(1)));
41
 
                bb[1] = static_cast<uchar>(QChar(in.at(2)));
42
 
                bb[0] = static_cast<uchar>(QChar(in.at(3)));*/
43
 
                bb = bb.insert(3, in.at(0));
44
 
                bb = bb.insert(2, in.at(1));
45
 
                bb = bb.insert(1, in.at(2));
46
 
                bb = bb.insert(0, in.at(3));
47
 
        }
48
 
        else
49
 
        {
50
 
                // Qt4
51
 
//              bb[0] = static_cast<uchar>(QChar(in.at(0)));
52
 
//              bb[1] = static_cast<uchar>(QChar(in.at(1)));
53
 
//              bb[2] = static_cast<uchar>(QChar(in.at(2)));
54
 
//              bb[3] = static_cast<uchar>(QChar(in.at(3)));
55
 
                bb = bb.insert(0, in.at(0));
56
 
                bb = bb.insert(1, in.at(1));
57
 
                bb = bb.insert(2, in.at(2));
58
 
                bb = bb.insert(3, in.at(3));
59
 
        }
60
 
        uint ret;
61
 
        ret = bb[0] & 0xff;
62
 
        ret |= (bb[1] << 8) & 0xff00;
63
 
        ret |= (bb[2] << 16) & 0xff0000;
64
 
        ret |= (bb[3] << 24) & 0xff000000;
65
 
        return ret;
66
 
}
67
 
 
68
 
QPainterPath RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2)
69
 
{
70
 
        uint cx = star ? c * 2 : c;
71
 
        double seg = 360.0 / cx;
72
 
        double sc = rota + 180.0;
73
 
        double di = factor;
74
 
        double mx = 0;
75
 
        double my = 0;
76
 
        bool first = true;
77
 
        double trueLength = sqrt(pow(sin(seg / 180.0 * M_PI) * (w / 2.0), 2) + pow(cos(seg / 180.0 * M_PI) * (h / 2.0) + (h/2.0) - h, 2));
78
 
        QPainterPath pts;
79
 
        for (uint x = 0; x < cx; ++x)
80
 
        {
81
 
                sc = seg * x + 180.0 + rota;
82
 
                if (star)
83
 
                {
84
 
                        double wf = w / 2.0;
85
 
                        double hf = h / 2.0;
86
 
                        if (x % 2 != 0)
87
 
                        {
88
 
                                wf *= di;
89
 
                                hf *= di;
90
 
                        }
91
 
                        mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
92
 
                        my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
93
 
                        if (first)
94
 
                                pts.moveTo(mx, my);
95
 
                        else
96
 
                        {
97
 
                                if (factor2 != 0.0)
98
 
                                {
99
 
                                        if (x % 2 != 0)
100
 
                                        {
101
 
                                                QPointF curr = pts.currentPosition();
102
 
                                                double mxc = sin((sc + 90.0) / 180.0 * M_PI) * (-trueLength * factor2) + mx;
103
 
                                                double myc = cos((sc + 90.0) / 180.0 * M_PI) * (-trueLength * factor2) + my;
104
 
                                                pts.cubicTo(curr, QPointF(mxc, myc), QPointF(mx, my));
105
 
                                        }
106
 
                                        else
107
 
                                        {
108
 
                                                QPointF curr = pts.currentPosition();
109
 
                                                double mxc = sin((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.x();
110
 
                                                double myc = cos((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.y();
111
 
                                                pts.cubicTo(QPointF(mxc, myc), QPointF(mx, my), QPointF(mx, my));
112
 
                                        }
113
 
                                }
114
 
                                else
115
 
                                        pts.lineTo(mx, my);
116
 
                        }
117
 
                }
118
 
                else
119
 
                {
120
 
                        mx = sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0);
121
 
                        my = cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0);
122
 
                        if (first)
123
 
                                pts.moveTo(mx, my);
124
 
                        else
125
 
                                pts.lineTo(mx, my);
126
 
                }
127
 
                first = false;
128
 
        }
129
 
        if ((star) && (factor2 != 0.0))
130
 
        {
131
 
                sc = 360.0 + 180.0 + rota;
132
 
                mx = sin(sc / 180.0 * M_PI) * (w / 2.0) + (w/2.0);
133
 
                my = cos(sc / 180.0 * M_PI) * (h / 2.0) + (h/2.0);
134
 
                QPointF curr = pts.currentPosition();
135
 
                double mxc = sin((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.x();
136
 
                double myc = cos((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.y();
137
 
                pts.cubicTo(QPointF(mxc, myc), QPointF(mx, my), QPointF(mx, my));
138
 
        }
139
 
        pts.closeSubpath();
140
 
        return pts;
141
 
}
142
 
 
143
 
QList<QPainterPath> decomposePath(QPainterPath &path)
144
 
{
145
 
        QList<QPainterPath> ret;
146
 
        ret.clear();
147
 
        QPainterPath part;
148
 
        part = QPainterPath();
149
 
        bool first = true;
150
 
        for (int i = 0; i < path.elementCount(); ++i)
151
 
        {
152
 
                const QPainterPath::Element &elm = path.elementAt(i);
153
 
                if ((first) && (elm.type != QPainterPath::MoveToElement))
154
 
                        part.moveTo(elm.x, elm.y);
155
 
                switch (elm.type)
156
 
                {
157
 
                        case QPainterPath::MoveToElement:
158
 
                                if (!first)
159
 
                                {
160
 
                                        ret.append(part);
161
 
                                        part = QPainterPath();
162
 
                                }
163
 
                                first = false;
164
 
                                part.moveTo(elm.x, elm.y);
165
 
                                break;
166
 
                        case QPainterPath::LineToElement:
167
 
                                part.lineTo(elm.x, elm.y);
168
 
                                break;
169
 
                        case QPainterPath::CurveToElement:
170
 
                                part.cubicTo(elm.x, elm.y, path.elementAt(i+1).x, path.elementAt(i+1).y, path.elementAt(i+2).x, path.elementAt(i+2).y );
171
 
                                break;
172
 
                        default:
173
 
                                break;
174
 
                }
175
 
        }
176
 
        if (!part.isEmpty())
177
 
                ret.append(part);
178
 
        return ret;
179
 
}
180
 
 
181
 
 
182
 
 
183
 
FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
184
 
{
185
 
        if (lineStart == lineEnd)
186
 
                return FPoint(lineStart.x(), lineStart.y());
187
 
        
188
 
        // move lineStart to Origin
189
 
        p -= FPoint(lineStart.x(), lineStart.y());
190
 
        lineEnd -= lineStart;
191
 
        // calc dot product
192
 
        double lineLengthSquare = lineEnd.x() * lineEnd.x() + lineEnd.y() * lineEnd.y();
193
 
        double partOfLine = p.x() * lineEnd.x() + p.y() * lineEnd.y() / lineLengthSquare;
194
 
        // return point on line
195
 
        return FPoint(lineStart.x() + partOfLine * lineEnd.x(), lineStart.y() + partOfLine * lineEnd.y());
196
 
}
197
 
 
198
 
 
199
 
QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
200
 
{
201
 
        QPolygon cli, outa;
202
 
        Segs.clear();
203
 
        if (ina.size() > 3)
204
 
        {
205
 
                for (uint poi=0; poi<ina.size()-3; poi += 4)
206
 
                {
207
 
                        if (ina.point(poi).x() > 900000) // && cli.size() > 0)
208
 
                        {
209
 
//                              outa << cli.point(cli.size()-1);
210
 
                                Segs.append(outa.size());
211
 
                                continue;
212
 
                        }
213
 
                        FPoint a1 = ina.point(poi);
214
 
                        FPoint a2 = ina.point(poi+1);
215
 
                        FPoint a3 = ina.point(poi+3);
216
 
                        FPoint a4 = ina.point(poi+2);
217
 
                        QPainterPath Bez;
218
 
                        Bez.moveTo(a1.x(), a1.y());
219
 
                        Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
220
 
                        cli = Bez.toFillPolygon().toPolygon();
221
 
                        if (cli.size() > 1)
222
 
                                outa.putPoints(outa.size(), cli.size()-2, cli);
223
 
                        else
224
 
                                outa << QPoint(qRound(a4.x()), qRound(a4.y()));
225
 
                }
226
 
//              if (cli.size() > 0)
227
 
//                      outa << cli.point(cli.size()-1);
228
 
        }
229
 
        return outa;
230
 
}
231
 
 
232
 
FPoint getMaxClipF(FPointArray* Clip)
233
 
{
234
 
        FPoint np, rp;
235
 
        double mx = 0;
236
 
        double my = 0;
237
 
        uint clipSize=Clip->size();
238
 
        for (uint c = 0; c < clipSize; ++c)
239
 
        {
240
 
                np = Clip->point(c);
241
 
                if (np.x() > 900000)
242
 
                        continue;
243
 
                if (np.x() > mx)
244
 
                        mx = np.x();
245
 
                if (np.y() > my)
246
 
                        my = np.y();
247
 
        }
248
 
        rp.setXY(mx, my);
249
 
        return rp;
250
 
}
251
 
 
252
 
FPoint getMinClipF(FPointArray* Clip)
253
 
{
254
 
        FPoint np, rp;
255
 
        double mx = 99999;
256
 
        double my = 99999;
257
 
        uint clipSize=Clip->size();
258
 
        for (uint c = 0; c < clipSize; ++c)
259
 
        {
260
 
                np = Clip->point(c);
261
 
                if (np.x() > 900000)
262
 
                        continue;
263
 
                if (np.x() < mx)
264
 
                        mx = np.x();
265
 
                if (np.y() < my)
266
 
                        my = np.y();
267
 
        }
268
 
        rp.setXY(mx, my);
269
 
        return rp;
270
 
}
271
 
 
272
 
 
273
 
bool compareDouble(double a, double b)
274
 
{
275
 
        if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
276
 
        {
277
 
                long al = static_cast<long>(10000 * a);
278
 
                long bl = static_cast<long>(10000 * b);
279
 
                return al == bl;
280
 
        }
281
 
        return a == b;
282
 
}
283
 
 
284
 
 
285
 
double constrainAngle(double angle, double constrain)
286
 
{
287
 
        double newAngle=angle;
288
 
        double constrainTo=constrain;
289
 
        if (newAngle<0.0)
290
 
                newAngle+=360.0;
291
 
        newAngle=qRound(angle/constrainTo)*constrainTo;
292
 
        if (newAngle==360.0)
293
 
                newAngle=0.0;
294
 
        return newAngle;
295
 
}
296
 
 
297
 
double getRotationFromMatrix(QMatrix& matrix, double def)
298
 
{
299
 
        double value = def;
300
 
        double norm = sqrt(fabs(matrix.det()));
301
 
        if (norm > 0.0000001)
302
 
        {
303
 
                double m11 = matrix.m11() / norm;
304
 
                double m12 = matrix.m12() / norm;
305
 
                double m21 = matrix.m21() / norm;
306
 
                double m22 = matrix.m22() / norm;
307
 
                if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
308
 
                {
309
 
                        QMatrix mat(m11, m12, m21, m22, 0, 0);
310
 
                        if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
311
 
                        {
312
 
                                double ac = acos(mat.m11());
313
 
                                value = (mat.m21() >= 0.0) ? ac : (-ac);
314
 
                        }
315
 
                }
316
 
        }
317
 
        return value;
318
 
}
319
 
 
 
1
/*
 
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
 
3
to the COPYING file provided with the program. Following this notice may exist
 
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
 
5
for which a new license (GPL+exception) is in place.
 
6
*/
 
7
/***************************************************************************
 
8
                          util.cpp  -  description
 
9
                             -------------------
 
10
    begin                : Fri Sep 14 2001
 
11
    copyright            : (C) 2001 by Franz Schmid
 
12
    email                : Franz.Schmid@altmuehlnet.de
 
13
 ***************************************************************************/
 
14
 
 
15
/***************************************************************************
 
16
 *                                                                         *
 
17
 *   This program is free software; you can redistribute it and/or modify  *
 
18
 *   it under the terms of the GNU General Public License as published by  *
 
19
 *   the Free Software Foundation; either version 2 of the License, or     *
 
20
 *   (at your option) any later version.                                   *
 
21
 *                                                                         *
 
22
 ***************************************************************************/
 
23
 
 
24
#include <QRegion>
 
25
 
 
26
#include "util_math.h"
 
27
#include "scconfig.h"
 
28
#include "fpoint.h"
 
29
#include "fpointarray.h"
 
30
 
 
31
using namespace std;
 
32
 
 
33
uint getDouble(const QByteArray in, bool raw)
 
34
{
 
35
        QByteArray bb(4, ' ');
 
36
        if (raw)
 
37
        {
 
38
                // Qt4
 
39
/*              bb[3] = static_cast<uchar>(QChar(in.at(0)));
 
40
                bb[2] = static_cast<uchar>(QChar(in.at(1)));
 
41
                bb[1] = static_cast<uchar>(QChar(in.at(2)));
 
42
                bb[0] = static_cast<uchar>(QChar(in.at(3)));*/
 
43
                bb[3] = in.at(0);
 
44
                bb[2] = in.at(1);
 
45
                bb[1] = in.at(2);
 
46
                bb[0] = in.at(3);
 
47
        }
 
48
        else
 
49
        {
 
50
                // Qt4
 
51
//              bb[0] = static_cast<uchar>(QChar(in.at(0)));
 
52
//              bb[1] = static_cast<uchar>(QChar(in.at(1)));
 
53
//              bb[2] = static_cast<uchar>(QChar(in.at(2)));
 
54
//              bb[3] = static_cast<uchar>(QChar(in.at(3)));
 
55
                bb[0] = in.at(0);
 
56
                bb[1] = in.at(1);
 
57
                bb[2] = in.at(2);
 
58
                bb[3] = in.at(3);
 
59
        }
 
60
        uint ret;
 
61
        ret = bb[0] & 0xff;
 
62
        ret |= (bb[1] << 8) & 0xff00;
 
63
        ret |= (bb[2] << 16) & 0xff0000;
 
64
        ret |= (bb[3] << 24) & 0xff000000;
 
65
        return ret;
 
66
}
 
67
 
 
68
QPainterPath RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2)
 
69
{
 
70
        uint cx = star ? c * 2 : c;
 
71
        double seg = 360.0 / cx;
 
72
        double sc = rota + 180.0;
 
73
        double di = factor;
 
74
        double mx = 0;
 
75
        double my = 0;
 
76
        bool first = true;
 
77
        double trueLength = sqrt(pow(sin(seg / 180.0 * M_PI) * (w / 2.0), 2) + pow(cos(seg / 180.0 * M_PI) * (h / 2.0) + (h/2.0) - h, 2));
 
78
        QPainterPath pts;
 
79
        for (uint x = 0; x < cx; ++x)
 
80
        {
 
81
                sc = seg * x + 180.0 + rota;
 
82
                if (star)
 
83
                {
 
84
                        double wf = w / 2.0;
 
85
                        double hf = h / 2.0;
 
86
                        if (x % 2 != 0)
 
87
                        {
 
88
                                wf *= di;
 
89
                                hf *= di;
 
90
                        }
 
91
                        mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
 
92
                        my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
 
93
                        if (first)
 
94
                                pts.moveTo(mx, my);
 
95
                        else
 
96
                        {
 
97
                                if (factor2 != 0.0)
 
98
                                {
 
99
                                        if (x % 2 != 0)
 
100
                                        {
 
101
                                                QPointF curr = pts.currentPosition();
 
102
                                                double mxc = sin((sc + 90.0) / 180.0 * M_PI) * (-trueLength * factor2) + mx;
 
103
                                                double myc = cos((sc + 90.0) / 180.0 * M_PI) * (-trueLength * factor2) + my;
 
104
                                                pts.cubicTo(curr, QPointF(mxc, myc), QPointF(mx, my));
 
105
                                        }
 
106
                                        else
 
107
                                        {
 
108
                                                QPointF curr = pts.currentPosition();
 
109
                                                double mxc = sin((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.x();
 
110
                                                double myc = cos((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.y();
 
111
                                                pts.cubicTo(QPointF(mxc, myc), QPointF(mx, my), QPointF(mx, my));
 
112
                                        }
 
113
                                }
 
114
                                else
 
115
                                        pts.lineTo(mx, my);
 
116
                        }
 
117
                }
 
118
                else
 
119
                {
 
120
                        mx = sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0);
 
121
                        my = cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0);
 
122
                        if (first)
 
123
                                pts.moveTo(mx, my);
 
124
                        else
 
125
                                pts.lineTo(mx, my);
 
126
                }
 
127
                first = false;
 
128
        }
 
129
        if ((star) && (factor2 != 0.0))
 
130
        {
 
131
                sc = 360.0 + 180.0 + rota;
 
132
                mx = sin(sc / 180.0 * M_PI) * (w / 2.0) + (w/2.0);
 
133
                my = cos(sc / 180.0 * M_PI) * (h / 2.0) + (h/2.0);
 
134
                QPointF curr = pts.currentPosition();
 
135
                double mxc = sin((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.x();
 
136
                double myc = cos((sc - seg + 90.0) / 180.0 * M_PI) * (trueLength * factor2) + curr.y();
 
137
                pts.cubicTo(QPointF(mxc, myc), QPointF(mx, my), QPointF(mx, my));
 
138
        }
 
139
        pts.closeSubpath();
 
140
        return pts;
 
141
}
 
142
 
 
143
QList<QPainterPath> decomposePath(QPainterPath &path)
 
144
{
 
145
        QList<QPainterPath> ret;
 
146
        ret.clear();
 
147
        QPainterPath part;
 
148
        part = QPainterPath();
 
149
        bool first = true;
 
150
        for (int i = 0; i < path.elementCount(); ++i)
 
151
        {
 
152
                const QPainterPath::Element &elm = path.elementAt(i);
 
153
                if ((first) && (elm.type != QPainterPath::MoveToElement))
 
154
                        part.moveTo(elm.x, elm.y);
 
155
                switch (elm.type)
 
156
                {
 
157
                        case QPainterPath::MoveToElement:
 
158
                                if (!first)
 
159
                                {
 
160
                                        ret.append(part);
 
161
                                        part = QPainterPath();
 
162
                                }
 
163
                                first = false;
 
164
                                part.moveTo(elm.x, elm.y);
 
165
                                break;
 
166
                        case QPainterPath::LineToElement:
 
167
                                part.lineTo(elm.x, elm.y);
 
168
                                break;
 
169
                        case QPainterPath::CurveToElement:
 
170
                                part.cubicTo(elm.x, elm.y, path.elementAt(i+1).x, path.elementAt(i+1).y, path.elementAt(i+2).x, path.elementAt(i+2).y );
 
171
                                break;
 
172
                        default:
 
173
                                break;
 
174
                }
 
175
        }
 
176
        if (!part.isEmpty())
 
177
                ret.append(part);
 
178
        return ret;
 
179
}
 
180
 
 
181
FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
 
182
{
 
183
        if (lineStart == lineEnd)
 
184
                return FPoint(lineStart.x(), lineStart.y());
 
185
        
 
186
        // move lineStart to Origin
 
187
        p -= FPoint(lineStart.x(), lineStart.y());
 
188
        lineEnd -= lineStart;
 
189
        // calc dot product
 
190
        double lineLengthSquare = lineEnd.x() * lineEnd.x() + lineEnd.y() * lineEnd.y();
 
191
        double partOfLine = p.x() * lineEnd.x() + p.y() * lineEnd.y() / lineLengthSquare;
 
192
        // return point on line
 
193
        return FPoint(lineStart.x() + partOfLine * lineEnd.x(), lineStart.y() + partOfLine * lineEnd.y());
 
194
}
 
195
 
 
196
bool regionContainsRect(const QRegion& shape, QRect rect)
 
197
{
 
198
        /*bool oldResult = QRegion(rect).subtracted(shape).isEmpty();*/
 
199
 
 
200
        // Code adapted from Qt RectInRegion (cf. qregion.cpp) to detect
 
201
        // if a specific rect is stricly contained in a specific region
 
202
        const QRect *pbox, *pboxEnd;
 
203
    bool partIn(false), partOut(false);
 
204
 
 
205
        QRect *prect = &rect;
 
206
        int rx = rect.left();
 
207
        int ry = rect.top();
 
208
   
 
209
        int rectCount = shape.rectCount();
 
210
        QRect boundingRect = shape.boundingRect();
 
211
    if (rectCount == 0 || !boundingRect.contains(rect))
 
212
        return false;
 
213
 
 
214
    /* can stop when both partOut and partIn are true, or we reach prect->y2 */
 
215
        const QVector<QRect> rects = shape.rects();
 
216
    pbox = (rectCount == 1) ? &boundingRect : rects.constData();
 
217
    pboxEnd = pbox + rectCount;
 
218
    for (; pbox < pboxEnd; ++pbox) {
 
219
        if (pbox->bottom() < ry)
 
220
           continue;
 
221
 
 
222
        if (pbox->top() > ry) {
 
223
           partOut = true;
 
224
           if (partIn || pbox->top() > prect->bottom())
 
225
              break;
 
226
           ry = pbox->top();
 
227
        }
 
228
 
 
229
        if (pbox->right() < rx)
 
230
           continue;            /* not far enough over yet */
 
231
 
 
232
        if (pbox->left() > rx) {
 
233
           partOut = true;      /* missed part of rectangle to left */
 
234
           if (partIn)
 
235
              break;
 
236
        }
 
237
 
 
238
        if (pbox->left() <= prect->right()) {
 
239
            partIn = true;      /* definitely overlap */
 
240
            if (partOut)
 
241
               break;
 
242
        }
 
243
 
 
244
        if (pbox->right() >= prect->right()) {
 
245
           ry = pbox->bottom() + 1;     /* finished with this band */
 
246
           if (ry > prect->bottom())
 
247
              break;
 
248
           rx = prect->left();  /* reset x out to left again */
 
249
        } else {
 
250
            /*
 
251
             * Because boxes in a band are maximal width, if the first box
 
252
             * to overlap the rectangle doesn't completely cover it in that
 
253
             * band, the rectangle must be partially out, since some of it
 
254
             * will be uncovered in that band. partIn will have been set true
 
255
             * by now...
 
256
             */
 
257
            break;
 
258
        }
 
259
    }
 
260
        /*bool newResult = partIn ? ((ry <= prect->bottom()) ? false : true) : false;
 
261
        if (oldResult != newResult)
 
262
                int test = 0;*/
 
263
    return partIn ? ((ry <= prect->bottom()) ? false : true) : false;
 
264
}
 
265
 
 
266
QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
 
267
{
 
268
        QPolygon cli, outa;
 
269
        Segs.clear();
 
270
        if (ina.size() > 3)
 
271
        {
 
272
                for (uint poi=0; poi<ina.size()-3; poi += 4)
 
273
                {
 
274
                        if (ina.point(poi).x() > 900000) // && cli.size() > 0)
 
275
                        {
 
276
//                              outa << cli.point(cli.size()-1);
 
277
                                Segs.append(outa.size());
 
278
                                continue;
 
279
                        }
 
280
                        FPoint a1 = ina.point(poi);
 
281
                        FPoint a2 = ina.point(poi+1);
 
282
                        FPoint a3 = ina.point(poi+3);
 
283
                        FPoint a4 = ina.point(poi+2);
 
284
                        QPainterPath Bez;
 
285
                        Bez.moveTo(a1.x(), a1.y());
 
286
                        Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
 
287
                        cli = Bez.toFillPolygon().toPolygon();
 
288
                        if (cli.size() > 1)
 
289
                                outa.putPoints(outa.size(), cli.size()-2, cli);
 
290
                        else
 
291
                                outa << QPoint(qRound(a4.x()), qRound(a4.y()));
 
292
                }
 
293
//              if (cli.size() > 0)
 
294
//                      outa << cli.point(cli.size()-1);
 
295
        }
 
296
        return outa;
 
297
}
 
298
 
 
299
FPoint getMaxClipF(FPointArray* Clip)
 
300
{
 
301
        FPoint np, rp;
 
302
        double mx = 0;
 
303
        double my = 0;
 
304
        uint clipSize=Clip->size();
 
305
        for (uint c = 0; c < clipSize; ++c)
 
306
        {
 
307
                np = Clip->point(c);
 
308
                if (np.x() > 900000)
 
309
                        continue;
 
310
                if (np.x() > mx)
 
311
                        mx = np.x();
 
312
                if (np.y() > my)
 
313
                        my = np.y();
 
314
        }
 
315
        rp.setXY(mx, my);
 
316
        return rp;
 
317
}
 
318
 
 
319
FPoint getMinClipF(FPointArray* Clip)
 
320
{
 
321
        FPoint np, rp;
 
322
        double mx = 99999;
 
323
        double my = 99999;
 
324
        uint clipSize=Clip->size();
 
325
        for (uint c = 0; c < clipSize; ++c)
 
326
        {
 
327
                np = Clip->point(c);
 
328
                if (np.x() > 900000)
 
329
                        continue;
 
330
                if (np.x() < mx)
 
331
                        mx = np.x();
 
332
                if (np.y() < my)
 
333
                        my = np.y();
 
334
        }
 
335
        rp.setXY(mx, my);
 
336
        return rp;
 
337
}
 
338
 
 
339
 
 
340
bool compareDouble(double a, double b)
 
341
{
 
342
        if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
 
343
        {
 
344
                long al = static_cast<long>(10000 * a);
 
345
                long bl = static_cast<long>(10000 * b);
 
346
                return al == bl;
 
347
        }
 
348
        return a == b;
 
349
}
 
350
 
 
351
 
 
352
double constrainAngle(double angle, double constrain)
 
353
{
 
354
        double newAngle=angle;
 
355
        double constrainTo=constrain;
 
356
        if (newAngle<0.0)
 
357
                newAngle+=360.0;
 
358
        newAngle=qRound(angle/constrainTo)*constrainTo;
 
359
        if (newAngle==360.0)
 
360
                newAngle=0.0;
 
361
        return newAngle;
 
362
}
 
363
 
 
364
double getRotationFromMatrix(QMatrix& matrix, double def)
 
365
{
 
366
        double value = def;
 
367
        double norm = sqrt(fabs(matrix.det()));
 
368
        if (norm > 0.0000001)
 
369
        {
 
370
                double m11 = matrix.m11() / norm;
 
371
                double m12 = matrix.m12() / norm;
 
372
                double m21 = matrix.m21() / norm;
 
373
                double m22 = matrix.m22() / norm;
 
374
                if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
 
375
                {
 
376
                        QMatrix mat(m11, m12, m21, m22, 0, 0);
 
377
                        if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
 
378
                        {
 
379
                                double ac = acos(mat.m11());
 
380
                                value = (mat.m21() >= 0.0) ? ac : (-ac);
 
381
                        }
 
382
                }
 
383
        }
 
384
        return value;
 
385
}
 
386