Subversion Repositories Scribus

Rev

Rev 11337 | Rev 12885 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10203 cbradney 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"
12461 avox 26
#include "fpoint.h"
27
#include "fpointarray.h"
10203 cbradney 28
 
10695 jghali 29
using namespace std;
10203 cbradney 30
 
31
 
32
 
33
uint getDouble(QString in, bool raw)
34
{
10592 fschmid 35
        QByteArray bb(4, ' ');
10203 cbradney 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
 
10264 fschmid 68
QPolygon RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
10203 cbradney 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
        int mx = 0;
75
        int my = 0;
10264 fschmid 76
        QPolygon pts(cx);
10203 cbradney 77
        for (uint x = 0; x < cx; ++x)
78
        {
79
                sc = seg * x + 180.0 + rota;
80
                if (star)
81
                {
10287 fschmid 82
                        double wf = x % 2 == 0 ? w / 2.0 : w / 2.0 * di;
83
                        double hf = x % 2 == 0 ? h / 2.0 : h / 2.0 * di;
84
                        mx = qRound(sin(sc / 180.0 * M_PI) * (wf) + (w/2.0));
85
                        my = qRound(cos(sc / 180.0 * M_PI) * (hf) + (h/2.0));
10203 cbradney 86
                }
87
                else
88
                {
10287 fschmid 89
                        mx = qRound(sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0));
90
                        my = qRound(cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0));
10203 cbradney 91
                }
92
                pts.setPoint(x, mx, my);
93
        }
94
        return pts;
95
}
96
 
97
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
98
{
99
        uint cx = star ? c * 2 : c;
100
        double seg = 360.0 / cx;
101
        double sc = rota + 180.0;
102
        double di = factor;
103
        double mx = 0;
104
        double my = 0;
105
        FPointArray pts(cx);
106
        for (uint x = 0; x < cx; ++x)
107
        {
108
                sc = seg * x + 180.0 + rota;
109
                if (star)
110
                {
10287 fschmid 111
                        double wf = x % 2 == 0 ? w / 2.0 : w / 2.0 * di;
112
                        double hf = x % 2 == 0 ? h / 2.0 : h / 2.0 * di;
113
                        mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
114
                        my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
10203 cbradney 115
                }
116
                else
117
                {
10287 fschmid 118
                        mx = sin(sc / 180.0 * M_PI) * (w/2.0) + (w/2.0);
119
                        my = cos(sc / 180.0 * M_PI) * (h/2.0) + (h/2.0);
10203 cbradney 120
                }
121
                pts.setPoint(x, mx, my);
122
        }
123
        return pts;
124
}
125
 
126
QList<QPainterPath> decomposePath(QPainterPath &path)
127
{
128
        QList<QPainterPath> ret;
129
        ret.clear();
130
        QPainterPath part;
131
        part = QPainterPath();
132
        bool first = true;
133
        for (int i = 0; i < path.elementCount(); ++i)
134
        {
135
                const QPainterPath::Element &elm = path.elementAt(i);
136
                if ((first) && (elm.type != QPainterPath::MoveToElement))
137
                        part.moveTo(elm.x, elm.y);
138
                switch (elm.type)
139
                {
140
                        case QPainterPath::MoveToElement:
141
                                if (!first)
142
                                {
143
                                        ret.append(part);
144
                                        part = QPainterPath();
145
                                }
146
                                first = false;
147
                                part.moveTo(elm.x, elm.y);
148
                                break;
149
                        case QPainterPath::LineToElement:
150
                                part.lineTo(elm.x, elm.y);
151
                                break;
152
                        case QPainterPath::CurveToElement:
153
                                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 );
154
                                break;
155
                        default:
156
                                break;
157
                }
158
        }
159
        if (!part.isEmpty())
160
                ret.append(part);
161
        return ret;
162
}
163
 
10701 avox 164
 
165
 
166
FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
167
{
168
        if (lineStart == lineEnd)
169
                return FPoint(lineStart.x(), lineStart.y());
170
 
171
        // move lineStart to Origin
172
        p -= FPoint(lineStart.x(), lineStart.y());
173
        lineEnd -= lineStart;
174
        // calc dot product
175
        double lineLengthSquare = lineEnd.x() * lineEnd.x() + lineEnd.y() * lineEnd.y();
176
        double partOfLine = p.x() * lineEnd.x() + p.y() * lineEnd.y() / lineLengthSquare;
177
        // return point on line
178
        return FPoint(lineStart.x() + partOfLine * lineEnd.x(), lineStart.y() + partOfLine * lineEnd.y());
179
}
180
 
