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.
7
/***************************************************************************
10
begin : Fri Sep 14 2001
11
copyright : (C) 2001 by Franz Schmid
12
email : Franz.Schmid@altmuehlnet.de
13
***************************************************************************/
15
/***************************************************************************
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. *
22
***************************************************************************/
24
#include "util_math.h"
27
#include "fpointarray.h"
33
uint getDouble(QString in, bool raw)
35
QByteArray bb(4, ' ');
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));
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));
62
ret |= (bb[1] << 8) & 0xff00;
63
ret |= (bb[2] << 16) & 0xff0000;
64
ret |= (bb[3] << 24) & 0xff000000;
68
QPainterPath RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2)
70
uint cx = star ? c * 2 : c;
71
double seg = 360.0 / cx;
72
double sc = rota + 180.0;
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));
79
for (uint x = 0; x < cx; ++x)
81
sc = seg * x + 180.0 + rota;
91
mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
92
my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
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));
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));
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);
129
if ((star) && (factor2 != 0.0))
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));
143
QList<QPainterPath> decomposePath(QPainterPath &path)
145
QList<QPainterPath> ret;
148
part = QPainterPath();
150
for (int i = 0; i < path.elementCount(); ++i)
152
const QPainterPath::Element &elm = path.elementAt(i);
153
if ((first) && (elm.type != QPainterPath::MoveToElement))
154
part.moveTo(elm.x, elm.y);
157
case QPainterPath::MoveToElement:
161
part = QPainterPath();
164
part.moveTo(elm.x, elm.y);
166
case QPainterPath::LineToElement:
167
part.lineTo(elm.x, elm.y);
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 );
183
FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
185
if (lineStart == lineEnd)
186
return FPoint(lineStart.x(), lineStart.y());
188
// move lineStart to Origin
189
p -= FPoint(lineStart.x(), lineStart.y());
190
lineEnd -= lineStart;
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());
199
QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
205
for (uint poi=0; poi<ina.size()-3; poi += 4)
207
if (ina.point(poi).x() > 900000) // && cli.size() > 0)
209
// outa << cli.point(cli.size()-1);
210
Segs.append(outa.size());
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);
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();
222
outa.putPoints(outa.size(), cli.size()-2, cli);
224
outa << QPoint(qRound(a4.x()), qRound(a4.y()));
226
// if (cli.size() > 0)
227
// outa << cli.point(cli.size()-1);
232
FPoint getMaxClipF(FPointArray* Clip)
237
uint clipSize=Clip->size();
238
for (uint c = 0; c < clipSize; ++c)
252
FPoint getMinClipF(FPointArray* Clip)
257
uint clipSize=Clip->size();
258
for (uint c = 0; c < clipSize; ++c)
273
bool compareDouble(double a, double b)
275
if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
277
long al = static_cast<long>(10000 * a);
278
long bl = static_cast<long>(10000 * b);
285
double constrainAngle(double angle, double constrain)
287
double newAngle=angle;
288
double constrainTo=constrain;
291
newAngle=qRound(angle/constrainTo)*constrainTo;
297
double getRotationFromMatrix(QMatrix& matrix, double def)
300
double norm = sqrt(fabs(matrix.det()));
301
if (norm > 0.0000001)
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)
309
QMatrix mat(m11, m12, m21, m22, 0, 0);
310
if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
312
double ac = acos(mat.m11());
313
value = (mat.m21() >= 0.0) ? ac : (-ac);
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.
7
/***************************************************************************
10
begin : Fri Sep 14 2001
11
copyright : (C) 2001 by Franz Schmid
12
email : Franz.Schmid@altmuehlnet.de
13
***************************************************************************/
15
/***************************************************************************
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. *
22
***************************************************************************/
26
#include "util_math.h"
29
#include "fpointarray.h"
33
uint getDouble(const QByteArray in, bool raw)
35
QByteArray bb(4, ' ');
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)));*/
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)));
62
ret |= (bb[1] << 8) & 0xff00;
63
ret |= (bb[2] << 16) & 0xff0000;
64
ret |= (bb[3] << 24) & 0xff000000;
68
QPainterPath RegularPolygon(double w, double h, uint c, bool star, double factor, double rota, double factor2)
70
uint cx = star ? c * 2 : c;
71
double seg = 360.0 / cx;
72
double sc = rota + 180.0;
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));
79
for (uint x = 0; x < cx; ++x)
81
sc = seg * x + 180.0 + rota;
91
mx = sin(sc / 180.0 * M_PI) * (wf) + (w/2.0);
92
my = cos(sc / 180.0 * M_PI) * (hf) + (h/2.0);
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));
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));
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);
129
if ((star) && (factor2 != 0.0))
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));
143
QList<QPainterPath> decomposePath(QPainterPath &path)
145
QList<QPainterPath> ret;
148
part = QPainterPath();
150
for (int i = 0; i < path.elementCount(); ++i)
152
const QPainterPath::Element &elm = path.elementAt(i);
153
if ((first) && (elm.type != QPainterPath::MoveToElement))
154
part.moveTo(elm.x, elm.y);
157
case QPainterPath::MoveToElement:
161
part = QPainterPath();
164
part.moveTo(elm.x, elm.y);
166
case QPainterPath::LineToElement:
167
part.lineTo(elm.x, elm.y);
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 );
181
FPoint projectPointOnLine(FPoint p, QPointF lineStart, QPointF lineEnd)
183
if (lineStart == lineEnd)
184
return FPoint(lineStart.x(), lineStart.y());
186
// move lineStart to Origin
187
p -= FPoint(lineStart.x(), lineStart.y());
188
lineEnd -= lineStart;
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());
196
bool regionContainsRect(const QRegion& shape, QRect rect)
198
/*bool oldResult = QRegion(rect).subtracted(shape).isEmpty();*/
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);
205
QRect *prect = ▭
206
int rx = rect.left();
209
int rectCount = shape.rectCount();
210
QRect boundingRect = shape.boundingRect();
211
if (rectCount == 0 || !boundingRect.contains(rect))
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)
222
if (pbox->top() > ry) {
224
if (partIn || pbox->top() > prect->bottom())
229
if (pbox->right() < rx)
230
continue; /* not far enough over yet */
232
if (pbox->left() > rx) {
233
partOut = true; /* missed part of rectangle to left */
238
if (pbox->left() <= prect->right()) {
239
partIn = true; /* definitely overlap */
244
if (pbox->right() >= prect->right()) {
245
ry = pbox->bottom() + 1; /* finished with this band */
246
if (ry > prect->bottom())
248
rx = prect->left(); /* reset x out to left again */
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
260
/*bool newResult = partIn ? ((ry <= prect->bottom()) ? false : true) : false;
261
if (oldResult != newResult)
263
return partIn ? ((ry <= prect->bottom()) ? false : true) : false;
266
QPolygon FlattenPath(const FPointArray& ina, QList<uint> &Segs)
272
for (uint poi=0; poi<ina.size()-3; poi += 4)
274
if (ina.point(poi).x() > 900000) // && cli.size() > 0)
276
// outa << cli.point(cli.size()-1);
277
Segs.append(outa.size());
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);
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();
289
outa.putPoints(outa.size(), cli.size()-2, cli);
291
outa << QPoint(qRound(a4.x()), qRound(a4.y()));
293
// if (cli.size() > 0)
294
// outa << cli.point(cli.size()-1);
299
FPoint getMaxClipF(FPointArray* Clip)
304
uint clipSize=Clip->size();
305
for (uint c = 0; c < clipSize; ++c)
319
FPoint getMinClipF(FPointArray* Clip)
324
uint clipSize=Clip->size();
325
for (uint c = 0; c < clipSize; ++c)
340
bool compareDouble(double a, double b)
342
if(a > -21473 && b > -21473 && a < 21474 && b < 21474)
344
long al = static_cast<long>(10000 * a);
345
long bl = static_cast<long>(10000 * b);
352
double constrainAngle(double angle, double constrain)
354
double newAngle=angle;
355
double constrainTo=constrain;
358
newAngle=qRound(angle/constrainTo)*constrainTo;
364
double getRotationFromMatrix(QMatrix& matrix, double def)
367
double norm = sqrt(fabs(matrix.det()));
368
if (norm > 0.0000001)
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)
376
QMatrix mat(m11, m12, m21, m22, 0, 0);
377
if (abs(mat.det()-1.0) < 0.00001 && (mat.m12() == -mat.m21()))
379
double ac = acos(mat.m11());
380
value = (mat.m21() >= 0.0) ? ac : (-ac);