181
 
10939 jghali 182
QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
10203 cbradney 183
{
10284 fschmid 184
        QPolygon cli, outa;
10203 cbradney 185
        Segs.clear();
186
        if (ina.size() > 3)
187
        {
188
                for (uint poi=0; poi<ina.size()-3; poi += 4)
189
                {
10409 fschmid 190
                        if (ina.point(poi).x() > 900000) // && cli.size() > 0)
10203 cbradney 191
                        {
10409 fschmid 192
//                              outa << cli.point(cli.size()-1);
10203 cbradney 193
                                Segs.append(outa.size());
194
                                continue;
195
                        }
10284 fschmid 196
                        FPoint a1 = ina.point(poi);
197
                        FPoint a2 = ina.point(poi+1);
198
                        FPoint a3 = ina.point(poi+3);
199
                        FPoint a4 = ina.point(poi+2);
200
                        QPainterPath Bez;
201
                        Bez.moveTo(a1.x(), a1.y());
202
                        Bez.cubicTo(a2.x(), a2.y(), a3.x(), a3.y(), a4.x(), a4.y());
203
                        cli = Bez.toFillPolygon().toPolygon();
10409 fschmid 204
                        if (cli.size() > 1)
205
                                outa.putPoints(outa.size(), cli.size()-2, cli);
10291 fschmid 206
                        else
207
                                outa << QPoint(qRound(a4.x()), qRound(a4.y()));
10203 cbradney 208
                }
10409 fschmid 209
//              if (cli.size() > 0)
210
//                      outa << cli.point(cli.size()-1);
10203 cbradney 211
        }
212
        return outa;
213
}
214
 
215
FPoint getMaxClipF(FPointArray* Clip)
216
{
217
        FPoint np, rp;
218
        double mx = 0;
219
        double my = 0;
220
        uint clipSize=Clip->size();
221
        for (uint c = 0; c < clipSize; ++c)
222
        {
223
                np = Clip->point(c);
224
                if (np.x() > 900000)
225
                        continue;
226
                if (np.x() > mx)
227
                        mx = np.x();
228
                if (np.y() > my)
229
                        my = np.y();
230
        }
231
        rp.setXY(mx, my);
232
        return rp;
233
}
234
 
235
FPoint getMinClipF(FPointArray* Clip)
236
{
237
        FPoint np, rp;
238
        double mx = 99999;
239
        double my = 99999;
240
        uint clipSize=Clip->size();
241
        for (uint c = 0; c < clipSize; ++c)
242
        {
243
                np = Clip->point(c);
244
                if (np.x() > 900000)
245
                        continue;
246
                if (np.x() < mx)
247
                        mx = np.x();
248
                if (np.y() < my)
249
                        my = np.y();
250
        }
251
        rp.setXY(mx, my);
252
        return rp;
253
}
254
 
255
 
256
bool compareDouble(double a, double b)
257
{
258
        if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
259
        {
260
                long al = static_cast<long>(10000 * a);
261
                long bl = static_cast<long>(10000 * b);
262
                return al == bl;
263
        }
264
        return a == b;
265
}
266
 
267
 
268
double constrainAngle(double angle, double constrain)
269
{
270
        double newAngle=angle;
271
        double constrainTo=constrain;
272
        if (newAngle<0.0)
273
                newAngle+=360.0;
274
        newAngle=qRound(angle/constrainTo)*constrainTo;
275
        if (newAngle==360.0)
276
                newAngle=0.0;
277
        return newAngle;
278
}
279
 
280
double getRotationFromMatrix(QMatrix& matrix, double def)
281
{
282
        double value = def;
283
        double norm = sqrt(fabs(matrix.det()));
284
        if (norm > 0.0000001)
285
        {
286
                double m11 = matrix.m11() / norm;
287
                double m12 = matrix.m12() / norm;
288
                double m21 = matrix.m21() / norm;
289
                double m22 = matrix.m22() / norm;
290
                if (fabs(m11) <= 1.0 && fabs(m12) <= 1.0 && fabs(m21) <= 1.0 && fabs(m22) <= 1.0)
291
                {
292
                        QMatrix mat(m11, m12, m21, m22, 0, 0);
293
                        if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
294
                        {
295
                                double ac = acos(mat.m11());
296
                                value = (mat.m21() >= 0.0) ? ac : (-ac);
297
                        }
298
                }
299
        }
300
        return value;
301
}
302